Skip to content

Commit 63e0c4f

Browse files
committed
Application selection at build time
A list of "user applications" is built at compile time. It contains all the info needed to create the application at runtime (ptr to a create() function) and to display the app in the application menu. All applications declare a TypeTrait with these information. When a new app must be loaded, DisplayApp first check if this app is a System app (in which case it creates it like it did before). If it's not a System app, it looks for the app in the list of User applications and creates it if it found it. Those changes allow to more easily add new app and to select which app must be built into the firmware. Switch to C++20 (and fix a few issues in SpiMaster.cpp and Watchdog.cpp.
1 parent f6d7f60 commit 63e0c4f

29 files changed

+445
-190
lines changed

CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose Debug or Release")
55
project(pinetime VERSION 1.13.0 LANGUAGES C CXX ASM)
66

77
set(CMAKE_C_STANDARD 99)
8-
set(CMAKE_CXX_STANDARD 14)
8+
set(CMAKE_CXX_STANDARD 20)
99

1010
# set(CMAKE_GENERATOR "Unix Makefiles")
1111
set(CMAKE_C_EXTENSIONS OFF)

src/CMakeLists.txt

-1
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,6 @@ list(APPEND SOURCE_FILES
394394
displayapp/screens/Notifications.cpp
395395
displayapp/screens/Twos.cpp
396396
displayapp/screens/HeartRate.cpp
397-
displayapp/screens/Motion.cpp
398397
displayapp/screens/FlashLight.cpp
399398
displayapp/screens/List.cpp
400399
displayapp/screens/CheckboxList.cpp

src/displayapp/Apps.h

+27-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#pragma once
2-
2+
#include <cstddef>
33
namespace Pinetime {
44
namespace Applications {
55
enum class Apps {
@@ -37,7 +37,32 @@ namespace Pinetime {
3737
SettingChimes,
3838
SettingShakeThreshold,
3939
SettingBluetooth,
40-
Error
40+
Error,
41+
Weather
42+
};
43+
template <Apps>
44+
struct AppTraits {};
45+
46+
template<Apps ...As>
47+
struct TypeList {
48+
static constexpr size_t Count = sizeof...(As);
4149
};
50+
51+
using UserAppTypes = TypeList<Apps::Alarm,
52+
Apps::HeartRate,
53+
Apps::Paint,
54+
Apps::Metronome,
55+
Apps::Music,
56+
Apps::Navigation,
57+
Apps::Paddle,
58+
Apps::Steps,
59+
Apps::StopWatch,
60+
Apps::Timer,
61+
Apps::Twos
62+
/*
63+
Apps::Weather,
64+
Apps::Motion
65+
*/
66+
>;
4267
}
4368
}

src/displayapp/Controllers.h

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#pragma once
2+
namespace Pinetime {
3+
namespace Applications {
4+
class DisplayApp;
5+
}
6+
namespace Components {
7+
class LittleVgl;
8+
}
9+
namespace Controllers {
10+
class Battery;
11+
class Ble;
12+
class DateTime;
13+
class NotificationManager;
14+
class HeartRateController;
15+
class Settings;
16+
class MotorController;
17+
class MotionController;
18+
class AlarmController;
19+
class BrightnessController;
20+
class WeatherService;
21+
class FS;
22+
class Timer;
23+
class MusicService;
24+
class NavigationService;
25+
}
26+
namespace System {
27+
class SystemTask;
28+
}
29+
namespace Applications {
30+
struct AppControllers {
31+
const Pinetime::Controllers::Battery& batteryController;
32+
const Pinetime::Controllers::Ble& bleController;
33+
Pinetime::Controllers::DateTime& dateTimeController;
34+
Pinetime::Controllers::NotificationManager& notificationManager;
35+
Pinetime::Controllers::HeartRateController& heartRateController;
36+
Pinetime::Controllers::Settings& settingsController;
37+
Pinetime::Controllers::MotorController& motorController;
38+
Pinetime::Controllers::MotionController& motionController;
39+
Pinetime::Controllers::AlarmController& alarmController;
40+
Pinetime::Controllers::BrightnessController& brightnessController;
41+
Pinetime::Controllers::WeatherService* weatherController;
42+
Pinetime::Controllers::FS& filesystem;
43+
Pinetime::Controllers::Timer& timer;
44+
Pinetime::System::SystemTask* systemTask;
45+
Pinetime::Applications::DisplayApp* displayApp;
46+
Pinetime::Components::LittleVgl& lvgl;
47+
Pinetime::Controllers::MusicService* musicService;
48+
Pinetime::Controllers::NavigationService* navigationService;
49+
};
50+
}
51+
}

src/displayapp/DisplayApp.cpp

+53-49
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include "displayapp/screens/settings/SettingBluetooth.h"
5151

5252
#include "libs/lv_conf.h"
53+
#include "UserApps.h"
5354

5455
using namespace Pinetime::Applications;
5556
using namespace Pinetime::Applications::Display;
@@ -96,7 +97,12 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd,
9697
touchHandler {touchHandler},
9798
filesystem {filesystem},
9899
lvgl {lcd, filesystem},
99-
timer(this, TimerCallback) {
100+
timer(this, TimerCallback),
101+
controllers{
102+
batteryController, bleController, dateTimeController, notificationManager, heartRateController,
103+
settingsController, motorController, motionController, alarmController, brightnessController,
104+
nullptr, filesystem, timer, nullptr, this, lvgl, nullptr, nullptr}
105+
{
100106
}
101107

102108
void DisplayApp::Start(System::BootErrors error) {
@@ -402,14 +408,21 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
402408
SetFullRefresh(direction);
403409

404410
switch (app) {
405-
case Apps::Launcher:
406-
currentScreen =
407-
std::make_unique<Screens::ApplicationList>(this, settingsController, batteryController, bleController, dateTimeController, filesystem);
408-
break;
409-
case Apps::Motion:
410-
// currentScreen = std::make_unique<Screens::Motion>(motionController);
411-
// break;
412-
case Apps::None:
411+
case Apps::Launcher: {
412+
std::array<Screens::Tile::Applications, UserAppTypes::Count> apps;
413+
int i = 0;
414+
for (const auto& userApp : userApps) {
415+
apps[i++] = Screens::Tile::Applications {userApp.icon, userApp.app, true};
416+
}
417+
currentScreen = std::make_unique<Screens::ApplicationList>(this,
418+
settingsController,
419+
batteryController,
420+
bleController,
421+
dateTimeController,
422+
filesystem,
423+
std::move(apps));
424+
}
425+
break;
413426
case Apps::Clock:
414427
currentScreen = std::make_unique<Screens::Clock>(dateTimeController,
415428
batteryController,
@@ -421,7 +434,6 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
421434
systemTask->nimble().weather(),
422435
filesystem);
423436
break;
424-
425437
case Apps::Error:
426438
currentScreen = std::make_unique<Screens::Error>(bootError);
427439
break;
@@ -453,14 +465,6 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
453465
*systemTask,
454466
Screens::Notifications::Modes::Preview);
455467
break;
456-
case Apps::Timer:
457-
currentScreen = std::make_unique<Screens::Timer>(timer);
458-
break;
459-
case Apps::Alarm:
460-
currentScreen = std::make_unique<Screens::Alarm>(alarmController, settingsController.GetClockType(), *systemTask, motorController);
461-
break;
462-
463-
// Settings
464468
case Apps::QuickSettings:
465469
currentScreen = std::make_unique<Screens::QuickSettings>(this,
466470
batteryController,
@@ -516,38 +520,25 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio
516520
case Apps::FlashLight:
517521
currentScreen = std::make_unique<Screens::FlashLight>(*systemTask, brightnessController);
518522
break;
519-
case Apps::StopWatch:
520-
currentScreen = std::make_unique<Screens::StopWatch>(*systemTask);
521-
break;
522-
case Apps::Twos:
523-
currentScreen = std::make_unique<Screens::Twos>();
524-
break;
525-
case Apps::Paint:
526-
currentScreen = std::make_unique<Screens::InfiniPaint>(lvgl, motorController);
527-
break;
528-
case Apps::Paddle:
529-
currentScreen = std::make_unique<Screens::Paddle>(lvgl);
530-
break;
531-
case Apps::Music:
532-
currentScreen = std::make_unique<Screens::Music>(systemTask->nimble().music());
533-
break;
534-
case Apps::Navigation:
535-
currentScreen = std::make_unique<Screens::Navigation>(systemTask->nimble().navigation());
536-
break;
537-
case Apps::HeartRate:
538-
currentScreen = std::make_unique<Screens::HeartRate>(heartRateController, *systemTask);
539-
break;
540-
case Apps::Metronome:
541-
currentScreen = std::make_unique<Screens::Metronome>(motorController, *systemTask);
542-
break;
543-
/* Weather debug app
544-
case Apps::Weather:
545-
currentScreen = std::make_unique<Screens::Weather>(this, systemTask->nimble().weather());
546-
break;
547-
*/
548-
case Apps::Steps:
549-
currentScreen = std::make_unique<Screens::Steps>(motionController, settingsController);
523+
default: {
524+
const auto* d = std::find_if(userApps.begin(), userApps.end(), [app](const AppDescription& appDescription) {
525+
return appDescription.app == app;
526+
});
527+
if (d != userApps.end())
528+
currentScreen.reset(d->create(controllers));
529+
else {
530+
currentScreen = std::make_unique<Screens::Clock>(dateTimeController,
531+
batteryController,
532+
bleController,
533+
notificationManager,
534+
settingsController,
535+
heartRateController,
536+
motionController,
537+
systemTask->nimble().weather(),
538+
filesystem);
539+
}
550540
break;
541+
}
551542
}
552543
currentApp = app;
553544
}
@@ -605,6 +596,19 @@ void DisplayApp::PushMessageToSystemTask(Pinetime::System::Messages message) {
605596

606597
void DisplayApp::Register(Pinetime::System::SystemTask* systemTask) {
607598
this->systemTask = systemTask;
599+
this->controllers.systemTask = systemTask;
600+
}
601+
602+
void DisplayApp::Register(Pinetime::Controllers::WeatherService* weatherService) {
603+
this->controllers.weatherController = weatherService;
604+
}
605+
606+
void DisplayApp::Register(Pinetime::Controllers::MusicService* musicService) {
607+
this->controllers.musicService = musicService;
608+
}
609+
610+
void DisplayApp::Register(Pinetime::Controllers::NavigationService* NavigationService) {
611+
this->controllers.navigationService = NavigationService;
608612
}
609613

610614
void DisplayApp::ApplyBrightness() {

src/displayapp/DisplayApp.h

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "BootErrors.h"
2121

2222
#include "utility/StaticStack.h"
23+
#include "displayapp/Controllers.h"
2324

2425
namespace Pinetime {
2526

@@ -73,6 +74,9 @@ namespace Pinetime {
7374
void SetFullRefresh(FullRefreshDirections direction);
7475

7576
void Register(Pinetime::System::SystemTask* systemTask);
77+
void Register(Pinetime::Controllers::WeatherService* weatherService);
78+
void Register(Pinetime::Controllers::MusicService* musicService);
79+
void Register(Pinetime::Controllers::NavigationService* NavigationService);
7680

7781
private:
7882
Pinetime::Drivers::St7789& lcd;
@@ -96,6 +100,7 @@ namespace Pinetime {
96100
Pinetime::Components::LittleVgl lvgl;
97101
Pinetime::Controllers::Timer timer;
98102

103+
AppControllers controllers;
99104
TaskHandle_t taskHandle;
100105

101106
States state = States::Running;

src/displayapp/UserApps.h

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
#include "Apps.h"
3+
#include "Controllers.h"
4+
5+
#include "displayapp/screens/Alarm.h"
6+
#include "displayapp/screens/Timer.h"
7+
#include "displayapp/screens/Twos.h"
8+
#include "displayapp/screens/Tile.h"
9+
#include "displayapp/screens/ApplicationList.h"
10+
#include "displayapp/screens/Clock.h"
11+
12+
namespace Pinetime {
13+
namespace Applications {
14+
namespace Screens {
15+
class Screen;
16+
}
17+
18+
struct AppDescription {
19+
Apps app;
20+
const char* icon;
21+
Screens::Screen* (*create)(AppControllers& controllers);
22+
};
23+
24+
template <Apps t>
25+
consteval AppDescription CreateAppDescription() {
26+
return {AppTraits<t>::app, AppTraits<t>::icon, &AppTraits<t>::Create};
27+
}
28+
29+
template <template<Apps...> typename T, Apps ...ts>
30+
consteval std::array<AppDescription, sizeof...(ts)> CreateAppDescriptions(T<ts...>) {
31+
return {CreateAppDescription<ts>()...};
32+
}
33+
34+
constexpr auto userApps = CreateAppDescriptions(UserAppTypes {});
35+
}
36+
}

src/displayapp/screens/Alarm.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
#include "displayapp/screens/Screen.h"
2020
#include "displayapp/screens/Symbols.h"
2121
#include "displayapp/InfiniTimeTheme.h"
22+
#include "components/settings/Settings.h"
23+
#include "components/alarm/AlarmController.h"
24+
#include "components/motor/MotorController.h"
25+
#include "systemtask/SystemTask.h"
2226

2327
using namespace Pinetime::Applications::Screens;
2428
using Pinetime::Controllers::AlarmController;

src/displayapp/screens/Alarm.h

+18-8
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,22 @@
1717
*/
1818
#pragma once
1919

20+
#include "displayapp/Apps.h"
21+
#include "components/settings/Settings.h"
2022
#include "displayapp/screens/Screen.h"
21-
#include "systemtask/SystemTask.h"
22-
#include "displayapp/LittleVgl.h"
23-
#include "components/alarm/AlarmController.h"
2423
#include "displayapp/widgets/Counter.h"
24+
#include "displayapp/Controllers.h"
25+
#include "Symbols.h"
2526

2627
namespace Pinetime {
2728
namespace Applications {
2829
namespace Screens {
2930
class Alarm : public Screen {
3031
public:
31-
Alarm(Controllers::AlarmController& alarmController,
32-
Controllers::Settings::ClockType clockType,
33-
System::SystemTask& systemTask,
34-
Controllers::MotorController& motorController);
32+
explicit Alarm(Controllers::AlarmController& alarmController,
33+
Controllers::Settings::ClockType clockType,
34+
System::SystemTask& systemTask,
35+
Controllers::MotorController& motorController);
3536
~Alarm() override;
3637
void SetAlerting();
3738
void OnButtonEvent(lv_obj_t* obj, lv_event_t event);
@@ -63,6 +64,15 @@ namespace Pinetime {
6364
Widgets::Counter hourCounter = Widgets::Counter(0, 23, jetbrains_mono_76);
6465
Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_76);
6566
};
67+
}
68+
template<>
69+
struct AppTraits<Apps::Alarm> {
70+
static constexpr Apps app = Apps::Alarm;
71+
static constexpr const char* icon = Screens::Symbols::clock;
72+
static Screens::Screen *Create(AppControllers& controllers) { return new Screens::Alarm(controllers.alarmController,
73+
controllers.settingsController.GetClockType(),
74+
*controllers.systemTask,
75+
controllers.motorController); };
6676
};
67-
};
77+
}
6878
}

0 commit comments

Comments
 (0)