This removes one unnecessary allocation from each application startup.
In some cases of the windowless apps the Platform::GLContext could be
put directly into the class, in other cases it had to be wrapped in an
Optional because we need delayed construction and/or earlier
destruction.
So in case it touches the GL state in some way, it doesn't do that on an
already destroyed context. The windowless apps do this all implicitly
due to the WindowlessGLContext encapsulation.
Right now only the command-line variant of it was checked. Since on
some platforms this requires the app to explicitly request a debug
context, the app needs to handle the case when it's passed via a
Configuration as well.
Disabling engine startup log or modifying enabled extensions /
workarounds from the application side was one of the common pain
points and this should *finally* solve the problem. This Configuration
is now inherited by the usual Platform::*Application::GLConfiguration /
Platform::Windowless*Application::Configuration classes people are used
to, so for the end user it's just as if these classes got a bunch new
options.
Having this, I also extended the ContextGLTest to verify that the
Configuration and command-line options do what's expected because that
hadn't automated tests until now. The test is mostly a copy of what I
did for Vulkan already, nothing special. Additionally all
Platform*ApplicationTest executables gained a new --quiet option to
verify that the GL::Context::Configuration subset gets correctly passed
from the Application code, because that's something we can't really
verify in an automated way.
These are in most cases the only strings that are used, and I don't
think having to call std::strlen() for each of them is a good idea if
we don't need to.
There's four more new cursors and the _cursors array was too small.
At first I got confused because I thought the assertion on top is done
against the CursorMap, which didn't contain the Hidden cursors. So to
avoid confusing myself again in the future, I moved the assert after the
special cases and made both arrays the same size since it doesn't make
sense to have always-empty fields in there.
Similar change is done in Sdl2Application, and an assert is added to
avoid a nondescript crash if the window is not created yet.
It was printing 0 before, which isn't correct. Also why not print both
values? Printing just the first one would hide issues where the second
is accidentally 0 or some other wrong value.
Instead of first entering the main loop, processing events etc. This
also makes it finally possible to exit the application cleanly, with all
non-global destructors executed as well.
If the application is constructed with delayed window creation, the
warning would be printed on each context creation attempt / call to
dpiScaling(const Configuration&), which is silly.
The event wasn't fired when the window size got changed through an API
call. Unfortunately after this change the event gets fired any time
I call setMaxWindowSize(), not just when the size changes.
On Emscripten as well, however I'm keeping the Configuration::setTitle()
a no-op because the title is usually set by the HTML markup already and
so dynamic code implicitly changing it to something else doesn't make
much sense.