-
Notifications
You must be signed in to change notification settings - Fork 27
Expand file tree
/
Copy pathApplication.h
More file actions
92 lines (79 loc) · 3.01 KB
/
Application.h
File metadata and controls
92 lines (79 loc) · 3.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#pragma once
#include "MatrixOS.h"
#include <functional>
#include <unordered_map>
#include <deque>
#include <cstdarg>
class Application;
struct Application_Info {
string name;
string author;
Color color;
uint32_t version;
bool visibility = true;
bool is_system = false; // System privilege flag
std::function<Application*()> factory = nullptr;
std::function<void(Application*)> destructor = nullptr;
};
class Application {
public:
void Start(const vector<string>& args) {
Setup(args);
while (true)
{
Loop();
taskYIELD();
}
}
void Exit() { // Call this to exit the application
MatrixOS::SYS::ExitAPP();
};
// Override these functions to implement your application
virtual void Setup(const vector<string>& args) {};
virtual void Loop() { Exit(); }; //If the Loop func didn't get overriden, it will just exit. This prevents infinity loop.
virtual void End() {};
virtual ~Application() = default;
};
#define APPID(author, name) StaticHash(author "-" name)
#define APPLICATION_HELPER_CLASS_IMPL(CLASS) CLASS##_HELPER
#define APPLICATION_HELPER_CLASS(CLASS) APPLICATION_HELPER_CLASS_IMPL(CLASS)
// Stores all the applications - Optimal for ID lookup
// Using function-local static to ensure proper initialization order
inline std::unordered_map<uint32_t, Application_Info*>& GetApplications() {
static std::unordered_map<uint32_t, Application_Info*> applications;
return applications;
}
// Store all the application id in order of registration - Preserves order and is optimal for iteration
inline std::map<uint32_t, uint32_t>& GetApplicationIDs() {
static std::map<uint32_t, uint32_t> application_ids;
return application_ids;
}
template <typename APPLICATION_CLASS>
static inline void register_application(uint32_t order, bool is_system) {
APPLICATION_CLASS::info.is_system = is_system; // Set system flag
APPLICATION_CLASS::info.factory = []() -> Application* {
void* mem = pvPortMalloc(sizeof(APPLICATION_CLASS));
if (mem == nullptr) {
return nullptr;
}
return new(mem) APPLICATION_CLASS(); // Placement new
};
APPLICATION_CLASS::info.destructor = [](Application* app) {
if (app != nullptr) {
app->~Application(); // Call destructor
vPortFree(app); // Free memory
}
};
MLOGI("Application", "Registering application: %s%s", APPLICATION_CLASS::info.name.c_str(), is_system ? " (system)" : "");
uint32_t app_id = StringHash(APPLICATION_CLASS::info.author + '-' + APPLICATION_CLASS::info.name);
auto& applications = GetApplications();
if (applications.find(app_id) != applications.end()) {
return;
}
applications.insert({app_id, &APPLICATION_CLASS::info});
GetApplicationIDs()[order] = app_id;
}
#define REGISTER_APPLICATION(APPLICATION_CLASS, IS_SYSTEM) \
__attribute__((__constructor__)) inline void APPLICATION_HELPER_CLASS(APPLICATION_CLASS)(void) { \
register_application<APPLICATION_CLASS>(__COUNTER__, IS_SYSTEM); \
}