-
Notifications
You must be signed in to change notification settings - Fork 133
IController - Persist and Restore #1920
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
8532490
5ca8414
0cf95f8
37975ae
57a56e1
fed1996
5720420
59199cd
e2c6116
4b29d94
dae711a
8a59b72
782b5da
0a5fc2a
a46b4fd
4a99d86
96e446c
237c40a
dfe6b0f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -132,7 +132,7 @@ namespace PluginHost { | |
| class Server { | ||
| public: | ||
| static const TCHAR* ConfigFile; | ||
| static const TCHAR* PluginOverrideFile; | ||
| static const TCHAR* PluginOverrideDirectory; | ||
| static const TCHAR* PluginConfigDirectory; | ||
| static const TCHAR* CommunicatorConnector; | ||
|
|
||
|
|
@@ -1742,18 +1742,19 @@ namespace PluginHost { | |
| }; | ||
|
|
||
| using Callsigns = std::unordered_map<string, Plugin>; | ||
| using PluginOverrideFiles = std::unordered_map<string, string>; // [callsign, filepath] | ||
|
|
||
| public: | ||
| Override(const Override&) = delete; | ||
| Override& operator=(const Override&) = delete; | ||
|
|
||
| Override(PluginHost::Config& serverconfig, ServiceMap& services, const string& persitentFile) | ||
| Override(PluginHost::Config& serverconfig, ServiceMap& services, const string& persitentFolder) | ||
| : Services() | ||
| , Prefix(serverconfig.Prefix()) | ||
| , IdleTime(serverconfig.IdleTime()) | ||
| , _services(services) | ||
| , _serverconfig(serverconfig) | ||
| , _fileName(persitentFile) | ||
| , _pluginOverrideFiles() | ||
| , _callsigns() | ||
| { | ||
| Add(_T("Services"), &Services); | ||
|
|
@@ -1770,6 +1771,10 @@ namespace PluginHost { | |
| std::forward_as_tuple(name), | ||
| std::forward_as_tuple(_T("{}"), "", PluginHost::IShell::startmode::UNAVAILABLE, false)).first); | ||
|
|
||
| // Create individual plugin configuration files | ||
| string filePath = persitentFolder + name + "Override.json"; | ||
| _pluginOverrideFiles[name] = filePath; | ||
nxtum marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| // Store the override config in the JSON String created in the map | ||
| Services.Add(index->first.c_str(), &(index->second)); | ||
| } | ||
|
|
@@ -1785,110 +1790,168 @@ namespace PluginHost { | |
| { | ||
| uint32_t result = Core::ERROR_NONE; | ||
|
|
||
| Core::File storage(_fileName); | ||
| ServiceMap::Iterator indexService(_services.Services()); | ||
| while (indexService.Next() == true) { | ||
| const string currentCallsign = indexService->Callsign(); | ||
|
||
|
|
||
| if ((storage.Exists() == true) && (storage.Open(true) == true)) { | ||
| PluginOverrideFiles::const_iterator indexFile = _pluginOverrideFiles.find(currentCallsign); | ||
| ASSERT(indexFile != _pluginOverrideFiles.end()); | ||
|
|
||
| result = true; | ||
| Callsigns::iterator indexCallsigns(_callsigns.find(currentCallsign)); | ||
| ASSERT(indexCallsigns != _callsigns.end()); | ||
|
|
||
| // Clear all currently set values, they might be from the precious run. | ||
| Clear(); | ||
| Core::File storage(indexFile->second); | ||
| if ((storage.Exists() == true) && (storage.Open(true) == true)) { | ||
|
|
||
| // Red the file and parse it into this object. | ||
| IElement::FromFile(storage); | ||
| result = true; | ||
|
|
||
| _serverconfig.SetPrefix(Prefix.Value()); | ||
| _serverconfig.SetIdleTime(IdleTime.Value()); | ||
| // Convey the real JSON struct information into the specific services. | ||
| ServiceMap::Iterator index(_services.Services()); | ||
| // Clear all currently set values, they might be from the previous run. | ||
| Clear(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this clears the whole object (ie. all services). Not only the element you're trying to load. So it seems to me that after all iterations you'll end up only with the last one loaded. |
||
|
|
||
| while (index.Next() == true) { | ||
| // Read the file and parse it into this object. | ||
| IElement::FromFile(storage); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This requires that the saved JSON has extra level of indirection "servces": { "name": { ... } }. |
||
| _serverconfig.SetPrefix(Prefix.Value()); | ||
| _serverconfig.SetIdleTime(IdleTime.Value()); | ||
|
|
||
| Callsigns::const_iterator current(_callsigns.find(index->Callsign())); | ||
|
|
||
| // ServiceMap should *NOT* change runtime... | ||
| ASSERT(current != _callsigns.end()); | ||
|
|
||
| if (current->second.IsSet() == true) { | ||
| if (current->second.Configuration.IsSet() == true) { | ||
| index->ConfigLine(current->second.Configuration.Value()); | ||
| if (indexCallsigns->second.IsSet() == true) { | ||
| if (indexCallsigns->second.Configuration.IsSet() == true) { | ||
| indexService->ConfigLine(indexCallsigns->second.Configuration.Value()); | ||
| } | ||
| if (current->second.SystemRootPath.IsSet() == true) { | ||
| index->SystemRootPath(current->second.SystemRootPath.Value()); | ||
| if (indexCallsigns->second.SystemRootPath.IsSet() == true) { | ||
| indexService->SystemRootPath(indexCallsigns->second.SystemRootPath.Value()); | ||
| } | ||
| if (current->second.StartMode.IsSet() == true) { | ||
| index->StartMode(current->second.StartMode.Value()); | ||
| if (indexCallsigns->second.StartMode.IsSet() == true) { | ||
| indexService->StartMode(indexCallsigns->second.StartMode.Value()); | ||
| } | ||
| if (current->second.Resumed.IsSet() == true) { | ||
| index->Resumed(current->second.Resumed.Value()); | ||
| if (indexCallsigns->second.Resumed.IsSet() == true) { | ||
| indexService->Resumed(indexCallsigns->second.Resumed.Value()); | ||
| } | ||
| } | ||
| storage.Close(); | ||
| } else { | ||
| result = storage.ErrorCode(); | ||
| } | ||
|
|
||
| storage.Close(); | ||
| } else { | ||
| result = storage.ErrorCode(); | ||
| } | ||
|
|
||
| return (result); | ||
| } | ||
|
|
||
| bool Save() | ||
| bool Save(const Core::OptionalType<string>& callsign) | ||
| { | ||
| uint32_t result = Core::ERROR_NONE; | ||
|
|
||
| auto CreateOverride = [this, &result](ServiceMap::Iterator& indexService) { | ||
| const string currentCallsign = indexService->Callsign(); | ||
|
||
|
|
||
| Core::File storage(_fileName); | ||
| PluginOverrideFiles::const_iterator indexFile = _pluginOverrideFiles.find(currentCallsign); | ||
| ASSERT(indexFile != _pluginOverrideFiles.end()); | ||
|
|
||
| if (storage.Create() == true) { | ||
| Callsigns::iterator indexCallsigns(_callsigns.find(currentCallsign)); | ||
| ASSERT(indexCallsigns != _callsigns.end()); | ||
|
|
||
| // Clear all currently set values, they might be from the precious run. | ||
| Clear(); | ||
| Core::File storage(indexFile->second); | ||
| if (storage.Create() == true) { | ||
|
|
||
| Prefix = _serverconfig.Prefix(); | ||
| IdleTime = _serverconfig.IdleTime(); | ||
| // Clear all currently set values, they might be from the previous run. | ||
| Clear(); | ||
|
|
||
| // Convey the real information from he specific services into the JSON struct. | ||
| ServiceMap::Iterator index(_services.Services()); | ||
| Prefix = _serverconfig.Prefix(); | ||
| IdleTime = _serverconfig.IdleTime(); | ||
|
|
||
| string config(indexService->ConfigLine()); | ||
|
|
||
| if (config.empty() == true) { | ||
| indexCallsigns->second.Configuration = _T("{}"); | ||
| } else { | ||
| indexCallsigns->second.Configuration = config; | ||
| } | ||
| indexCallsigns->second.SystemRootPath = indexService->SystemRootPath(); | ||
| indexCallsigns->second.StartMode = indexService->StartMode(); | ||
| indexCallsigns->second.Resumed = indexService->Resumed(); | ||
|
|
||
| // Persist the currently set information | ||
| IElement::ToFile(storage); | ||
| storage.Close(); | ||
| } else { | ||
| result = storage.ErrorCode(); | ||
| } | ||
| }; | ||
|
|
||
| if (callsign.IsSet() == true) { | ||
| bool found = false; | ||
| const string target = callsign.Value(); | ||
|
|
||
| ServiceMap::Iterator index(_services.Services()); | ||
| while (index.Next() == true) { | ||
| if (index->Callsign() == target) { | ||
| CreateOverride(index); | ||
| found = true; | ||
| break; | ||
| } | ||
| } | ||
| if (found == false) { | ||
| result = Core::ERROR_GENERAL; | ||
| } | ||
| } | ||
| else { // Persist all plugins | ||
| ServiceMap::Iterator index(_services.Services()); | ||
| while (index.Next() == true) { | ||
| CreateOverride(index); | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
| Callsigns::iterator current(_callsigns.find(index->Callsign())); | ||
| bool Destroy(const Core::OptionalType<string>& callsign) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no way to delete the pluginhost config. |
||
| { | ||
| uint32_t result = Core::ERROR_NONE; | ||
|
|
||
| // ServiceMap should *NOT* change runtime... | ||
| ASSERT(current != _callsigns.end()); | ||
| auto DestroyOverride = [this, &result](const string& target) { | ||
|
|
||
| string config(index->ConfigLine()); | ||
| PluginOverrideFiles::const_iterator indexFile = _pluginOverrideFiles.find(target); | ||
| ASSERT(indexFile != _pluginOverrideFiles.end()); | ||
|
|
||
| if (config.empty() == true) { | ||
| current->second.Configuration = _T("{}"); | ||
| } else { | ||
| current->second.Configuration = config; | ||
| Core::File storage(indexFile->second); | ||
|
|
||
| if (storage.Exists() == true) { | ||
| if (storage.Destroy() == false) { | ||
| result = storage.ErrorCode(); | ||
| } | ||
| current->second.SystemRootPath = index->SystemRootPath(); | ||
| current->second.StartMode = index->StartMode(); | ||
| current->second.Resumed = index->Resumed(); | ||
| } | ||
| }; | ||
|
|
||
| if (callsign.IsSet() == true) { | ||
| bool found = false; | ||
| const string target = callsign.Value(); | ||
|
|
||
| // Persist the currently set information | ||
| IElement::ToFile(storage); | ||
|
|
||
| storage.Close(); | ||
| } else { | ||
| result = storage.ErrorCode(); | ||
| ServiceMap::Iterator index(_services.Services()); | ||
| while (index.Next() == true) { | ||
| if (index->Callsign() == target) { | ||
| DestroyOverride(target); | ||
| found = true; | ||
| break; | ||
| } | ||
| } | ||
| if (found == false) { | ||
| result = Core::ERROR_GENERAL; | ||
| } | ||
| } | ||
|
|
||
| return (result); | ||
| else { | ||
| ServiceMap::Iterator index(_services.Services()); | ||
| while (index.Next() == true) { | ||
| DestroyOverride(index->Callsign()); | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
| Core::JSON::Container Services; | ||
|
|
||
| Core::JSON::String Prefix; | ||
| Core::JSON::DecUInt16 IdleTime; | ||
|
|
||
| private: | ||
| ServiceMap& _services; | ||
| PluginHost::Config& _serverconfig; | ||
| string _fileName; | ||
| PluginOverrideFiles _pluginOverrideFiles; | ||
| Callsigns _callsigns; | ||
| }; | ||
|
|
||
|
|
@@ -4741,16 +4804,21 @@ namespace PluginHost { | |
|
|
||
| void StateControlStateChange(const string& callsign, const IStateControl::state state); | ||
|
|
||
| uint32_t Persist() | ||
| uint32_t Persist(const Core::OptionalType<string>& callsign) | ||
| { | ||
| Override infoBlob(_config, _services, Configuration().PersistentPath() + PluginOverrideFile); | ||
| Override infoBlob(_config, _services, Configuration().PersistentPath() + PluginOverrideDirectory); | ||
| return (infoBlob.Save(callsign)); | ||
| } | ||
|
|
||
| return (infoBlob.Save()); | ||
| uint32_t Restore(const Core::OptionalType<string>& callsign) | ||
| { | ||
| Override infoBlob(_config, _services, Configuration().PersistentPath() + PluginOverrideDirectory); | ||
| return (infoBlob.Destroy(callsign)); | ||
| } | ||
|
|
||
| uint32_t Load() | ||
| { | ||
| Override infoBlob(_config, _services, Configuration().PersistentPath() + PluginOverrideFile); | ||
|
|
||
| Override infoBlob(_config, _services, Configuration().PersistentPath() + PluginOverrideDirectory); | ||
|
Comment on lines
+4876
to
+4888
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I find this approach inefficient. Even if we are working with a single callsign we still create the Override object and prepare for handling all plugins (ie. saving callsiings, configs, filenames.... etc). |
||
| return (infoBlob.Load()); | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be good to move the directory now to Thunder/plugins and store the configs there, it is in the same line as the fixed configs are. Maybe you could even swap this line than with the nex line and use the default of the plugins config from there so place this:
on the line "after" the Server::PluginConfigDirectory declaration