From d597750398194b5e41c7bf2bb76b9e7778d4cc15 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Thu, 11 May 2017 13:56:06 -0400 Subject: [PATCH] Some more refactoring of the documentation feature --- data/web/properties/main.hbs | 1 - data/web/properties/script.js | 2 +- .../documentation/documentationengine.h | 19 +- .../interaction/interactionhandler.h | 3 +- include/openspace/scene/scene.h | 13 +- include/openspace/scripting/scriptengine.h | 10 +- include/openspace/util/documented.h | 5 +- include/openspace/util/factorymanager.h | 18 +- modules/galaxy/rendering/galaxyraycaster.h | 2 +- .../rendering/kameleonvolumeraycaster.h | 2 +- .../rendering/multiresvolumeraycaster.h | 2 +- .../toyvolume/rendering/toyvolumeraycaster.h | 2 +- openspace.cfg | 31 +- src/documentation/documentationengine.cpp | 259 +++++++++-------- src/engine/configurationmanager_doc.inl | 140 ++------- src/engine/openspaceengine.cpp | 117 ++------ src/interaction/interactionhandler.cpp | 127 --------- src/scene/scene.cpp | 223 +++++---------- src/scripting/scriptengine.cpp | 265 +++--------------- src/util/factorymanager.cpp | 169 +++-------- 20 files changed, 388 insertions(+), 1022 deletions(-) diff --git a/data/web/properties/main.hbs b/data/web/properties/main.hbs index fc56bca0b8..6af37752cd 100644 --- a/data/web/properties/main.hbs +++ b/data/web/properties/main.hbs @@ -18,7 +18,6 @@

OpenSpace Scene Properties

Version: {{version.[0]}}.{{version.[1]}}.{{version.[2]}}

-

Scene name: {{sceneFilename}}

Generated: {{generationTime}}

{{#each propertyOwners}} diff --git a/data/web/properties/script.js b/data/web/properties/script.js index f7302a5e0b..52b8a468fa 100644 --- a/data/web/properties/script.js +++ b/data/web/properties/script.js @@ -53,7 +53,7 @@ window.onload = function () { var data = { propertyOwners: propertyOwners, version: version, - sceneFilename: sceneFilename, + // sceneFilename: sceneFilename, generationTime: generationTime } diff --git a/include/openspace/documentation/documentationengine.h b/include/openspace/documentation/documentationengine.h index 41400602fb..444d164c6a 100644 --- a/include/openspace/documentation/documentationengine.h +++ b/include/openspace/documentation/documentationengine.h @@ -27,6 +27,8 @@ #include +#include + #include #include @@ -38,7 +40,9 @@ namespace documentation { * produced in the application an write them out as a documentation file for human * consumption. */ -class DocumentationEngine : public ghoul::Singleton { +class DocumentationEngine : public ghoul::Singleton + , public Documented +{ public: /** * This exception is thrown by the addDocumentation method if a provided Documentation @@ -57,16 +61,7 @@ public: Documentation documentation; }; - /** - * Write the collected Documentation%s to disk at the \p filename in the specified - * \p type. A new file is created and silently overwritten in the location that - * \p filename is pointed to. - * \param filename The file that is to be created containing all the Documentation - * information. - * \param type The type of documentation that is written. Currently allowed values are - * \c text and \c html - */ - void writeDocumentation(const std::string& filename, const std::string& type); + DocumentationEngine(); /** * Adds the \p documentation to the list of Documentation%s that are written to a @@ -90,6 +85,8 @@ public: static DocumentationEngine& ref(); private: + std::string generateJson() const override; + /// The list of all Documentation%s that are stored by the DocumentationEngine std::vector _documentations; diff --git a/include/openspace/interaction/interactionhandler.h b/include/openspace/interaction/interactionhandler.h index dc68272217..576b9cf01a 100644 --- a/include/openspace/interaction/interactionhandler.h +++ b/include/openspace/interaction/interactionhandler.h @@ -121,7 +121,6 @@ public: void saveCameraStateToFile(const std::string& filepath); void restoreCameraStateFromFile(const std::string& filepath); -// void writeKeyboardDocumentation(const std::string& type, const std::string& file); private: using Synchronized = ghoul::Boolean; @@ -132,7 +131,7 @@ private: std::string documentation; }; - std::string generateJson() const override; + std::string generateJson() const override; void setInteractionMode(std::shared_ptr interactionMode); diff --git a/include/openspace/scene/scene.h b/include/openspace/scene/scene.h index 76f87a3e41..9a1aecbd7d 100644 --- a/include/openspace/scene/scene.h +++ b/include/openspace/scene/scene.h @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -45,7 +46,7 @@ class SceneGraphNode; // Notifications: // SceneGraphFinishedLoading -class Scene { +class Scene : public Documented { public: using UpdateDependencies = ghoul::Boolean; @@ -61,7 +62,6 @@ public: // constructors & destructor Scene(); - ~Scene(); /** * Initalizes the SceneGraph @@ -135,11 +135,6 @@ public: */ const std::map& nodesByName() const; - /** - * Output property documentation to a file. - */ - void writePropertyDocumentation(const std::string& filename, const std::string& type, const std::string& sceneFilename); - /** * Returns the Lua library that contains all Lua functions available to change the * scene graph. The functions contained are @@ -152,7 +147,9 @@ public: static documentation::Documentation Documentation(); -private: +private: + std::string generateJson() const override; + void sortTopologically(); std::unique_ptr _root; diff --git a/include/openspace/scripting/scriptengine.h b/include/openspace/scripting/scriptengine.h index b28a8fb2ba..280b4fa588 100644 --- a/include/openspace/scripting/scriptengine.h +++ b/include/openspace/scripting/scriptengine.h @@ -26,6 +26,7 @@ #define __OPENSPACE_CORE___SCRIPTENGINE___H__ #include +#include #include #include @@ -50,9 +51,12 @@ namespace scripting { * openspace namespac prefix in Lua. The same functions can be exposed to * other Lua states by passing them to the #initializeLuaState method. */ -class ScriptEngine : public Syncable { +class ScriptEngine : public Syncable, public Documented { public: using RemoteScripting = ghoul::Boolean; + + ScriptEngine(); + /** * Initializes the internal Lua state and registers a common set of library functions * \throw LuaRuntimeException If the creation of the new Lua state fails @@ -73,8 +77,6 @@ public: bool runScript(const std::string& script); bool runScriptFile(const std::string& filename); - void writeDocumentation(const std::string& filename, const std::string& type) const; - bool writeLog(const std::string& script); virtual void presync(bool isMaster); @@ -106,6 +108,8 @@ private: void addBaseLibrary(); void remapPrintFunction(); + std::string generateJson() const override; + ghoul::lua::LuaState _state; std::set _registeredLibraries; diff --git a/include/openspace/util/documented.h b/include/openspace/util/documented.h index c6cfd16445..7f9b92a28f 100644 --- a/include/openspace/util/documented.h +++ b/include/openspace/util/documented.h @@ -37,8 +37,11 @@ public: std::string filename; }; - Documented(std::string name, std::string jsonName, std::vector handlebarTemplates, + Documented(std::string name, std::string jsonName, + std::vector handlebarTemplates, std::string javascriptFilename); + + virtual ~Documented() = default; void writeDocumentation(const std::string& filename); diff --git a/include/openspace/util/factorymanager.h b/include/openspace/util/factorymanager.h index 7b815ca065..997976e461 100644 --- a/include/openspace/util/factorymanager.h +++ b/include/openspace/util/factorymanager.h @@ -25,6 +25,8 @@ #ifndef __OPENSPACE_CORE___FACTORYMANAGER___H__ #define __OPENSPACE_CORE___FACTORYMANAGER___H__ +#include + #include #include @@ -37,7 +39,7 @@ namespace openspace { * them available through the #addFactory and #factory methods. Each * ghoul::TemplateFactory can only be added once and can be accessed by its type. */ -class FactoryManager { +class FactoryManager : public Documented { public: /// This exception is thrown if the ghoul::TemplateFactory could not be found in the /// #factory method @@ -55,6 +57,8 @@ public: /// The type describing the ghoul::TemplateFactory that could not be found std::string type; }; + + FactoryManager(); /** * Static initializer that initializes the static member. This needs to be done before @@ -104,17 +108,9 @@ public: template ghoul::TemplateFactory* factory() const; - /** - * Writes a documentation for the FactoryMananger that contains all of the registered - * factories and for each factory all registered class names. - * \param file The file to which the documentation will be written - * \param type The type of documentation that will be written - * \pre \p file must not be empty - * \pre \p type must not be empty - */ - void writeDocumentation(const std::string& file, const std::string& type); - private: + std::string generateJson() const override; + /// Singleton member for the Factory Manager static FactoryManager* _manager; diff --git a/modules/galaxy/rendering/galaxyraycaster.h b/modules/galaxy/rendering/galaxyraycaster.h index dcd34063e6..b65e08eff6 100644 --- a/modules/galaxy/rendering/galaxyraycaster.h +++ b/modules/galaxy/rendering/galaxyraycaster.h @@ -44,7 +44,7 @@ namespace ghoul { namespace openspace { -class RenderData; +struct RenderData; class RaycastData; class GalaxyRaycaster : public VolumeRaycaster { diff --git a/modules/kameleonvolume/rendering/kameleonvolumeraycaster.h b/modules/kameleonvolume/rendering/kameleonvolumeraycaster.h index 95f4ecb656..d45590d2a7 100644 --- a/modules/kameleonvolume/rendering/kameleonvolumeraycaster.h +++ b/modules/kameleonvolume/rendering/kameleonvolumeraycaster.h @@ -49,7 +49,7 @@ namespace ghoul { namespace openspace { -class RenderData; +struct RenderData; class RaycastData; class KameleonVolumeRaycaster : public VolumeRaycaster { diff --git a/modules/multiresvolume/rendering/multiresvolumeraycaster.h b/modules/multiresvolume/rendering/multiresvolumeraycaster.h index c08a75e0c4..3c598ffd84 100644 --- a/modules/multiresvolume/rendering/multiresvolumeraycaster.h +++ b/modules/multiresvolume/rendering/multiresvolumeraycaster.h @@ -48,7 +48,7 @@ namespace ghoul { namespace openspace { -class RenderData; +struct RenderData; class RaycastData; class MultiresVolumeRaycaster : public VolumeRaycaster { diff --git a/modules/toyvolume/rendering/toyvolumeraycaster.h b/modules/toyvolume/rendering/toyvolumeraycaster.h index 08569987bf..1577ede5ec 100644 --- a/modules/toyvolume/rendering/toyvolumeraycaster.h +++ b/modules/toyvolume/rendering/toyvolumeraycaster.h @@ -41,7 +41,7 @@ namespace ghoul { namespace openspace { -class RenderData; +struct RenderData; class RaycastData; class ToyVolumeRaycaster : public VolumeRaycaster { diff --git a/openspace.cfg b/openspace.cfg index be9164e8aa..5bba443950 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -62,30 +62,13 @@ return { }, CapabilitiesVerbosity = "Full" }, - LuaDocumentation = { - Type = "html", - File = "${DOCUMENTATION}/LuaScripting.html" - }, - PropertyDocumentation = { - Type = "html", - File = "${DOCUMENTATION}/Properties.html" - }, - ScriptLog = { - Type = "text", - File = "${BASE_PATH}/ScriptLog.txt" - }, - KeyboardShortcuts = { - Type = "html", - File = "${DOCUMENTATION}/KeyboardMapping.html" - }, - Documentation = { - Type = "html", - File = "${DOCUMENTATION}/Documentation.html" - }, - FactoryDocumentation = { - Type = "html", - File = "${DOCUMENTATION}/FactoryDocumentation.html" - }, + LuaDocumentation = "${DOCUMENTATION}/LuaScripting.html", + PropertyDocumentation = "${DOCUMENTATION}/Properties.html", + ScriptLog = "${BASE_PATH}/ScriptLog.txt", + KeyboardShortcuts = "${DOCUMENTATION}/KeyboardMapping.html", + Documentation = "${DOCUMENTATION}/Documentation.html", + FactoryDocumentation = "${DOCUMENTATION}/FactoryDocumentation.html", + ShutdownCountdown = 3, -- OnScreenTextScaling = "framebuffer", -- PerSceneCache = true, diff --git a/src/documentation/documentationengine.cpp b/src/documentation/documentationengine.cpp index 2f48183dd1..7dc5b11c0b 100644 --- a/src/documentation/documentationengine.cpp +++ b/src/documentation/documentationengine.cpp @@ -61,6 +61,19 @@ DocumentationEngine::DuplicateDocumentationException::DuplicateDocumentationExce , documentation(std::move(documentation)) {} +DocumentationEngine::DocumentationEngine() + : Documented( + "Documentation", + "documentation", + { + { "mainTemplate", MainTemplateFilename }, + { "documentationTemplate", DocumentationTemplateFilename } + }, + JsFilename + ) +{} + + DocumentationEngine& DocumentationEngine::ref() { if (_instance == nullptr) { _instance = new DocumentationEngine; @@ -256,126 +269,152 @@ std::string generateHtmlDocumentation(const Documentation& d) { return html.str(); } -void DocumentationEngine::writeDocumentation(const std::string& f, const std::string& t) { - if (t == "text") { - std::ofstream file; - file.exceptions(~std::ofstream::goodbit); - file.open(f); +std::string DocumentationEngine::generateJson() const { + std::stringstream json; + json << "["; - for (const Documentation& d : _documentations) { - int indent = 0; - file << documentation::generateTextDocumentation(d, indent) << "\n\n"; + for (const Documentation& d : _documentations) { + json << generateJsonDocumentation(d); + if (&d != &_documentations.back()) { + json << ", "; } } - else if (t == "html") { - std::ifstream handlebarsInput(absPath(HandlebarsFilename)); - std::ifstream jsInput(absPath(JsFilename)); - std::string jsContent; - std::back_insert_iterator jsInserter(jsContent); + json << "]"; - std::copy(std::istreambuf_iterator{handlebarsInput}, std::istreambuf_iterator(), jsInserter); - std::copy(std::istreambuf_iterator{jsInput}, std::istreambuf_iterator(), jsInserter); - - std::ifstream bootstrapInput(absPath(BootstrapFilename)); - std::ifstream cssInput(absPath(CssFilename)); - - std::string cssContent; - std::back_insert_iterator cssInserter(cssContent); - - std::copy(std::istreambuf_iterator{bootstrapInput}, std::istreambuf_iterator(), cssInserter); - std::copy(std::istreambuf_iterator{cssInput}, std::istreambuf_iterator(), cssInserter); - - std::ifstream mainTemplateInput(absPath(MainTemplateFilename)); - std::string mainTemplateContent{ std::istreambuf_iterator{mainTemplateInput}, - std::istreambuf_iterator{}}; - - std::ifstream documentationTemplateInput(absPath(DocumentationTemplateFilename)); - std::string documentationTemplateContent{ std::istreambuf_iterator{documentationTemplateInput}, - std::istreambuf_iterator{} }; - - std::ofstream file; - file.exceptions(~std::ofstream::goodbit); - file.open(f); - - std::stringstream json; - json << "["; - - for (const Documentation& d : _documentations) { - json << generateJsonDocumentation(d); - if (&d != &_documentations.back()) { - json << ", "; - } + std::string jsonString = ""; + for (const char& c : json.str()) { + if (c == '\'') { + jsonString += "\\'"; } - - json << "]"; - - std::string jsonString = ""; - for (const char& c : json.str()) { - if (c == '\'') { - jsonString += "\\'"; - } else { - jsonString += c; - } + else { + jsonString += c; } - - std::stringstream html; - html << "\n" - << "\n" - << "\t\n" - << "\t\t\n" - << "\t\t\n" - << "\t\n" - << "\t\n" - << "\t\tDocumentation\n" - << "\t\n" - << "\t\n" - << "\t\n" - << "\n"; - - file << html.str(); - -/* - Use this for generating documentation in raw html: - - html << "\n" - << "\t\n\n" - << "\t\n" - << "\t\t\n" - << "\t\t\t\n" - << "\t\t\n" - << "\t\t\n" - << "\t\t\t\n" - << "\t\t\t\n" - << "\t\t\t\n" - << "\t\t\t\n" - << "\t\t\t\n" - << "\t\t\n" - << "\t\n" - << "\t\n"; - - for (const Documentation& d : _documentations) { - html << generateHtmlDocumentation(d); - - html << "\t\n"; - } - - html << "\t\n" - << "
Documentation
Name
KeyOptionalTypeRestrictionsDocumentation

\n"; -*/ } + + return jsonString; } +//void DocumentationEngine::writeDocumentation(const std::string& f, const std::string& t) { +// if (t == "text") { +// std::ofstream file; +// file.exceptions(~std::ofstream::goodbit); +// file.open(f); +// +// for (const Documentation& d : _documentations) { +// int indent = 0; +// file << documentation::generateTextDocumentation(d, indent) << "\n\n"; +// } +// } +// else if (t == "html") { +// std::ifstream handlebarsInput(absPath(HandlebarsFilename)); +// std::ifstream jsInput(absPath(JsFilename)); +// +// std::string jsContent; +// std::back_insert_iterator jsInserter(jsContent); +// +// std::copy(std::istreambuf_iterator{handlebarsInput}, std::istreambuf_iterator(), jsInserter); +// std::copy(std::istreambuf_iterator{jsInput}, std::istreambuf_iterator(), jsInserter); +// +// std::ifstream bootstrapInput(absPath(BootstrapFilename)); +// std::ifstream cssInput(absPath(CssFilename)); +// +// std::string cssContent; +// std::back_insert_iterator cssInserter(cssContent); +// +// std::copy(std::istreambuf_iterator{bootstrapInput}, std::istreambuf_iterator(), cssInserter); +// std::copy(std::istreambuf_iterator{cssInput}, std::istreambuf_iterator(), cssInserter); +// +// std::ifstream mainTemplateInput(absPath(MainTemplateFilename)); +// std::string mainTemplateContent{ std::istreambuf_iterator{mainTemplateInput}, +// std::istreambuf_iterator{}}; +// +// std::ifstream documentationTemplateInput(absPath(DocumentationTemplateFilename)); +// std::string documentationTemplateContent{ std::istreambuf_iterator{documentationTemplateInput}, +// std::istreambuf_iterator{} }; +// +// std::ofstream file; +// file.exceptions(~std::ofstream::goodbit); +// file.open(f); +// +// std::stringstream json; +// json << "["; +// +// for (const Documentation& d : _documentations) { +// json << generateJsonDocumentation(d); +// if (&d != &_documentations.back()) { +// json << ", "; +// } +// } +// +// json << "]"; +// +// std::string jsonString = ""; +// for (const char& c : json.str()) { +// if (c == '\'') { +// jsonString += "\\'"; +// } else { +// jsonString += c; +// } +// } +// +// std::stringstream html; +// html << "\n" +// << "\n" +// << "\t\n" +// << "\t\t\n" +// << "\t\t\n" +// << "\t\n" +// << "\t\n" +// << "\t\tDocumentation\n" +// << "\t\n" +// << "\t\n" +// << "\t\n" +// << "\n"; +// +// file << html.str(); +// +///* +// Use this for generating documentation in raw html: +// +// html << "\n" +// << "\t\n\n" +// << "\t\n" +// << "\t\t\n" +// << "\t\t\t\n" +// << "\t\t\n" +// << "\t\t\n" +// << "\t\t\t\n" +// << "\t\t\t\n" +// << "\t\t\t\n" +// << "\t\t\t\n" +// << "\t\t\t\n" +// << "\t\t\n" +// << "\t\n" +// << "\t\n"; +// +// for (const Documentation& d : _documentations) { +// html << generateHtmlDocumentation(d); +// +// html << "\t\n"; +// } +// +// html << "\t\n" +// << "
Documentation
Name
KeyOptionalTypeRestrictionsDocumentation

\n"; +//*/ +// } +//} + void DocumentationEngine::addDocumentation(Documentation doc) { for (const DocumentationEntry& e : doc.entries) { ghoul_assert( diff --git a/src/engine/configurationmanager_doc.inl b/src/engine/configurationmanager_doc.inl index a00228b045..e47a9d9c39 100644 --- a/src/engine/configurationmanager_doc.inl +++ b/src/engine/configurationmanager_doc.inl @@ -141,143 +141,49 @@ documentation::Documentation ConfigurationManager::Documentation() { }, { ConfigurationManager::KeyLuaDocumentation, - new TableVerifier({ - { - ConfigurationManager::PartType, - new StringInListVerifier( - // List from ScriptEngine::writeDocumentation - { "text", "html" } - ), - "The type of documentation that will be written." - }, - { - ConfigurationManager::PartFile, - new StringVerifier, - "The filename that will be created on startup containing the " - "documentation of available Lua functions. Any existing file " - "will be silently overwritten." - } - }), - "Descriptions of whether and where to create a documentation file that " - "describes the available Lua functions that can be executed in scene " - "files or per console.", + new StringVerifier, + "The filename that will be created on startup containing the documentation " + "of available Lua functions that can be executed in scene files or per " + "console. Any existing file will be silently overwritten.", Optional::Yes }, { ConfigurationManager::KeyPropertyDocumentation, - new TableVerifier({ - { - ConfigurationManager::PartType, - new StringInListVerifier( - // List taken from Scene::writePropertyDocumentation - { "text", "html" } - ), - "The type of property documentation file that is created." - }, - { - ConfigurationManager::PartFile, - new StringVerifier, - "The file that will be created on startup containing a list of " - "all properties in the scene. Any existing file will be silently " - "overwritten." - } - }), - "Descriptions of whether and where to create a list of all properties " - "that were created in the current scene.", + new StringVerifier, + "The file that will be created on startup containing a list of all " + "properties in the scene. Any existing file will be silently overwritten.", Optional::Yes }, { ConfigurationManager::KeyScriptLog, - new TableVerifier({ - { - ConfigurationManager::PartType, - new StringInListVerifier( - // List taken from ScriptEngine::writeLog - { "text" } - ), - "The type of logfile that will be created." - }, - { - ConfigurationManager::PartFile, - new StringVerifier, - "The file that will be created on startup containing the log of " - "all Lua scripts that are executed. Any existing file (including " - "the results from previous runs) will be silently overwritten." - } - }), - "Contains a log of all Lua scripts that were executed in the last " - "session.", + new StringVerifier, + "The file that will be created on startup containing the log of all Lua " + "scripts that are executed in the last session. Any existing file (including " + "the results from previous runs) will be silently overwritten.", Optional::Yes }, { ConfigurationManager::KeyKeyboardShortcuts, - new TableVerifier({ - { - ConfigurationManager::PartType, - new StringInListVerifier( - // List from InteractionHandler::writeKeyboardDocumentation - { "text", "html" } - ), - "The type of keyboard binding documentation that should be " - "written." - }, - { - ConfigurationManager::PartFile, - new StringVerifier, - "The file that will be created on startup containing the list of " - "all keyboard bindings with their respective Lua scripts. Any " - "previous file in this location will be silently overritten." - } - }), - "Contains the collection of all keyboard shortcuts that were collected " - "during startup. For each key, it mentions which scripts will be " - "executed in the current session.", + new StringVerifier, + "The file that will be created on startup containing the list of all " + "keyboard bindings with their respective Lua scripts. For each key, it " + "mentions which scripts will be executed in the current session.", Optional::Yes }, { ConfigurationManager::KeyDocumentation, - new TableVerifier({ - { - ConfigurationManager::PartType, - new StringInListVerifier( - // List from DocumentationEngine::writeDocumentation - { "text", "html" } - ), - "The type of documentation that should be written." - }, - { - ConfigurationManager::PartFile, - new StringVerifier, - "The file that will be created on startup containing this " - "documentation. Any previous file in this location will be silently " - "overritten." - } - }), - "This defines the location and type of this documentation file.", + new StringVerifier, + "The file that will be created on startup containing this documentation. Any " + "previous file in this location will be silently overwritten.", Optional::Yes }, { ConfigurationManager::KeyFactoryDocumentation, - new TableVerifier({ - { - ConfigurationManager::PartType, - new StringInListVerifier( - // List from FactoryManager::writeDocumentation - { "text", "html" } - ), - "The type of documentation that should be written." - }, - { - ConfigurationManager::PartFile, - new StringVerifier, - "The file that will be created on startup containing the factory " - "documentation. Any previous file in this location will be silently " - "overritten." - } - }), - "This defines the location and type of the factory documentation file, which " - "shows the different types of objects that can be created in the current " - "application configuration.", + new StringVerifier, + "The file that will be created on startup containing the factory " + "documentation which shows the different types of objects that can be " + "created in the current application configuration. Any previous file in this " + "location will be silently overritten.", Optional::Yes }, { diff --git a/src/engine/openspaceengine.cpp b/src/engine/openspaceengine.cpp index d2bdea1456..9a96c49899 100644 --- a/src/engine/openspaceengine.cpp +++ b/src/engine/openspaceengine.cpp @@ -589,44 +589,21 @@ void OpenSpaceEngine::loadScene(const std::string& scenePath) { } // Write keyboard documentation. - { - const std::string KeyboardShortcutsType = - ConfigurationManager::KeyKeyboardShortcuts + "." + - ConfigurationManager::PartType; - - const std::string KeyboardShortcutsFile = - ConfigurationManager::KeyKeyboardShortcuts + "." + - ConfigurationManager::PartFile; - - std::string type, file; - const bool hasType = configurationManager().getValue(KeyboardShortcutsType, type); - const bool hasFile = configurationManager().getValue(KeyboardShortcutsFile, file); - - if (hasType && hasFile) { - file = absPath(file); - interactionHandler().writeDocumentation(file); -// interactionHandler().writeKeyboardDocumentation(type, file); - } + if (configurationManager().hasKey(ConfigurationManager::KeyKeyboardShortcuts)) { + interactionHandler().writeDocumentation( + absPath(configurationManager().value( + ConfigurationManager::KeyKeyboardShortcuts + )) + ); } // If a PropertyDocumentationFile was specified, generate it now. - { - const std::string KeyPropertyDocumentationType = - ConfigurationManager::KeyPropertyDocumentation + '.' + - ConfigurationManager::PartType; - - const std::string KeyPropertyDocumentationFile = - ConfigurationManager::KeyPropertyDocumentation + '.' + - ConfigurationManager::PartFile; - - std::string type, file; - const bool hasType = configurationManager().getValue(KeyPropertyDocumentationType, type); - const bool hasFile = configurationManager().getValue(KeyPropertyDocumentationFile, file); - - if (hasType && hasFile) { - file = absPath(file); - scene->writePropertyDocumentation(file, type, scenePath); - } + if (configurationManager().hasKey(ConfigurationManager::KeyPropertyDocumentation)) { + scene->writeDocumentation( + absPath(configurationManager().value( + ConfigurationManager::KeyPropertyDocumentation + )) + ); } _syncEngine->addSyncables(Time::ref().getSyncables()); @@ -647,72 +624,30 @@ void OpenSpaceEngine::deinitialize() { void OpenSpaceEngine::writeDocumentation() { // If a LuaDocumentationFile was specified, generate it now - const std::string LuaDocumentationType = - ConfigurationManager::KeyLuaDocumentation + "." + ConfigurationManager::PartType; - const std::string LuaDocumentationFile = - ConfigurationManager::KeyLuaDocumentation + "." + ConfigurationManager::PartFile; - - const bool hasLuaDocType = configurationManager().hasKey(LuaDocumentationType); - const bool hasLuaDocFile = configurationManager().hasKey(LuaDocumentationFile); - if (hasLuaDocType && hasLuaDocFile) { - std::string luaDocumentationType = configurationManager().value( - LuaDocumentationType - ); - std::string luaDocumentationFile = configurationManager().value( - LuaDocumentationFile - ); - + if (configurationManager().hasKey(ConfigurationManager::KeyLuaDocumentation)) { _scriptEngine->writeDocumentation( - absPath(luaDocumentationFile), - luaDocumentationType + absPath(configurationManager().value( + ConfigurationManager::KeyLuaDocumentation + )) ); } // If a general documentation was specified, generate it now - const std::string DocumentationType = - ConfigurationManager::KeyDocumentation + '.' + ConfigurationManager::PartType; - const std::string DocumentationFile = - ConfigurationManager::KeyDocumentation + '.' + ConfigurationManager::PartFile; - - const bool hasDocumentationType = configurationManager().hasKey(DocumentationType); - const bool hasDocumentationFile = configurationManager().hasKey(DocumentationFile); - if (hasDocumentationType && hasDocumentationFile) { - std::string documentationType = configurationManager().value( - DocumentationType - ); - std::string documentationFile = configurationManager().value( - DocumentationFile - ); - + if (configurationManager().hasKey(ConfigurationManager::KeyDocumentation)) { DocEng.writeDocumentation( - absPath(documentationFile), - documentationType + absPath(configurationManager().value( + ConfigurationManager::KeyDocumentation + )) ); } - const std::string FactoryDocumentationType = - ConfigurationManager::KeyFactoryDocumentation + '.' + - ConfigurationManager::PartType; - - const std::string FactoryDocumentationFile = - ConfigurationManager::KeyFactoryDocumentation + '.' + - ConfigurationManager::PartFile; - - bool hasFactoryDocumentationType = configurationManager().hasKey( - FactoryDocumentationType - ); - bool hasFactoryDocumentationFile = configurationManager().hasKey( - FactoryDocumentationFile - ); - if (hasFactoryDocumentationType && hasFactoryDocumentationFile) { - std::string type = configurationManager().value( - FactoryDocumentationType + // If a factory documentation was specified, generate it now + if (configurationManager().hasKey(ConfigurationManager::KeyFactoryDocumentation)) { + FactoryManager::ref().writeDocumentation( + absPath(configurationManager().value( + ConfigurationManager::KeyFactoryDocumentation + )) ); - std::string file = configurationManager().value( - FactoryDocumentationFile - ); - - FactoryManager::ref().writeDocumentation(absPath(file), type); } } diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index e87dabb564..1a55b2eca9 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -472,133 +472,6 @@ std::string InteractionHandler::generateJson() const { return jsonString; } -//void InteractionHandler::writeKeyboardDocumentation(const std::string& type, -// const std::string& file) -//{ -// if (type == "text") { -// std::ofstream f; -// f.exceptions(~std::ofstream::goodbit); -// f.open(absPath(file)); -// -// for (const auto& p : _keyLua) { -// std::string remoteScriptingInfo; -// bool remoteScripting = p.second.synchronization; -// -// if (!remoteScripting) { -// remoteScriptingInfo = " (LOCAL)"; -// } -// f << std::to_string(p.first) << ": " -// << p.second.command << remoteScriptingInfo << '\n' -// << p.second.documentation << '\n'; -// } -// } -// else if (type == "html") { -// std::ofstream f; -// f.exceptions(~std::ofstream::goodbit); -// f.open(absPath(file)); -// -// std::ifstream handlebarsInput(absPath(HandlebarsFilename)); -// std::ifstream jsInput(absPath(JsFilename)); -// -// std::string jsContent; -// std::back_insert_iterator jsInserter(jsContent); -// -// std::copy(std::istreambuf_iterator{handlebarsInput}, std::istreambuf_iterator(), jsInserter); -// std::copy(std::istreambuf_iterator{jsInput}, std::istreambuf_iterator(), jsInserter); -// -// std::ifstream bootstrapInput(absPath(BootstrapFilename)); -// std::ifstream cssInput(absPath(CssFilename)); -// -// std::string cssContent; -// std::back_insert_iterator cssInserter(cssContent); -// -// std::copy(std::istreambuf_iterator{bootstrapInput}, std::istreambuf_iterator(), cssInserter); -// std::copy(std::istreambuf_iterator{cssInput}, std::istreambuf_iterator(), cssInserter); -// -// std::ifstream mainTemplateInput(absPath(MainTemplateFilename)); -// std::string mainTemplateContent{ std::istreambuf_iterator{mainTemplateInput}, -// std::istreambuf_iterator{} }; -// -// std::ifstream keybindingTemplateInput(absPath(KeybindingTemplateFilename)); -// std::string keybindingTemplateContent{ std::istreambuf_iterator{keybindingTemplateInput}, -// std::istreambuf_iterator{} }; -// -// std::stringstream json; -// json << "["; -// bool first = true; -// for (const auto& p : _keyLua) { -// if (!first) { -// json << ","; -// } -// first = false; -// json << "{"; -// json << "\"key\": \"" << std::to_string(p.first) << "\","; -// json << "\"script\": \"" << p.second.command << "\","; -// json << "\"remoteScripting\": " << (p.second.synchronization ? "true," : "false,"); -// json << "\"documentation\": \"" << p.second.documentation << "\""; -// json << "}"; -// } -// json << "]"; -// -// std::string jsonString = ""; -// for (const char& c : json.str()) { -// if (c == '\'') { -// jsonString += "\\'"; -// } else { -// jsonString += c; -// } -// } -// -// std::string generationTime; -// try { -// generationTime = Time::now().ISO8601(); -// } -// catch (...) {} -// -// std::stringstream html; -// html << "\n" -// << "\n" -// << "\t\n" -// << "\t\t\n" -// << "\t\t\n" -// << "\t\n" -// << "\t\n" -// << "\t\tDocumentation\n" -// << "\t\n" -// << "\t\n" -// << "\t\n" -// << "\n"; -// -// f << html.str(); -// -// -// /* -// for (const auto& p : _keyLua) { -// html << "\t\t\n" -// << "\t\t\t" << std::to_string(p.first) << "\n" -// << "\t\t\t" << p.second.first << "\n" -// << "\t\t\t" << (p.second.second ? "Yes" : "No") << "\n" -// << "\t\t\n"; -// }*/ -// } -// else { -// throw ghoul::RuntimeError( -// "Unsupported keyboard documentation type '" + type + "'", -// "InteractionHandler" -// ); -// } -//} scripting::LuaLibrary InteractionHandler::luaLibrary() { return{ diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index 4778aee872..6799f75717 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -82,9 +82,18 @@ namespace { namespace openspace { -Scene::Scene() {} - -Scene::~Scene() {} +Scene::Scene() + : Documented( + "Documented", + "propertyOwners", + { + { "mainTemplate", MainTemplateFilename }, + { "propertyOwnerTemplate", PropertyOwnerTemplateFilename }, + { "propertyTemplate", PropertyTemplateFilename } + }, + JsFilename + ) +{} void Scene::setRoot(std::unique_ptr root) { if (_root) { @@ -266,165 +275,71 @@ const std::vector& Scene::allSceneGraphNodes() const { return _topologicallySortedNodes; } -void Scene::writePropertyDocumentation(const std::string& filename, const std::string& type, const std::string& sceneFilename) { - LDEBUG("Writing documentation for properties"); - if (type == "text") { - std::ofstream file; - file.exceptions(~std::ofstream::goodbit); - file.open(filename); - - using properties::Property; - for (SceneGraphNode* node : allSceneGraphNodes()) { - std::vector properties = node->propertiesRecursive(); - if (!properties.empty()) { - file << node->name() << std::endl; - - for (Property* p : properties) { - file << p->fullyQualifiedIdentifier() << ": " << - p->guiName() << std::endl; - } - - file << std::endl; - } - } - } - else if (type == "html") { - std::ofstream file; - file.exceptions(~std::ofstream::goodbit); - file.open(filename); - - - std::ifstream handlebarsInput(absPath(HandlebarsFilename)); - std::ifstream jsInput(absPath(JsFilename)); - - std::string jsContent; - std::back_insert_iterator jsInserter(jsContent); - - std::copy(std::istreambuf_iterator{handlebarsInput}, std::istreambuf_iterator(), jsInserter); - std::copy(std::istreambuf_iterator{jsInput}, std::istreambuf_iterator(), jsInserter); - - std::ifstream bootstrapInput(absPath(BootstrapFilename)); - std::ifstream cssInput(absPath(CssFilename)); - - std::string cssContent; - std::back_insert_iterator cssInserter(cssContent); - - std::copy(std::istreambuf_iterator{bootstrapInput}, std::istreambuf_iterator(), cssInserter); - std::copy(std::istreambuf_iterator{cssInput}, std::istreambuf_iterator(), cssInserter); - - std::ifstream mainTemplateInput(absPath(MainTemplateFilename)); - std::string mainTemplateContent{ std::istreambuf_iterator{mainTemplateInput}, - std::istreambuf_iterator{} }; - - std::ifstream propertyOwnerTemplateInput(absPath(PropertyOwnerTemplateFilename)); - std::string propertyOwnerTemplateContent{ std::istreambuf_iterator{propertyOwnerTemplateInput}, - std::istreambuf_iterator{} }; - - std::ifstream propertyTemplateInput(absPath(PropertyTemplateFilename)); - std::string propertyTemplateContent{ std::istreambuf_iterator{propertyTemplateInput}, - std::istreambuf_iterator{} }; - - // Create JSON - std::function createJson = - [&createJson](properties::PropertyOwner* owner) -> std::string - { - std::stringstream json; - json << "{"; - json << "\"name\": \"" << owner->name() << "\","; - - json << "\"properties\": ["; - auto properties = owner->properties(); - for (properties::Property* p : properties) { - json << "{"; - json << "\"id\": \"" << p->identifier() << "\","; - json << "\"type\": \"" << p->className() << "\","; - json << "\"fullyQualifiedId\": \"" << p->fullyQualifiedIdentifier() << "\","; - json << "\"guiName\": \"" << p->guiName() << "\""; - json << "}"; - if (p != properties.back()) { - json << ","; - } - } - json << "],"; - - json << "\"propertyOwners\": ["; - auto propertyOwners = owner->propertySubOwners(); - for (properties::PropertyOwner* o : propertyOwners) { - json << createJson(o); - if (o != propertyOwners.back()) { - json << ","; - } - } - json << "]"; - json << "}"; - - return json.str(); - }; - - +std::string Scene::generateJson() const { + std::function createJson = + [&createJson](properties::PropertyOwner* owner) -> std::string + { std::stringstream json; - json << "["; - std::vector nodes = allSceneGraphNodes(); - if (!nodes.empty()) { - json << std::accumulate( - std::next(nodes.begin()), - nodes.end(), - createJson(*nodes.begin()), - [createJson](std::string a, SceneGraphNode* n) { - return a + "," + createJson(n); - } - ); - } + json << "{"; + json << "\"name\": \"" << owner->name() << "\","; - json << "]"; - - std::string jsonString = ""; - for (const char& c : json.str()) { - if (c == '\'') { - jsonString += "\\'"; - } else { - jsonString += c; + json << "\"properties\": ["; + auto properties = owner->properties(); + for (properties::Property* p : properties) { + json << "{"; + json << "\"id\": \"" << p->identifier() << "\","; + json << "\"type\": \"" << p->className() << "\","; + json << "\"fullyQualifiedId\": \"" << p->fullyQualifiedIdentifier() << "\","; + json << "\"guiName\": \"" << p->guiName() << "\""; + json << "}"; + if (p != properties.back()) { + json << ","; } } + json << "],"; - std::string generationTime; - try { - generationTime = Time::now().ISO8601(); + json << "\"propertyOwners\": ["; + auto propertyOwners = owner->propertySubOwners(); + for (properties::PropertyOwner* o : propertyOwners) { + json << createJson(o); + if (o != propertyOwners.back()) { + json << ","; + } } - catch (...) {} + json << "]"; + json << "}"; - std::stringstream html; - html << "\n" - << "\n" - << "\t\n" - << "\t\t\n" - << "\t\t\n" - << "\t\t\n" - << "\t\n" - << "\t\n" - << "\t\tDocumentation\n" - << "\t\n" - << "\t\n" - << "\t\n" - << "\n"; - file << html.str(); + return json.str(); + }; + + + std::stringstream json; + json << "["; + std::vector nodes = allSceneGraphNodes(); + if (!nodes.empty()) { + json << std::accumulate( + std::next(nodes.begin()), + nodes.end(), + createJson(*nodes.begin()), + [createJson](std::string a, SceneGraphNode* n) { + return a + "," + createJson(n); + } + ); } - else - LERROR("Undefined type '" << type << "' for Property documentation"); + + json << "]"; + + std::string jsonString = ""; + for (const char& c : json.str()) { + if (c == '\'') { + jsonString += "\\'"; + } + else { + jsonString += c; + } + } + + return jsonString; } scripting::LuaLibrary Scene::luaLibrary() { diff --git a/src/scripting/scriptengine.cpp b/src/scripting/scriptengine.cpp index ddbd6fac4f..af37f4623c 100644 --- a/src/scripting/scriptengine.cpp +++ b/src/scripting/scriptengine.cpp @@ -65,6 +65,18 @@ namespace { std::string ScriptEngine::OpenSpaceLibraryName = "openspace"; +ScriptEngine::ScriptEngine() + : Documented( + "Script Documentation", + "scripting", + { + { "mainTemplate", MainTemplateFilename }, + { "scriptingTemplate", ScriptingTemplateFilename } + }, + JsFilename + ) +{} + void ScriptEngine::initialize() { LDEBUG("Adding base library"); addBaseLibrary(); @@ -496,235 +508,48 @@ std::vector ScriptEngine::allLuaFunctions() const { return result; } -void ScriptEngine::writeDocumentation(const std::string& filename, const std::string& type) const { - auto concatenate = [](std::string library, std::string function) { - std::string total = "openspace."; - if (!library.empty()) { - total += std::move(library) + "."; +std::string ScriptEngine::generateJson() const { + // Create JSON + std::stringstream json; + json << "["; + + bool first = true; + for (const LuaLibrary& l : _registeredLibraries) { + if (!first) { + json << ","; } - total += std::move(function); - return total; - }; + first = false; - LDEBUG("Writing Lua documentation of type '" << type << - "' to file '" << filename << "'"); - if (type == "text") { - // Settings - const unsigned int lineWidth = 80; - static const std::string whitespace = " \t"; - static const std::string padding = " "; + json << "{"; + json << "\"library\": \"" << l.name << "\","; + json << "\"functions\": ["; - // The additional space between the longest function name and the descriptions - - std::ofstream file; - file.exceptions(~std::ofstream::goodbit); - file.open(filename); - - file << "Available commands:\n"; - // Now write out the functions - for (const LuaLibrary& l : _registeredLibraries) { - for (const LuaLibrary::Function& f : l.functions) { - std::string name = concatenate(l.name, f.name); - file << padding << name << "(" << f.argumentText << ")" << std::endl; - } - } - file << std::endl; - - // Now write out the functions definitions - for (const LuaLibrary& library : _registeredLibraries) { - for (const LuaLibrary::Function& function : library.functions) { - std::string name = concatenate(library.name, function.name); - file << name << "(" << function.argumentText << "):" << std::endl; - - std::string remainingHelptext = function.helpText; - while (!remainingHelptext.empty()) { - const size_t length = remainingHelptext.length(); - const size_t paddingLength = padding.length(); - - if ((length + paddingLength) > lineWidth) { - size_t lastSpace = remainingHelptext.find_last_of( - whitespace, - lineWidth - 1 - paddingLength - ); - if (lastSpace == remainingHelptext.npos) { - lastSpace = lineWidth; - } - - file << padding << remainingHelptext.substr(0, lastSpace) << '\n'; - - size_t firstNotSpace = remainingHelptext.find_first_not_of( - whitespace, - lastSpace - ); - if (firstNotSpace == remainingHelptext.npos) { - firstNotSpace = lastSpace; - } - remainingHelptext = remainingHelptext.substr(firstNotSpace); - } - else { - file << padding << remainingHelptext << std::endl; - remainingHelptext = ""; - } - } - file << std::endl; - } - } - } - else if (type == "html") { - std::ifstream handlebarsInput(absPath(HandlebarsFilename)); - std::ifstream jsInput(absPath(JsFilename)); - - std::string jsContent; - std::back_insert_iterator jsInserter(jsContent); - - std::copy(std::istreambuf_iterator{handlebarsInput}, std::istreambuf_iterator(), jsInserter); - std::copy(std::istreambuf_iterator{jsInput}, std::istreambuf_iterator(), jsInserter); - - std::ifstream bootstrapInput(absPath(BootstrapFilename)); - std::ifstream cssInput(absPath(CssFilename)); - - std::string cssContent; - std::back_insert_iterator cssInserter(cssContent); - - std::copy(std::istreambuf_iterator{bootstrapInput}, std::istreambuf_iterator(), cssInserter); - std::copy(std::istreambuf_iterator{cssInput}, std::istreambuf_iterator(), cssInserter); - - std::ifstream mainTemplateInput(absPath(MainTemplateFilename)); - std::string mainTemplateContent{ std::istreambuf_iterator{mainTemplateInput}, - std::istreambuf_iterator{} }; - - std::ifstream scriptingTemplateInput(absPath(ScriptingTemplateFilename)); - std::string scriptingTemplateContent{ std::istreambuf_iterator{scriptingTemplateInput}, - std::istreambuf_iterator{} }; - - std::ofstream file; - file.exceptions(~std::ofstream::goodbit); - file.open(filename); - - // Create JSON - std::stringstream json; - json << "["; - - bool first = true; - for (const LuaLibrary& l : _registeredLibraries) { - if (!first) { + for (const LuaLibrary::Function& f : l.functions) { + json << "{"; + json << "\"name\": \"" << f.name << "\", "; + json << "\"arguments\": \"" << f.argumentText << "\", "; + json << "\"help\": \"" << f.helpText << "\""; + json << "}"; + if (&f != &l.functions.back()) { json << ","; } - first = false; - - json << "{"; - json << "\"library\": \"" << l.name << "\","; - json << "\"functions\": ["; - - for (const LuaLibrary::Function& f : l.functions) { - json << "{"; - json << "\"name\": \"" << f.name << "\", "; - json << "\"arguments\": \"" << f.argumentText << "\", "; - json << "\"help\": \"" << f.helpText << "\""; - json << "}"; - if (&f != &l.functions.back()) { - json << ","; - } - } - json << "]}"; - } - json << "]"; + json << "]}"; - std::string jsonString = ""; - for (const char& c : json.str()) { - if (c == '\'') { - jsonString += "\\'"; - } - else { - jsonString += c; - } - } - - std::stringstream html; - html << "\n" - << "\n" - << "\t\n" - << "\t\t\n" - << "\t\t\n" - << "\t\n" - << "\t\n" - << "\t\tDocumentation\n" - << "\t\n" - << "\t\n" - << "\t\n" - << "\n"; - - file << html.str(); - - /* - - html << "\n" - << "\t\n" - << "\t\tScript Log\n" - << "\t\n" - << "\n" - << "\n" - << "\t\n\n" - << "\t\n" - << "\t\t\n" - << "\t\t\t\n" - << "\t\t\t\n" - << "\t\t\n" - << "\t\t\n" - << "\t\t\t\n" - << "\t\t\t\n" - << "\t\t\t\n" - << "\t\t\n" - << "\t\n" - << "\t\n"; - - - - for (const LuaLibrary& l : _registeredLibraries) { - html << "\t\n"; - - if (l.name.empty()) { - html << "\t\t\n"; - } - else { - html << "\t\t\n"; - } - html << "\t\t\n" - << "\t\"; - - for (const LuaLibrary::Function& f : l.functions) { - html << "\t\n" - << "\t\t\n" - << "\t\t\n" - << "\t\t\n" - << "\t\t\n" - << "\t\n"; - } - - html << "\t\n"; - } - - html << "\t\n" - << "
Script Log
LibraryFunctions
NameArgumentsHelp
openspaceopenspace." << l.name << "
" << f.name << "" << f.argumentText << "" << f.helpText << "
\n" - << ""; - - file << html.str(); -*/ } - else { - throw ghoul::RuntimeError("Undefined type '" + type + "' for Lua documentation"); + json << "]"; + + std::string jsonString = ""; + for (const char& c : json.str()) { + if (c == '\'') { + jsonString += "\\'"; + } + else { + jsonString += c; + } } + + return jsonString; } bool ScriptEngine::writeLog(const std::string& script) { diff --git a/src/util/factorymanager.cpp b/src/util/factorymanager.cpp index 3c13b6fcc8..4de2e4ac8f 100644 --- a/src/util/factorymanager.cpp +++ b/src/util/factorymanager.cpp @@ -52,6 +52,18 @@ FactoryManager::FactoryNotFoundError::FactoryNotFoundError(std::string t) ghoul_assert(!type.empty(), "Type must not be empty"); } +FactoryManager::FactoryManager() + : Documented( + "Factory Documentation", + "factories", + { + { "mainTemplate", MainTemplateFilename }, + { "factoryTemplate", FactoryTemplateFilename } + }, + JsFilename + ) +{} + void FactoryManager::initialize() { ghoul_assert(!_manager, "Factory Manager must not have been initialized"); _manager = new FactoryManager; @@ -79,151 +91,34 @@ void FactoryManager::addFactory(std::unique_ptr fact _factories.push_back({ std::move(factory), std::move(name) }); } -void FactoryManager::writeDocumentation(const std::string& file, const std::string& type) { - if (type == "text") { - std::ofstream f; - f.exceptions(~std::ofstream::goodbit); - f.open(file); +std::string FactoryManager::generateJson() const { + std::stringstream json; - for (const FactoryInfo& factoryInfo : _factories) { - f << factoryInfo.name << '\n'; + json << "["; + for (const FactoryInfo& factoryInfo : _factories) { + json << "{"; + json << "\"name\": \"" << factoryInfo.name << "\","; + json << "\"classes\": ["; - ghoul::TemplateFactoryBase* factory = factoryInfo.factory.get(); - for (const std::string& c : factory->registeredClasses()) { - f << '\t' << c << '\n'; - } - f << "\n\n"; - } - - } - else if (type == "html") { - std::ifstream handlebarsInput(absPath(HandlebarsFilename)); - std::ifstream jsInput(absPath(JsFilename)); - - std::string jsContent; - std::back_insert_iterator jsInserter(jsContent); - - std::copy(std::istreambuf_iterator{handlebarsInput}, std::istreambuf_iterator(), jsInserter); - std::copy(std::istreambuf_iterator{jsInput}, std::istreambuf_iterator(), jsInserter); - - std::ifstream bootstrapInput(absPath(BootstrapFilename)); - std::ifstream cssInput(absPath(CssFilename)); - - std::string cssContent; - std::back_insert_iterator cssInserter(cssContent); - - std::copy(std::istreambuf_iterator{bootstrapInput}, std::istreambuf_iterator(), cssInserter); - std::copy(std::istreambuf_iterator{cssInput}, std::istreambuf_iterator(), cssInserter); - - std::ifstream mainTemplateInput(absPath(MainTemplateFilename)); - std::string mainTemplateContent{ std::istreambuf_iterator{mainTemplateInput}, - std::istreambuf_iterator{} }; - - std::ifstream factoryTemplateInput(absPath(FactoryTemplateFilename)); - std::string factoryTemplateContent{ std::istreambuf_iterator{factoryTemplateInput}, - std::istreambuf_iterator{} }; - - std::stringstream json; - - json << "["; - for (const FactoryInfo& factoryInfo : _factories) { - json << "{"; - json << "\"name\": \"" << factoryInfo.name << "\","; - json << "\"classes\": ["; - - ghoul::TemplateFactoryBase* factory = factoryInfo.factory.get(); - const std::vector& registeredClasses = factory->registeredClasses(); - for (const std::string& c : registeredClasses) { - json << "\"" << c << "\""; - if (&c != ®isteredClasses.back()) { - json << ","; - } - } - - json << "]}"; - if (&factoryInfo != &_factories.back()) { + ghoul::TemplateFactoryBase* factory = factoryInfo.factory.get(); + const std::vector& registeredClasses = factory->registeredClasses(); + for (const std::string& c : registeredClasses) { + json << "\"" << c << "\""; + if (&c != ®isteredClasses.back()) { json << ","; } } - json << "]"; - - // I did not check the output of this for correctness ---abock - std::string jsonText = json.str(); - - std::ofstream f; - f.exceptions(~std::ofstream::goodbit); - f.open(file); - - std::string jsonString = ""; - for (const char& c : json.str()) { - if (c == '\'') { - jsonString += "\\'"; - } else { - jsonString += c; - } + json << "]}"; + if (&factoryInfo != &_factories.back()) { + json << ","; } - - std::stringstream html; - html << "\n" - << "\n" - << "\t\n" - << "\t\t\n" - << "\t\t\n" - << "\t\n" - << "\t\n" - << "\t\tDocumentation\n" - << "\t\n" - << "\t\n" - << "\t\n" - << "\n"; - - f << html.str(); - - /* - html << "\n" - << "\t\n" - << "\t\tFactories\n" - << "\t\n" - << "\n" - << "\n" - << "\t\n\n" - << "\t\n" - << "\t\t\n" - << "\t\t\t\n" - << "\t\t\t\n" - << "\t\t\n" - << "\t\n" - << "\t\n"; - - for (const FactoryInfo& factoryInfo : _factories) { - html << "\t\t\n" - << "\t\t\t\n"; - - ghoul::TemplateFactoryBase* factory = factoryInfo.factory.get(); - for (const std::string& c : factory->registeredClasses()) { - html << "\t\t\t\n"; - } - html << "\t\n"; - - } - - html << "\t\n" - << "
Factories
TypeObject
" << factoryInfo.name << "
" << c << "
\n" - << ";"; - f << html.str(); - */ } + + json << "]"; + + // I did not check the output of this for correctness ---abock + return json.str(); } } // namespace openspace