-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathzic.cpp
More file actions
127 lines (101 loc) · 5.03 KB
/
zic.cpp
File metadata and controls
127 lines (101 loc) · 5.03 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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/** Description:
This C++ program serves as the core application engine, managing both background processes and the user interface (UI) display. It is structured using multiple threads, allowing different tasks to run simultaneously.
The program starts in the primary function, where it performs initial setup. This includes defining the visual style (like the color palette), loading necessary backend components (controllers), and reading application settings from a configuration file (typically `config.json`). Importantly, it sets up a special monitoring system to watch the configuration file; if the settings change while the program is running, it can automatically detect and handle the update. It then starts a separate "host" thread for background data management.
The visual component is handled by a dedicated UI thread. This thread initializes the drawing system, determines which screen or "view" should be displayed first (sometimes based on system settings), and renders the initial graphics.
The UI thread then enters a continuous loop, which is the heart of the application's responsiveness. In this loop, it constantly redraws the visible components and, if running on a desktop environment, checks for user events like mouse clicks. This loop ensures the screen is updated smoothly at a regular interval (about 80 milliseconds).
The code is flexible and supports two different rendering modes: one for desktop systems (which handles sophisticated user interaction) and one for embedded systems that draw directly to a screen buffer.
In summary, the program launches background services, initializes the display, and maintains a dedicated thread to continuously draw the interface and manage user interaction until the application is intentionally closed.
sha: 9b4b75cf72c101ad301595b99115aad5e0f96fa184394c49b5b3610033786736
*/
#define ZIC_LOG_LEVEL ZIC_LOG_DEBUG
#include "config.h"
#include "draw/draw.h"
#include "helpers/configWatcher.h"
#include "helpers/getTicks.h"
#include "host.h"
#include "plugins/controllers/PixelController.h"
#include "styles.h"
#include "viewManager.h"
#include <cstdlib>
#include <pthread.h>
bool appRunning = true;
void* uiThread(void* = NULL)
{
ViewManager& viewManager = ViewManager::get();
viewManager.init();
if (getenv("START_VIEW") && getenv("START_VIEW")[0] != '\0') {
logInfo("Env variable starting view: %s", getenv("START_VIEW"));
viewManager.setView(getenv("START_VIEW"));
}
viewManager.draw.fullClear();
if (!viewManager.render()) {
printf("No view were initialized to be rendered.");
return NULL;
}
// int ms = 50;
int ms = 80;
#ifdef DRAW_DESKTOP
logInfo("Rendering on desktop.");
unsigned long lastUpdate = getTicks();
while (viewManager.renderer->handleEvent(viewManager.view) && appRunning) {
unsigned long now = getTicks();
if (now - lastUpdate > ms) {
lastUpdate = now;
viewManager.renderer->preRender(viewManager.view, now);
viewManager.renderComponents(now);
if (viewManager.draw.needRendering()) {
viewManager.renderer->render();
}
}
usleep(1);
}
appRunning = false;
#else
logDebug("Rendering framebuffer.");
int us = ms * 1000;
while (appRunning) {
unsigned long now = getTicks();
viewManager.renderComponents(now);
if (viewManager.draw.needRendering()) {
viewManager.renderer->render();
}
usleep(us);
}
#endif
viewManager.renderer->quit();
return NULL;
}
int main(int argc, char* argv[])
{
loadHostPlugin();
// styles.colors.primary = { 0x3a, 0x7d, 0x80 }; // #3a7d80
// styles.colors.secondary = { 0xff, 0xa0, 0xad }; // #ffa0ad
// styles.colors.tertiary = { 0xa0, 0xb4, 0x97 }; // #A0B497
// styles.colors.quaternary = { 0xe6, 0xc3, 0x4a }; // #e6c34a
styles.colors.primary = { 0x4f, 0xbf, 0xc5 }; // #4fbfc5
styles.colors.secondary = { 0xff, 0x8a, 0x94 }; // #ff8a94
styles.colors.tertiary = { 0xc5, 0xd8, 0xb2 }; // #c5d8b2
styles.colors.quaternary = { 0xf7, 0xda, 0x6d }; // #f7da6d
lastPluginControllerInstance = new PixelController(controllerProps, 0);
controllers.push_back({ "Default", lastPluginControllerInstance });
std::string configFilepath = argc >= 2 ? argv[1] : "config.json";
loadJsonConfig(configFilepath);
pthread_t watcherTid = configWatcher(configFilepath, &appRunning, []() {
ViewManager& viewManager = ViewManager::get();
Point pos = viewManager.renderer->getWindowPosition();
Size size = viewManager.renderer->getWindowSize();
printf("RESTART: %s %d,%d %d,%d\n", viewManager.view->name.c_str(), pos.x, pos.y, size.w, size.h);
fflush(stdout);
});
showLogLevel();
startHostThread();
pthread_t ptid;
pthread_create(&ptid, NULL, &uiThread, NULL);
pthread_setname_np(ptid, "ui");
// wait for uiThread to finish
pthread_join(ptid, NULL);
if (watcherTid != 0) {
pthread_join(watcherTid, NULL);
}
return 0;
}