The new ver­sion puts a fo­cus on us­abil­i­ty with tweak­able con­stants for live cod­ing, Dear ImGui in­te­gra­tion, new pack­ages, Gra­dle-less An­droid de­vel­op­ment, com­pile time speedup and oth­er gen­er­al pol­ish­ing.

Tweak­able con­stants for live cod­ing

While Mag­num sup­port­ed code hot-reload through its Plug­in­Man­ag­er li­brary from the very be­gin­ning, now there’s a new, much faster — but al­so more re­strict­ed — coun­ter­part to it. In the con­text of live cod­ing, 90% it­er­a­tions is done on the da­ta, fid­dling with val­ues un­til they feel right. Even wait­ing few sec­onds for code to re­com­pile af­ter each such it­er­a­tion is still very time-con­sum­ing and of­ten the process is abrupt­ly end­ed when the val­ue is “good enough”. So, what if we wouldn’t need to re­com­pile?

Util­i­ty::Tweak­able is re­spon­si­ble for all the mag­ic shown in the above video and the gist of it is an abil­i­ty to up­date a run­ning ap­pli­ca­tion with con­stants from mod­i­fied source code — with­out re­com­pi­la­tion. The video al­so shows an ad­vanced IDE in­te­gra­tion with a col­or pick­er, how­ev­er the ba­sic ap­proach of code changes be­ing re­flect­ed im­me­di­ate­ly works with any ed­i­tor.

This fea­ture is still very ex­per­i­men­tal, on the roadmap is a sup­port for hot code reload and tweak­able con­stants un­der Em­scripten and on An­droid, we al­so plan on re­leas­ing IDE in­te­gra­tion plug­ins sim­i­lar to the one above once they reach a more ma­ture state.

Dear ImGui in­te­gra­tion is now of­fi­cial

In­te­gra­tion of Dear ImGui in­to Mag­num start­ed as a com­mu­ni­ty project and got so wide­ly used with mul­ti­ple forked ver­sions that it made sense to turn it in­to an of­fi­cial­ly main­tained li­brary. It’s now avail­able as ImGui­In­te­gra­tion, part of the mag­num-in­te­gra­tion repos­i­to­ry. The cor­re­spond­ing ex­am­ple is in­te­grat­ed as well and has a We­bGL 2 ver­sion avail­able:

Dear ImGui example screenshot
Dear ImGui Ex­am­ple wasm we­bgl2 ui
HiD­PI-en­abled im­me­di­ate-mode GUI ren­der­ing us­ing the Dear ImGui li­brary.

In­stead of hav­ing the Dear ImGui sources bun­dled with Mag­num, there’s a new Find­ImGui.cmake mod­ule that takes care of find­ing the sources and com­pil­ing them as part of ImGui­In­te­gra­tion. That gives you the pos­si­bil­i­ty of al­ways be­ing on ex­act­ly the ver­sion (or a fork) you need and the flex­i­bil­i­ty to bun­dle it your own way. Some pack­ag­ing sys­tems (such as Vcp­kg) pro­vide Dear ImGui as a li­brary, that’s sup­port­ed too.

An­i­ma­tion eas­in­gs li­brary

The an­i­ma­tion li­brary, which de­but­ed in the 2018.10 re­lease, re­ceived a col­lec­tion of var­i­ous eas­ing func­tions to add life to your an­i­ma­tions. To pro­vide a com­plete and cor­rect ref­er­ence for not just Mag­num users, the func­tions are al­so well-doc­u­ment­ed, with a cor­re­spond­ing math equa­tion, plot and the equiv­a­lent Bézi­er rep­re­sen­ta­tion, if it ex­ists. See the An­i­ma­tion::Eas­ing names­pace for your­self. Us­age is straigh­for­ward — sim­ply mod­i­fy the in­ter­po­la­tion fac­tor pa­ram­e­ter with them:

Vector3 result = Math::lerp(a, b, Animation::Easing::bounceIn(t));
Animation::Easing documentation

An­droid de­vel­op­ment, but with­out the pain

Con­trary to pop­u­lar be­lief, nei­ther An­droid Stu­dio nor Gra­dle is re­quired to de­vel­op apps for An­droid. With 2019.01, there’s a new CMake macro android_create_apk() that al­lows you to cre­ate an APK di­rect­ly from CMake, with­out need­ing to touch Gra­dle 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, us­ing this macro al­so adds a new build tar­get which al­lows you to build, in­stall, pack­age, sign and de­ploy an APK to a de­vice with a sin­gle com­mand — for ex­am­ple when us­ing Nin­ja:

$ ninja my-application-deploy
[5/5] Installing my-application.apk
Success

This func­tion­al­i­ty is cur­rent­ly ex­per­i­men­tal and very lim­it­ed, but it can save you sev­er­al sec­onds on each de­ploy com­pared to equiv­a­lent work­flow us­ing Gra­dle. See the very ex­ten­sive An­droid build­ing docs for more in­for­ma­tion.

Drop­ping GCC 4.7 and CMake 2.8.12 sup­port

With Ubun­tu 14.04 go­ing away even on Travis CI, it was a time to say good­bye to com­pat­i­bil­i­ty with the old CMake 2.8.12. How­ev­er, ver­sion 3.0 had some is­sues with im­port­ed tar­gets, so the min­i­mal re­quired ver­sion is now 3.1. All suf­fi­cient­ly mod­ern Lin­ux dis­tri­bu­tions (ex­cept De­bian Jessie) are al­ready on ver­sions past 3.1, so this should not be a prob­lem — and if not, you can al­ways down­load and use an of­fi­cial CMake bi­na­ry on af­fect­ed sys­tems.

While at it, sup­port for GCC 4.7 was dropped as well, since this is the last com­pil­er that didn’t sup­port rval­ue over­loads for this. Min­i­mal ver­sion is now 4.8.1, since 4.8 is still used on Cen­tOS 7 and we don’t want to pre­vent Mag­num from be­ing used on serv­er side as well.

As far as C++ stan­dard goes, Mag­num is go­ing to stay on C++11 for the fore­see­able fu­ture. Ex­cept for ex­tend­ed constexpr, nei­ther C++14 nor C++17 of­fers any­thing that would lead to sig­nif­i­cant im­prove­ments on the li­brary side and the mi­nor ad­van­tages are not worth the com­pile time slow­downs due to in­crease in STL head­er bloat. How­ev­er, Mag­num is not for­bid­ding you to jump to new­er C++ stan­dards — if you need the re­cent fea­tures, feel free to use them.

On­go­ing com­pile-time and bi­na­ry size im­prove­ments

Speak­ing of STL head­er bloat, and not en­tire­ly un­re­lat­ed to the re­cent out­rage about “The State Of C++”, Mag­num is un­der­go­ing a gen­er­al up­date that aims for short­ened com­pile times and small­er bi­na­ry sizes, es­pe­cial­ly in We­bAssem­bly builds. Right now, this is main­ly about re­duc­ing the amount of STL in­cludes in head­ers and be­cause not all ba­si­cal­ly no STL con­tain­ers can be eas­i­ly for­ward-de­clared, it means re­plac­ing them with cus­tom al­ter­na­tives.

As not all up­dates can be made in a back­wards-com­pat­i­ble way, the change is hap­pen­ing grad­u­al­ly — this re­lease re­places most us­es of std::unique_p­tr and std::ref­er­ence_wrap­per with Con­tain­ers::Point­er and Con­tain­ers::Ref­er­ence in or­der to avoid heavy <memory> and <functional> in­cludes and the work will con­tin­ue in fu­ture re­leas­es.

As with all oth­er de­sign de­ci­sions in Mag­num, this doesn’t mean the en­gine will now un­con­di­tion­al­ly force you to use some alien types. In­stead, you have a choice — if you feel more com­fort­able us­ing stan­dard types, your team is not ready to learn yet an­oth­er API or you’re in­ter­act­ing with a 3rd par­ty lib that us­es them any­way, just keep us­ing them, the new Mag­num point­er and ref­er­ence types are im­plic­it­ly con­vert­ible to and from the STL equiv­a­lents. On the oth­er hand, if you re­al­ly care about your com­pile times and de­bug per­for­mance, the new types are for you — and you’re en­cour­aged to use them else­where as well, not just when in­ter­act­ing with Mag­num.

Sin­gle-head­er ver­sions of Mag­num APIs

A re­lat­ed on­go­ing project, which is ba­si­cal­ly a side-prod­uct of the above “head­er di­et” work, is avail­abil­i­ty of var­i­ous Mag­num APIs as sin­gle-head­er li­braries — with a fo­cus on ease of in­te­gra­tion, fast com­pile times and small file sizes, while in­her­it­ing >99% test cov­er­age and ex­ten­sive doc­u­men­ta­tion that’s own to the Mag­num project it­self.

Com­bin­ing all that is on­ly pos­si­ble be­cause the func­tion­al­i­ty is pri­mar­i­ly main­tained, doc­u­ment­ed and test­ed as part of Mag­num, where it can make use of all the in­fra­struc­ture and tool­ing. Se­lect­ed func­tion­al­i­ty is then ex­tract­ed via a script that strips it of com­ments, ver­bose doc­u­men­ta­tion blocks and rarely used func­tion­al­i­ty. The re­sult is a small self-con­tained file, how­ev­er still with the con­fi­dence of all code paths be­ing prop­er­ly test­ed and doc­u­ment­ed.

The mag­num-sin­gles repos­i­to­ry is a new home for the sin­gle-head­er ver­sions of var­i­ous Mag­num APIs. At the mo­ment the fol­low­ing low-lev­el con­tain­ers are present:

Li­brary LoC Pre­pro­cessed LoC De­scrip­tion
Cor­radeOp­tion­al.h 328 2742 See Con­tain­ers::Op­tion­al docs
Cor­rade­Point­er.h 259 2321 See Con­tain­ers::Point­er docs
Cor­radeRef­er­ence.h 115 1639 See Con­tain­ers::Ref­er­ence docs
Cor­rade­Scope­Guard.h 108 26 See Con­tain­ers::Scope­Guard docs

More li­braries are to come as the head­er cleanup ad­vances fur­ther. The gen­er­al rule for ex­pos­ing a fea­ture as a sin­gle-head­er li­brary is how much it in­flates af­ter pre­pro­cess­ing — cur­rent­ly the soft up­per lim­it is 10k lines. For com­par­i­son, not even the <string> head­er fits in there, as it has 12k; on the oth­er hand I’m pret­ty con­fi­dent I can squeeze the whole Math li­brary un­der this lim­it.

Vulkan++

As an­oth­er small piece of the Vulkan puz­zle, the new Mag­num/Vk/In­te­gra­tion.h head­er pro­vides con­ver­sion be­tween ba­sic Vulkan types and their equiv­a­lents from the Math li­brary, to­geth­er with enum trans­la­tion con­tribut­ing to a smoother in­ter­ac­tion with raw Vulkan code.

VkOffset2D a{64, 32};
Vector2i b(a);

using namespace Math::Literals;
VkClearColorValue c = VkClearColorValue(0x5297d7_srgbf);

Since Mag­num now pro­vides math in­te­gra­tion for quite a few li­braries, in­clud­ing ImGui, there’s a full list pro­vid­ing de­tailed in­for­ma­tion about avail­able con­ver­sions for ev­ery third-par­ty API.

Qual­i­ty-of-Life im­prove­ments in the doc­u­men­ta­tion

The Mag­num doc­u­men­ta­tion re­ceived a larg­er up­date, main­ly re­lat­ed to search func­tion­al­i­ty. It’s now al­so show­ing the cor­re­spond­ing #include for each API — and that’s not just class­es, but al­so free func­tions, types and sin­gle-file names­paces. De­tails in this ar­ti­cle.

Include information for free namespace members

Hunter, MSYS2 and Co­nan pack­ages

Thanks to our ded­i­cat­ed com­mu­ni­ty, Cor­rade, Mag­num and Mag­num Plug­ins now have MSYS2 pack­ages. These are based off the Arch­Lin­ux PKGBUILDs (since both use pacman as the pack­age man­ag­er) and there’s both a in-source pack­age, build­ing the cur­rent­ly checked out work­ing tree; and a sta­ble one, down­load­ing a re­lease tar­ball.

Apart from MSYS2, Mag­num is now avail­able in both Co­nan and Hunter pack­age man­agers. While Hunter is CMake-based and works di­rect­ly from in­side the CMake build di­rec­to­ry with­out any ad­di­tion­al de­pen­den­cies, Co­nan is buildsys­tem-in­de­pen­dent, but re­quires you to in­stall the Co­nan client first. Note that while Cor­rade for Co­nan is al­ready there, the Mag­num pack­age is still work-in-progress.

Home­brew and Vcp­kg pack­ages are al­ready on the lat­est ver­sion, Arch­Lin­ux pack­ages are sched­uled to be up­dat­ed soon.

Up­dat­ing from pre­vi­ous ver­sions

If you build Mag­num with BUILD_DEP­RE­CAT­ED en­abled (the de­fault), most of the above-men­tioned changes re­lat­ed to std::unique_p­tr, std::ref­er­ence_wrap­per etc. should not re­sult in any source-break­ing changes — stan­dard types used in your code will still work as be­fore. How­ev­er, due to the gen­er­al head­er cleanup, you might end up with a bunch of “in­com­plete type” er­rors, as defini­tons for­mer­ly tran­si­tive­ly in­clud­ed from oth­er head­ers won’t be present any­more. In par­tic­u­lar, due to re­moval of long-dep­re­cat­ed fea­tures, the Con­tain­ers::Op­tion­al type is now on­ly for­ward-de­clared in all im­porter plug­in APIs, and sim­i­lar­ly it is with Con­tain­ers::Ref­er­ence, so you may need to add some of these to your code­bas­es:

#include <Corrade/Containers/Optional.h>
#include <Corrade/Containers/Reference.h>

In or­der to keep your code for­ward com­pat­i­ble, the rule should be to al­ways ex­plic­it­ly in­clude all types that you use in the par­tic­u­lar source file and not re­ly on the def­i­ni­tions be­ing present due to in­ter­nal en­gine head­er struc­ture. In prac­tice this is quite hard to achieve, on the oth­er hand due to the evolv­ing na­ture of the li­brary, there’s not much Mag­num it­self can do to pre­vent such break­ages.

This ver­sion al­so starts to re­move APIs dep­re­cat­ed in 2018.02 (the first re­lease af­ter three years with­out sta­ble up­dates), mean­ing if you still have code­bas­es that are from be­fore this ver­sion, these will def­i­nite­ly not work any­more. The rec­om­mend­ed up­grade path is, as al­ways, go­ing through the sta­ble ver­sions one-by-one and fix­ing er­rors and dep­re­ca­tion warn­ings as they ap­pear — jump­ing straight to lat­est won’t be nowhere near a smooth up­grade ex­pe­ri­ence.

For a com­plete over­view of new­ly dep­re­cat­ed fea­tures and pos­si­ble com­pat­i­bil­i­ty break­ages, check the changel­ogs list­ed be­low.

Com­plete changel­og

There’s many more lit­tle things — im­proved constexpr sup­port for ar­ray view class­es, new im­porter plug­in for AAC au­dio files, abil­i­ty to switch to the stan­dard C assert() macro for as­ser­tions etc. See the full changel­ogs for more:

Spe­cial thanks

Many things in this re­lease wouldn’t be pos­si­ble with­out ded­i­ca­tion of sev­er­al con­trib­u­tors: