This function ensures that a key is present in the HashMap.
If it's not present, it is inserted, and the corresponding value
is initialized with whatever the callback returns.
It allows us to express this:
auto it = map.find(key);
if (it == map.end()) {
map.set(it, make_a_value());
it = map.find(key);
}
auto& value = it->value;
Like this:
auto& value = map.ensure(key, [] { return make_a_value(); });
Note that the callback is only invoked if we have to insert a missing
key into the HashMap. This is important in case constructing the default
value is expensive or otherwise undesirable.
It relies on a mapper function to convert each T& to a JS::Value. This
allows us to avoid awkward Vector<T> to MarkedValueList conversion at
the call site.
Without this, the bounding rect for the text as generated by TextLayout
can go beyond the bounds of the user-supplied drawing rect and cause the
text to overlap because of the line_rect.intersect(rect) a few lines
below.
This ensures we safely handle interrupts (which can call virtual
functions), so they don't happen in the constructor - this pattern can
lead to a crash, if we are still in the constructor context because
not all methods are available for usage (some are pure virtual,
so it's possible to call __cxa_pure_virtual).
Also, under some conditions like adding a PCI device via PCI-passthrough
mechanism in QEMU, it became exposed to the eye that the code asserts on
RNG::handle_device_config_change(). That device has no configuration but
if the hypervisor still misbehaves and tries to configure it, we should
simply return false to indicate nothing happened.
Like with the ProcFS, description data can change at anytime, so it's
wise to ensure that when the userland reads from an Inode, data is
consistent unless the userland indicated it wants to refresh the data
(by seeking to offset 0, or re-attaching the Inode).
Otherwise, if the data changes in the middle of the reading, it can
cause silent corruption in output which can lead to random crashes.
This introduces a new define AK_DONT_REPLACE_STD that disables our own
implementation of std::move and std::forward. Some ports include both
STL and AK headers which causes conflicts when trying to resolve those
functions. The port can define AK_DONT_REPLACE_STD before including
Serenity headers in that case.
We were accidentally calling TextDirection::get_text_direction with a
String instead of a UtfView, which meant each byte was treated as a
codepoint, resulting in incorrect identification of text direction.
The fd would get closed when the File went out of scope, so we couldn't
open any file specified by 'pp <path to file>'. We need the fd to be
alive and we solemnly swear to take good care of it and close it
ourselves later.
Previously all memory values on the performance was formatted as KiB,
but with such formatting it can be quite hard to read large numbers
(as mentioned by Andreas on todays office hours livestream :^)).
This patch makes use of the human readable formatting utilies and
displays them in an easier to read format.
The amount of aliases in the likely-subtags dataset is quite large, so
this also needed to change the way the data is generated. Otherwise, the
compiler would complain about the size of the generated code.
Previously, a static method was generated that would effectively parse
the dataset into a HashMap of Unicode::LanguageID at runtime. We now
perform that parsing at generation-time, and instead generate an Array
of a structure similar to Unicode::LanguageID (we cannot use the same
structure because it contains String and Optional, which cannot be used
at compile-time).
The UnicodeLocale generator will need to parse canonicalized locale
strings, and will require using these methods. However, the generator
cannot depend on LibUnicode because Locale.cpp within LibUnicode already
depends on the generated file. Instead, defining the methods that the
generator needs inline allows the generator to use them without linking
against LibUnicode.
This makes calling value() on a temporary KResultOr be a compile-time
error. This exposed a number of missing error checks (fixed in the
preceding commits.)
This option is similar to the qgrub option, but instead of starting a
QEMU PIIX4 machine, it starts a QEMU Q35 machine, booting a grub image
disk within it.
There are a few places in the system where this could be useful,
such as PixelPaint and the MandelBrot demo. It seems general enough
that it is probably useful to have it as a system-wide cursor rather
than loading it manually each time.
This can be used immediately in PixelPaint (separate commit), but
I am adding this as a system-wide cursor since it may also be useful
for other applications that want to use it.
Every tool that has a slider now registers the primary/secondary
sliders and now uses the same keyboard shortcuts to modify the
primary and secondary properties. `[` and `]` for the primary,
`{` and `}` for the secondary.
There are quite a few tools that might want to change certain values
based on consistent keyboard shortcuts. This commit allows tools to
hook up a "primary" and "secondary" slider with the base `Tool`
class, which can then handle updating those sliders with the common
shortcuts.
Note that any derived classes that want to override the `on_keydown`
function will manually need to call `Tool::on_keydown()`.
Previously there was no way to draw rectangles with any specific
thickness, like we can do with ellises, for instance. This method
is just a simple wrapper around `draw_line()` several times. At
least for now, we don't need to do anything sophisticated since
this will only be used by PixelPaint.`
This new class will open and parse files (either images directly or .pp
project files) and one can get the parsed Image as well as other
information from it.
This patch removes a bunch of 'try_create_from..." methods from Image in
favor of using the ProjectLoader.
The only json_metadata that is available are Guides for now.