diff --git a/apps/Makefile b/apps/Makefile index 6249c5f29..9f6d9959c 100644 --- a/apps/Makefile +++ b/apps/Makefile @@ -3,11 +3,11 @@ include apps/home/Makefile include apps/on_boarding/Makefile include apps/hardware_test/Makefile include apps/usb/Makefile -snapshots = +apps = # All selected apps are included. Each Makefile below is responsible for setting -# the $snapshots variable (name of the snapshot class) and the $snapshot_headers -# (path to the snapshot header). +# the $apps variable (name of the app class) and the $app_headers +# (path to the apps header). $(foreach i,${EPSILON_APPS},$(eval include apps/$(i)/Makefile)) app_objs += $(addprefix apps/,\ @@ -33,14 +33,15 @@ app_objs += $(addprefix apps/,\ variable_box_leaf_cell.o\ ) -snapshots_declaration = $(foreach i,$(snapshots),$(i) m_snapshot$(subst :,,$(i));) -snapshots_construction = $(foreach i,$(snapshots),,m_snapshot$(subst :,,$(i))()) -snapshots_list = $(foreach i,$(snapshots),,&m_snapshot$(subst :,,$(i))) -snapshots_count = $(words $(snapshots)) -snapshot_includes = $(foreach i,$(snapshot_headers),-include $(i) ) +snapshots_declaration = $(foreach i,$(apps),$(i)::Snapshot m_snapshot$(subst :,,$(i))Snapshot;) +apps_declaration = $(foreach i,$(apps),$(i) m_$(subst :,,$(i));) +snapshots_construction = $(foreach i,$(apps),,m_snapshot$(subst :,,$(i))Snapshot()) +snapshots_list = $(foreach i,$(apps),,&m_snapshot$(subst :,,$(i))Snapshot) +snapshots_count = $(words $(apps)) +snapshot_includes = $(foreach i,$(app_headers),-include $(i) ) epsilon_app_names = '$(foreach i,${EPSILON_APPS},"$(i)", )' -apps/apps_container_storage.o apps/main.o: CXXFLAGS += $(snapshot_includes) -DAPPS_CONTAINER_SNAPSHOT_DECLARATIONS="$(snapshots_declaration)" -DAPPS_CONTAINER_SNAPSHOT_CONSTRUCTORS="$(snapshots_construction)" -DAPPS_CONTAINER_SNAPSHOT_LIST="$(snapshots_list)" -DAPPS_CONTAINER_SNAPSHOT_COUNT=$(snapshots_count) -DEPSILON_APPS_NAMES=$(epsilon_app_names) +apps/apps_container_storage.o apps/main.o: CXXFLAGS += $(snapshot_includes) -DAPPS_CONTAINER_APPS_DECLARATION="$(apps_declaration)" -DAPPS_CONTAINER_SNAPSHOT_DECLARATIONS="$(snapshots_declaration)" -DAPPS_CONTAINER_SNAPSHOT_CONSTRUCTORS="$(snapshots_construction)" -DAPPS_CONTAINER_SNAPSHOT_LIST="$(snapshots_list)" -DAPPS_CONTAINER_SNAPSHOT_COUNT=$(snapshots_count) -DEPSILON_APPS_NAMES=$(epsilon_app_names) i18n_files += $(addprefix apps/language_,$(addsuffix .universal.i18n, $(EPSILON_I18N))) diff --git a/apps/apps_container_storage.h b/apps/apps_container_storage.h index c683b54bb..9e35962ae 100644 --- a/apps/apps_container_storage.h +++ b/apps/apps_container_storage.h @@ -13,7 +13,18 @@ public: AppsContainerStorage(); int numberOfApps() override; App::Snapshot * appSnapshotAtIndex(int index) override; + void * currentAppBuffer() override { return &m_apps; }; private: + union Apps { + public: + /* Enforce a trivial constructor and destructor that just leave the memory + * unmodified. This way, m_apps can be trivially destructed. */ + Apps() {}; + ~Apps() {}; + private: + APPS_CONTAINER_APPS_DECLARATION + }; + Apps m_apps; APPS_CONTAINER_SNAPSHOT_DECLARATIONS }; diff --git a/apps/calculation/Makefile b/apps/calculation/Makefile index 6cb7d73a6..c2b9bc190 100644 --- a/apps/calculation/Makefile +++ b/apps/calculation/Makefile @@ -1,5 +1,5 @@ -snapshots += Calculation::App::Snapshot -snapshot_headers += apps/calculation/app.h +apps += Calculation::App +app_headers += apps/calculation/app.h app_objs += $(addprefix apps/calculation/,\ app.o\ diff --git a/apps/calculation/app.cpp b/apps/calculation/app.cpp index d1bd94140..9fc012d3d 100644 --- a/apps/calculation/app.cpp +++ b/apps/calculation/app.cpp @@ -23,7 +23,7 @@ const Image * App::Descriptor::icon() { } App * App::Snapshot::unpack(Container * container) { - return new App(container, this); + return new (container->currentAppBuffer()) App(container, this); } void App::Snapshot::reset() { diff --git a/apps/code/Makefile b/apps/code/Makefile index e96475ff0..6207f39dc 100644 --- a/apps/code/Makefile +++ b/apps/code/Makefile @@ -1,5 +1,5 @@ -snapshots += Code::App::Snapshot -snapshot_headers += apps/code/app.h +apps += Code::App +app_headers += apps/code/app.h app_objs += $(addprefix apps/code/,\ app.o\ diff --git a/apps/code/app.cpp b/apps/code/app.cpp index a9b684fed..eccdb925b 100644 --- a/apps/code/app.cpp +++ b/apps/code/app.cpp @@ -27,7 +27,7 @@ App::Snapshot::Snapshot() : } App * App::Snapshot::unpack(Container * container) { - return new App(container, this); + return new (container->currentAppBuffer()) App(container, this); } void App::Snapshot::reset() { diff --git a/apps/graph/Makefile b/apps/graph/Makefile index 342bcfecd..7dbbaf8d3 100644 --- a/apps/graph/Makefile +++ b/apps/graph/Makefile @@ -1,5 +1,5 @@ -snapshots += Graph::App::Snapshot -snapshot_headers += apps/graph/app.h +apps += Graph::App +app_headers += apps/graph/app.h app_objs += $(addprefix apps/graph/,\ app.o\ diff --git a/apps/probability/Makefile b/apps/probability/Makefile index 080071ce2..510b0cf62 100644 --- a/apps/probability/Makefile +++ b/apps/probability/Makefile @@ -1,5 +1,5 @@ -snapshots += Probability::App::Snapshot -snapshot_headers += apps/probability/app.h +apps += Probability::App +app_headers += apps/probability/app.h app_objs += $(addprefix apps/probability/,\ app.o\ diff --git a/apps/regression/Makefile b/apps/regression/Makefile index e6518509b..57a950967 100644 --- a/apps/regression/Makefile +++ b/apps/regression/Makefile @@ -1,5 +1,5 @@ -snapshots += Regression::App::Snapshot -snapshot_headers += apps/regression/app.h +apps += Regression::App +app_headers += apps/regression/app.h app_objs += $(addprefix apps/regression/,\ app.o\ diff --git a/apps/sequence/Makefile b/apps/sequence/Makefile index 722141570..2941b50fb 100644 --- a/apps/sequence/Makefile +++ b/apps/sequence/Makefile @@ -1,5 +1,5 @@ -snapshots += Sequence::App::Snapshot -snapshot_headers += apps/sequence/app.h +apps += Sequence::App +app_headers += apps/sequence/app.h app_objs += $(addprefix apps/sequence/,\ app.o\ diff --git a/apps/settings/Makefile b/apps/settings/Makefile index 9078f0463..40bd2ac72 100644 --- a/apps/settings/Makefile +++ b/apps/settings/Makefile @@ -1,5 +1,5 @@ -snapshots += Settings::App::Snapshot -snapshot_headers += apps/settings/app.h +apps += Settings::App +app_headers += apps/settings/app.h app_objs += $(addprefix apps/settings/,\ app.o\ diff --git a/apps/solver/Makefile b/apps/solver/Makefile index 7f637d438..c010c0697 100644 --- a/apps/solver/Makefile +++ b/apps/solver/Makefile @@ -1,5 +1,5 @@ -snapshots += Solver::App::Snapshot -snapshot_headers += apps/solver/app.h +apps += Solver::App +app_headers += apps/solver/app.h app_objs += $(addprefix apps/solver/,\ app.o\ diff --git a/apps/statistics/Makefile b/apps/statistics/Makefile index 0caf06634..483a8785e 100644 --- a/apps/statistics/Makefile +++ b/apps/statistics/Makefile @@ -1,5 +1,5 @@ -snapshots += Statistics::App::Snapshot -snapshot_headers += apps/statistics/app.h +apps += Statistics::App +app_headers += apps/statistics/app.h app_objs += $(addprefix apps/statistics/,\ app.o\ diff --git a/escher/include/escher/app.h b/escher/include/escher/app.h index be767aedb..b86eeabfe 100644 --- a/escher/include/escher/app.h +++ b/escher/include/escher/app.h @@ -42,6 +42,8 @@ public: /* tidy clean all dynamically-allocated data */ virtual void tidy(); }; + /* The destructor has to be virtual. Otherwise calling a destructor on an + * App * pointing to a Derived App would have undefined behaviour. */ virtual ~App() = default; constexpr static uint8_t Magic = 0xA8; Snapshot * snapshot(); diff --git a/escher/include/escher/container.h b/escher/include/escher/container.h index 9855b5c33..8857c59bc 100644 --- a/escher/include/escher/container.h +++ b/escher/include/escher/container.h @@ -23,6 +23,7 @@ public: Container(Container&& other) = delete; Container& operator=(const Container& other) = delete; Container& operator=(Container&& other) = delete; + virtual void * currentAppBuffer() = 0; virtual void run(); App * activeApp(); virtual bool dispatchEvent(Ion::Events::Event event) override; diff --git a/escher/src/app.cpp b/escher/src/app.cpp index 4f343436e..87b20da31 100644 --- a/escher/src/app.cpp +++ b/escher/src/app.cpp @@ -18,7 +18,7 @@ const Image * App::Descriptor::icon() { void App::Snapshot::pack(App * app) { tidy(); - delete app; + app->~App(); } void App::Snapshot::reset() {