The new version puts a focus on usability with tweakable constants for live coding, Dear ImGui integration, new packages, Gradle-less Android development, compile time speedup and other general polishing.
Tweakable constants for live coding
While Magnum supported code hot-reload through its PluginManager library from the very beginning, now there’s a new, much faster — but also more restricted — counterpart to it. In the context of live coding, 90% iterations is done on the data, fiddling with values until they feel right. Even waiting few seconds for code to recompile after each such iteration is still very time-consuming and often the process is abruptly ended when the value is “good enough”. So, what if we wouldn’t need to recompile?
Hot code reload? Check! With instant feedback? Sure! And visual input in the editor? Um … yes, of course! This is how my workflow with #MagnumEngine and #KDevelop looks like now. In pure C++. 😎 #cpp #cplusplus #gamedev #livereload pic.twitter.com/o45TiSsQsu
— Vladimír Vondruš (@czmosra) November 6, 2018
Utility::Tweakable is responsible for all the magic shown in the above video and the gist of it is an ability to update a running application with constants from modified source code — without recompilation. The video also shows an advanced IDE integration with a color picker, however the basic approach of code changes being reflected immediately works with any editor.
This feature is still very experimental, on the roadmap is a support for hot code reload and tweakable constants under Emscripten and on Android, we also plan on releasing IDE integration plugins similar to the one above once they reach a more mature state.
Dear ImGui integration is now official
Integration of Dear ImGui into Magnum started as a community project and got so widely used with multiple forked versions that it made sense to turn it into an officially maintained library. It’s now available as ImGuiIntegration, part of the magnum-integration repository. The corresponding example is integrated as well and has a WebGL 2 version available:
Instead of having the Dear ImGui sources bundled with Magnum, there’s a new FindImGui.cmake module that takes care of finding the sources and compiling them as part of ImGuiIntegration. That gives you the possibility of always being on exactly the version (or a fork) you need and the flexibility to bundle it your own way. Some packaging systems (such as Vcpkg) provide Dear ImGui as a library, that’s supported too.
Animation easings library
The animation library, which debuted in the 2018.10 release, received a collection of various easing functions to add life to your animations. To provide a complete and correct reference for not just Magnum users, the functions are also well-documented, with a corresponding math equation, plot and the equivalent Bézier representation, if it exists. See the Animation::Easing namespace for yourself. Usage is straighforward — simply modify the interpolation factor parameter with them:
Vector3 result = Math::lerp(a, b, Animation::Easing::bounceIn(t));
Android development, but without the pain
Contrary to popular belief, neither Android Studio nor Gradle is required to
develop apps for Android. With 2019.01, there’s a new CMake macro android_create_apk()
that allows you to create an APK directly from
CMake, without needing to touch Gradle at all:
find_package(Magnum REQUIRED AndroidApplication) add_library(my-application SHARED MyApp.cpp) target_link_libraries(my-application PRIVATE Magnum::Magnum Magnum::Application) android_create_apk(my-application AndroidManifest.xml)
As a bonus, using this macro also adds a new build target which allows you to build, install, package, sign and deploy an APK to a device with a single command — for example when using Ninja:
$ ninja my-application-deploy [5/5] Installing my-application.apk Success
This functionality is currently experimental and very limited, but it can save you several seconds on each deploy compared to equivalent workflow using Gradle. See the very extensive Android building docs for more information.
Dropping GCC 4.7 and CMake 2.8.12 support
With Ubuntu 14.04 going away even on Travis CI, it was a time to say goodbye to compatibility with the old CMake 2.8.12. However, version 3.0 had some issues with imported targets, so the minimal required version is now 3.1. All sufficiently modern Linux distributions (except Debian Jessie) are already on versions past 3.1, so this should not be a problem — and if not, you can always download and use an official CMake binary on affected systems.
While at it, support for GCC 4.7 was dropped as well, since this is the last
compiler that didn’t support rvalue overloads for this
. Minimal version
is now 4.8.1, since 4.8 is still used on CentOS 7 and we don’t want to prevent
Magnum from being used on server side as well.
As far as C++ standard goes, Magnum is going to stay on C++11 for the
foreseeable future. Except for extended constexpr
, neither C++14 nor
C++17 offers anything that would lead to significant improvements on the
library side and the minor advantages are not worth the compile time slowdowns
due to increase in STL header bloat.
However, Magnum is not forbidding you to jump to newer C++ standards — if
you need the recent features, feel free to use them.
Ongoing compile-time and binary size improvements
Speaking of STL header bloat, and not entirely unrelated to the recent outrage about “The State Of C++”, Magnum is undergoing a general update that aims for shortened compile times and smaller binary sizes, especially in WebAssembly builds. Right now, this is mainly about reducing the amount of STL includes in headers and because not all basically no STL containers can be easily forward-declared, it means replacing them with custom alternatives.
As not all updates can be made in a backwards-compatible way, the change is
happening gradually — this release replaces most uses of
std::unique_ptr and std::reference_wrapper with
Containers::Pointer and Containers::Reference in order to avoid
heavy <memory>
and <functional>
includes and the work will continue in
future releases.
As with all other design decisions in Magnum, this doesn’t mean the engine will now unconditionally force you to use some alien types. Instead, you have a choice — if you feel more comfortable using standard types, your team is not ready to learn yet another API or you’re interacting with a 3rd party lib that uses them anyway, just keep using them, the new Magnum pointer and reference types are implicitly convertible to and from the STL equivalents. On the other hand, if you really care about your compile times and debug performance, the new types are for you — and you’re encouraged to use them elsewhere as well, not just when interacting with Magnum.
Single-header versions of Magnum APIs
A related ongoing project, which is basically a side-product of the above “header diet” work, is availability of various Magnum APIs as single-header libraries — with a focus on ease of integration, fast compile times and small file sizes, while inheriting >99% test coverage and extensive documentation that’s own to the Magnum project itself.
Combining all that is only possible because the functionality is primarily maintained, documented and tested as part of Magnum, where it can make use of all the infrastructure and tooling. Selected functionality is then extracted via a script that strips it of comments, verbose documentation blocks and rarely used functionality. The result is a small self-contained file, however still with the confidence of all code paths being properly tested and documented.
The magnum-singles repository is a new home for the single-header versions of various Magnum APIs. At the moment the following low-level containers are present:
Library | LoC | Preprocessed LoC | Description |
---|---|---|---|
CorradeOptional.h | 328 | 2742 | See Containers::Optional docs |
CorradePointer.h | 259 | 2321 | See Containers::Pointer docs |
CorradeReference.h | 115 | 1639 | See Containers::Reference docs |
CorradeScopeGuard.h | 108 | 26 | See Containers::ScopeGuard docs |
More libraries are to come as the header cleanup advances further. The general
rule for exposing a feature as a single-header library is how much it inflates
after preprocessing — currently the soft upper limit is 10k lines. For
comparison, not even the <string>
header fits in there, as it has 12k; on
the other hand I’m pretty confident I can squeeze the whole Math library
under this limit.
Vulkan++
As another small piece of the Vulkan puzzle, the new Magnum/Vk/Integration.h header provides conversion between basic Vulkan types and their equivalents from the Math library, together with enum translation contributing to a smoother interaction with raw Vulkan code.
VkOffset2D a{64, 32}; Vector2i b(a); using namespace Math::Literals; VkClearColorValue c = VkClearColorValue(0x5297d7_srgbf);
Since Magnum now provides math integration for quite a few libraries, including ImGui, there’s a full list providing detailed information about available conversions for every third-party API.
Quality-of-Life improvements in the documentation
The Magnum documentation received a larger update, mainly related to search
functionality. It’s now also showing the corresponding #include
for each
API — and that’s not just classes, but also free functions, types and
single-file namespaces. Details in this article.
Hunter, MSYS2 and Conan packages
Thanks to our dedicated community, Corrade, Magnum and Magnum Plugins now have
MSYS2 packages. These are based off the ArchLinux
PKGBUILD
s (since both use pacman
as the package manager) and there’s
both a in-source package, building the currently checked out working tree; and
a stable one, downloading a release tarball.
Apart from MSYS2, Magnum is now available in both Conan and Hunter package managers. While Hunter is CMake-based and works directly from inside the CMake build directory without any additional dependencies, Conan is buildsystem-independent, but requires you to install the Conan client first. Note that while Corrade for Conan is already there, the Magnum package is still work-in-progress.
Homebrew and Vcpkg packages are already on the latest version, ArchLinux packages are scheduled to be updated soon.
Updating from previous versions
If you build Magnum with BUILD_DEPRECATED enabled (the default), most of the above-mentioned changes related to std::unique_ptr, std::reference_wrapper etc. should not result in any source-breaking changes — standard types used in your code will still work as before. However, due to the general header cleanup, you might end up with a bunch of “incomplete type” errors, as definitons formerly transitively included from other headers won’t be present anymore. In particular, due to removal of long-deprecated features, the Containers::Optional type is now only forward-declared in all importer plugin APIs, and similarly it is with Containers::Reference, so you may need to add some of these to your codebases:
#include <Corrade/Containers/Optional.h> #include <Corrade/Containers/Reference.h>
In order to keep your code forward compatible, the rule should be to always explicitly include all types that you use in the particular source file and not rely on the definitions being present due to internal engine header structure. In practice this is quite hard to achieve, on the other hand due to the evolving nature of the library, there’s not much Magnum itself can do to prevent such breakages.
This version also starts to remove APIs deprecated in 2018.02 (the first release after three years without stable updates), meaning if you still have codebases that are from before this version, these will definitely not work anymore. The recommended upgrade path is, as always, going through the stable versions one-by-one and fixing errors and deprecation warnings as they appear — jumping straight to latest won’t be nowhere near a smooth upgrade experience.
For a complete overview of newly deprecated features and possible compatibility breakages, check the changelogs listed below.
Complete changelog
There’s many more little things — improved constexpr
support for array
view classes, new importer plugin for AAC audio files, ability to switch to the
standard C assert()
macro for assertions etc. See the full changelogs
for more:
Special thanks
Many things in this release wouldn’t be possible without dedication of several contributors:
- Jonathan Hale (@Squareys), Guillaume Jacquemin (@williamjcm), @denesik, Natesh Narain (@nnarain), Tomáš Skřivan (@lecopivo) and @ShaddyDC — the ImGuiIntegration library and a corresponding example
- Max Schwarz (@xqms) — fixes and clarifications in the BulletIntegration library and memory leak plugs in the corresponding example
- Borislav Stanimirov (@iboB) — strict weak ordering for Math types
- Guillaume Jacquemin (@williamjcm) — MSYS2 packages
- Pascal Thomet (@pthom), Ruslan Baratov (@ruslo) — Hunter packages
- Fred Helmesjö (@helmesjo), Michael “Croydon” Keck (@Croydon) — Conan packages
- Jonathan Hale (@Squareys) — continued Vcpkg package maintenance
- Alexander F Rødseth (@xyproto) — continued ArchLinux
[community]
package maintenance - Erik Wijmans (@erikwijmans) — NVidia-specific workarounds for headless EGL contexts
- Steeve Morin (@steeve), Fabien Freling (@ffreling) and Thomas Tissot-Dupont (@dolphineye) — iOS- and Android-specific driver workarounds and improvements