Skip to content

Commit 98ddd2b

Browse files
committed
Update README
1 parent c86352a commit 98ddd2b

1 file changed

Lines changed: 76 additions & 14 deletions

File tree

‎README.md‎

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -266,35 +266,97 @@ STDC_EXPORT_PLUGIN(EditorPlugin)
266266

267267
Configure every path and setting before `loadPlugins()`. Loading freezes the discovered plugin set, paths, and settings, so later changes have no effect.
268268

269+
A typical application treats the two settings files differently:
270+
271+
- The global file belongs to the application installation. An installer normally provides it. If it is absent or unreadable, the application may create and save its global defaults only when that location is writable. If writing there requires administrator or root privileges, the installer must provide the file.
272+
- The local file belongs to the current user. It normally does not exist on first startup, so an empty `PluginSettings` value is the local default.
273+
- After plugin shutdown, the application saves the local settings for the next run.
274+
269275
```cpp
270276
#include <filesystem>
277+
#include <fstream>
278+
#include <optional>
279+
#include <sstream>
280+
#include <utility>
271281
#include <vector>
272282

273283
#include <stdcorelib/pluginsystem/pluginsettings.h>
274284
#include <stdcorelib/pluginsystem/pluginsystem.h>
285+
#include <stdcorelib/support/json.h>
275286

276287
using namespace stdc::pluginsystem;
277288

278-
PluginSystem plugins("org.example.ApplicationPlugin");
279-
const std::vector<std::filesystem::path> paths{"plugins"};
280-
plugins.setPluginPaths(paths);
289+
std::optional<PluginSettings> readPluginSettings(const std::filesystem::path &path) {
290+
std::ifstream file(path);
291+
if (!file) {
292+
return std::nullopt;
293+
}
281294

282-
PluginSettings globalSettings;
283-
globalSettings.setPluginEnabled("org.example.experimental", true);
284-
plugins.setPluginSettings(PluginSystem::Global, globalSettings);
295+
std::stringstream text;
296+
text << file.rdbuf();
285297

286-
PluginSettings localSettings;
287-
localSettings.setPluginEnabled("org.example.diagnostics", false);
288-
plugins.setPluginSettings(PluginSystem::Local, localSettings);
298+
stdc::json::ParseError parseError;
299+
auto value = stdc::json::Value::fromJson(text.str(), true, &parseError);
300+
if (parseError) {
301+
return std::nullopt;
302+
}
303+
return PluginSettings::fromJson(value);
304+
}
289305

290-
plugins.loadPlugins();
291-
for (const auto spec : plugins.plugins()) {
292-
if (spec->hasError()) {
293-
// Report spec->id() and spec->errorMessage().
306+
bool writePluginSettings(const std::filesystem::path &path,
307+
const PluginSettings &settings) {
308+
std::error_code error;
309+
if (!path.parent_path().empty()) {
310+
std::filesystem::create_directories(path.parent_path(), error);
294311
}
312+
if (error) {
313+
return false;
314+
}
315+
316+
std::ofstream file(path);
317+
file << settings.toJson().toJson(4);
318+
return bool(file);
295319
}
296320

297-
plugins.shutdownPlugins();
321+
int runApplication(const std::filesystem::path &applicationDir,
322+
const std::filesystem::path &userConfigDir) {
323+
const auto globalSettingsPath = applicationDir / "plugin-settings.json";
324+
const auto localSettingsPath = userConfigDir / "plugin-settings.json";
325+
326+
PluginSettings globalSettings;
327+
if (auto stored = readPluginSettings(globalSettingsPath)) {
328+
globalSettings = std::move(*stored);
329+
} else {
330+
globalSettings.setPluginEnabled("org.example.experimental", true);
331+
if (!writePluginSettings(globalSettingsPath, globalSettings)) {
332+
return 1;
333+
}
334+
}
335+
336+
PluginSettings localSettings;
337+
if (auto stored = readPluginSettings(localSettingsPath)) {
338+
localSettings = std::move(*stored);
339+
}
340+
341+
PluginSystem plugins("org.example.ApplicationPlugin");
342+
const std::vector<std::filesystem::path> paths{applicationDir / "plugins"};
343+
plugins.setPluginPaths(paths);
344+
plugins.setPluginSettings(PluginSystem::Global, globalSettings);
345+
plugins.setPluginSettings(PluginSystem::Local, localSettings);
346+
347+
plugins.loadPlugins();
348+
for (const auto spec : plugins.plugins()) {
349+
if (spec->hasError()) {
350+
// Report spec->id() and spec->errorMessage().
351+
}
352+
}
353+
354+
plugins.shutdownPlugins();
355+
if (!writePluginSettings(localSettingsPath, plugins.pluginSettings(PluginSystem::Local))) {
356+
return 1;
357+
}
358+
return 0;
359+
}
298360
```
299361
300362
The lifecycle has the following ordering and ownership rules:

0 commit comments

Comments
 (0)