-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathcontrollers.h
More file actions
69 lines (51 loc) · 2.85 KB
/
controllers.h
File metadata and controls
69 lines (51 loc) · 2.85 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
/** Description:
This code serves as the core management system for handling physical hardware inputs and integrating external software components (plugins) into the application. It is designed to be highly flexible, allowing the system to easily support different hardware devices like buttons or rotary knobs.
The main purpose of this header is managing dynamic system functionality. It allows the core program to load and use specialized "controller" modules without needing to be recompiled every time a new device is supported.
Two essential functions (`encoderHandler` and `keyHandler`) are defined to standardize input processing. When a physical action occurs (a knob is turned or a button is pressed), these functions capture the event and immediately pass it along to the currently displayed screen, ensuring the user interface responds instantly.
The crucial process, `loadPluginController`, handles system expansion. This function dynamically loads an external plugin file, verifies its integrity, initializes the new controller component with a unique ID, and provides it with the standard input communication channels. This architectural design makes the system highly modular, allowing diverse hardware controllers to be swapped in or out easily while logging any errors transparently.
sha: 4a5d1f7d012799983af1a216dbd1407629ed23178d18c63bedea783a5cda7631
*/
#ifndef _CONTROLLERS_H_
#define _CONTROLLERS_H_
#include "controllerList.h"
#include "host.h"
#include "log.h"
#include "plugins/controllers/controllerInterface.h"
#include "viewManager.h"
#include <dlfcn.h>
ControllerInterface* lastPluginControllerInstance = NULL;
void encoderHandler(int8_t id, int8_t direction, uint32_t tick)
{
ViewManager::get().view->onEncoder(id, direction, tick);
}
void keyHandler(uint16_t id, int key, int8_t state)
{
ViewManager::get().view->onKey(id, key, state);
}
uint16_t controllerId = 1;
ControllerInterface::Props controllerProps = { encoderHandler, keyHandler };
void loadPluginController(char* value, const char* filename)
{
Controller plugin;
strcpy(plugin.name, strtok(value, " "));
char* path = strtok(NULL, " ");
void* handle = dlopen(path, RTLD_LAZY);
if (!handle) {
logError("Cannot open controller library %s [%s]: %s\n", path, filename, dlerror());
return;
}
dlerror();
void* allocator = dlsym(handle, "allocator");
const char* dlsym_error = dlerror();
if (dlsym_error) {
logError("Cannot load symbol: %s\n", dlsym_error);
dlclose(handle);
return;
}
// TODO pass the controller config here...
plugin.instance = ((ControllerInterface * (*)(ControllerInterface::Props & props, uint16_t id)) allocator)(controllerProps, controllerId++);
lastPluginControllerInstance = plugin.instance;
logDebug("plugin interface loaded: %s\n", path);
controllers.push_back(plugin);
}
#endif