Skip to content

Commit 358dbd4

Browse files
author
Pavel Siska
committed
processPluginManager
1 parent 4bfdc8a commit 358dbd4

File tree

1 file changed

+188
-0
lines changed

1 file changed

+188
-0
lines changed
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
#pragma once
2+
3+
#include "fieldManager.hpp"
4+
#include "flowRecord.hpp"
5+
#include "processPlugin.hpp"
6+
#include "processPluginEntry.hpp"
7+
8+
namespace ipxp {
9+
10+
class ProcessPluginManager {
11+
public:
12+
ProcessPluginManager(FieldManager& manager)
13+
: m_fieldManager(manager)
14+
{
15+
}
16+
17+
template<typename... Args>
18+
void addProcessPlugin(const std::string& pluginName, Args&&... args)
19+
{
20+
std::lock_guard<std::mutex> lock(m_mutex);
21+
22+
auto processPlugin
23+
= std::make_shared<IcmpPlugin>(std::forward<Args>(args)..., m_fieldManager);
24+
auto [pluginContextSize, pluginContextAlignment] = processPlugin->getDataMemoryLayout();
25+
const ProcessPluginEntry pluginEntry = {
26+
.name = pluginName,
27+
.contextSize = pluginContextSize,
28+
.contextAlignment = pluginContextAlignment,
29+
.enabled = true,
30+
.plugin = std::move(processPlugin),
31+
};
32+
33+
printPluginEntry(pluginEntry);
34+
35+
m_processPlugins.emplace_back(pluginEntry);
36+
}
37+
38+
void enableProcessPlugin(const std::string& pluginName)
39+
{
40+
std::lock_guard<std::mutex> lock(m_mutex);
41+
42+
for (auto& plugin : m_processPlugins) {
43+
if (plugin.name == pluginName) {
44+
plugin.enabled = true;
45+
std::cout << "Plugin '" << pluginName << "' has been enabled\n";
46+
return;
47+
}
48+
}
49+
std::cout << "Plugin '" << pluginName << "' not found\n";
50+
}
51+
52+
void disableProcessPlugin(const std::string& pluginName)
53+
{
54+
std::lock_guard<std::mutex> lock(m_mutex);
55+
for (auto& plugin : m_processPlugins) {
56+
if (plugin.name == pluginName) {
57+
plugin.enabled = false;
58+
std::cout << "Plugin '" << pluginName << "' has been disabled\n";
59+
return;
60+
}
61+
}
62+
std::cout << "Plugin '" << pluginName << "' not found\n";
63+
}
64+
65+
void processFlowRecord(FlowContext& flowContext)
66+
{
67+
// updateBasicStats
68+
69+
FlowRecord& flowRecord = flowContext.flowRecord;
70+
71+
// Check if any plugin needs to be updated
72+
if (flowRecord.pluginsUpdate.none()) {
73+
return;
74+
}
75+
76+
for (std::size_t pluginID = 0; pluginID < m_processPlugins.size(); pluginID++) {
77+
const auto& pluginEntry = m_processPlugins[pluginID];
78+
// Plugin is not available in FlowRecord
79+
if (!flowRecord.pluginsAvailable.test(pluginID)) {
80+
continue;
81+
}
82+
83+
// Plugin does not want to process packets
84+
if (!flowRecord.pluginsUpdate.test(pluginID)) {
85+
continue;
86+
}
87+
88+
// Plugin not yet constructed, call onInit
89+
if (!flowRecord.pluginsConstructed.test(pluginID)) {
90+
const auto pluginInitResult
91+
= pluginEntry.plugin->onInit(flowContext, flowRecord.getPluginData(pluginID));
92+
93+
// If no update is needed, we can reset the update flag
94+
if (pluginInitResult.updateRequirement == UpdateRequirement::NoUpdateNeeded) {
95+
flowRecord.pluginsUpdate.reset(pluginID);
96+
}
97+
98+
// TODO: je toto valid?
99+
if (pluginInitResult.flowAction == FlowAction::RemovePlugin) {
100+
flowRecord.pluginsAvailable.reset(pluginID);
101+
}
102+
103+
// If the plugin was successfully constructed, we set the constructed bit
104+
if (pluginInitResult.constructionState == ConstructionState::Constructed) {
105+
flowRecord.pluginsConstructed.set(pluginID);
106+
}
107+
108+
continue;
109+
}
110+
111+
// Call onUpdate for constructed plugins
112+
if (flowRecord.pluginsConstructed.test(pluginID)) {
113+
const auto pluginUpdateResult = pluginEntry.plugin->onFlowUpdate(
114+
flowContext,
115+
flowRecord.getPluginData(pluginID));
116+
117+
// If no update is needed, we can reset the update flag
118+
if (pluginUpdateResult.updateRequirement == UpdateRequirement::NoUpdateNeeded) {
119+
flowRecord.pluginsUpdate.reset(pluginID);
120+
}
121+
122+
// If the plugin requested to be removed, we reset the available bit
123+
if (pluginUpdateResult.flowAction == FlowAction::RemovePlugin) {
124+
// call onDestroy
125+
pluginEntry.plugin->onDestroy(flowRecord.getPluginData(pluginID));
126+
127+
flowRecord.pluginsAvailable.reset(pluginID);
128+
flowRecord.pluginsUpdate.reset(pluginID);
129+
flowRecord.pluginsConstructed.reset(pluginID);
130+
} else if (pluginUpdateResult.flowAction == FlowAction::Flush) {
131+
// TODO remove flush
132+
}
133+
}
134+
}
135+
136+
void exportFlowRecord(FlowRecord & flowRecord)
137+
{
138+
for (std::size_t pluginID = 0; pluginID < m_processPlugins.size(); pluginID++) {
139+
const auto& pluginEntry = m_processPlugins[pluginID];
140+
// Check if the plugin is available for the flow
141+
if (!flowRecord.pluginsAvailable.test(pluginID)) {
142+
continue;
143+
}
144+
145+
// Check if the plugin is constructed
146+
if (!flowRecord.pluginsConstructed.test(pluginID)) {
147+
continue;
148+
}
149+
150+
// Call the plugin's onExport method
151+
const auto pluginExportResult
152+
= pluginEntry.plugin->onExport(flowRecord, flowRecord.getPluginData(pluginID));
153+
154+
// Check the export result wants to remove the plugin
155+
if (pluginExportResult.flowAction == FlowAction::RemovePlugin) {
156+
// call onDestroy
157+
pluginEntry.plugin->onDestroy(flowRecord.getPluginData(pluginID));
158+
159+
flowRecord.pluginsAvailable.reset(pluginID);
160+
flowRecord.pluginsConstructed.reset(pluginID);
161+
flowRecord.pluginsUpdate.reset(pluginID);
162+
}
163+
}
164+
}
165+
166+
std::shared_ptr<FlowRecordBuilder> rebuild();
167+
168+
const std::vector<ProcessPluginEntry>& getEntries()
169+
{
170+
return m_processPlugins;
171+
}
172+
173+
private:
174+
void printPluginEntry(const ProcessPluginEntry& entry)
175+
{
176+
std::cout << "Plugin: " << entry.name << "\n";
177+
std::cout << " Context Size: " << entry.contextSize << " bytes\n";
178+
std::cout << " Context Alignment: " << entry.contextAlignment << " bytes\n";
179+
// std::cout << " Enabled: " << std::boolalpha << entry.isEnabled << "\n";
180+
}
181+
182+
std::mutex m_mutex;
183+
std::atomic<std::size_t> m_pluginID = 0;
184+
FieldManager & m_fieldManager;
185+
std::vector<ProcessPluginEntry> m_processPlugins;
186+
};
187+
188+
} // namespace ipxp

0 commit comments

Comments
 (0)