mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 12:10:52 -06:00
Merge branch 'feature/documentation-cleanup'
This commit is contained in:
Submodule documentation updated: c4e5cb78a9...3917fa57e4
@@ -25,8 +25,6 @@
|
||||
#ifndef __OPENSPACE_CORE___DOCUMENTATIONENGINE___H__
|
||||
#define __OPENSPACE_CORE___DOCUMENTATIONENGINE___H__
|
||||
|
||||
#include <openspace/documentation/documentationgenerator.h>
|
||||
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/json.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
@@ -38,7 +36,7 @@ namespace openspace::documentation {
|
||||
* produced in the application an write them out as a documentation file for human
|
||||
* consumption.
|
||||
*/
|
||||
class DocumentationEngine : public DocumentationGenerator {
|
||||
class DocumentationEngine {
|
||||
public:
|
||||
/**
|
||||
* This exception is thrown by the addDocumentation method if a provided Documentation
|
||||
@@ -71,14 +69,6 @@ public:
|
||||
*/
|
||||
void addDocumentation(Documentation documentation);
|
||||
|
||||
/* Adds the \p templates to the list of templates that are written to the
|
||||
* documentation html file.
|
||||
* \param templates Vector of templates to add. Most of the time this list
|
||||
* will just contain one item, but some modules may wish to provide
|
||||
* multiple templates for subtypes, etc
|
||||
*/
|
||||
void addHandlebarTemplates(std::vector<HandlebarTemplate> templates);
|
||||
|
||||
/**
|
||||
* Returns a list of all registered Documentation%s.
|
||||
*
|
||||
@@ -97,18 +87,7 @@ public:
|
||||
*/
|
||||
static DocumentationEngine& ref();
|
||||
|
||||
/**
|
||||
* Generates the documentation html file. Generated file will have embeded
|
||||
* in it: HandlebarJS Templates (from _handlebarTemplates) and json (from
|
||||
* \p data) along with the base template and js/css files from the source
|
||||
* directory ${WEB}/documentation
|
||||
*
|
||||
* \param path The path to add
|
||||
* \param data The JSON data that is written to the documentation
|
||||
*/
|
||||
void writeDocumentationHtml(const std::string& path, std::string data);
|
||||
|
||||
std::string generateJson() const override;
|
||||
std::string generateJson() const;
|
||||
|
||||
nlohmann::json generateJsonJson() const;
|
||||
|
||||
@@ -116,12 +95,9 @@ private:
|
||||
|
||||
/// The list of all Documentation%s that are stored by the DocumentationEngine
|
||||
std::vector<Documentation> _documentations;
|
||||
/// The list of templates to render the documentation with.
|
||||
std::vector<HandlebarTemplate> _handlebarTemplates;
|
||||
|
||||
static DocumentationEngine* _instance;
|
||||
};
|
||||
|
||||
} // namespace openspace::documentation
|
||||
|
||||
#define DocEng (openspace::documentation::DocumentationEngine::ref())
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2023 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef __OPENSPACE_CORE___DOCUMENTATIONGENERATOR___H__
|
||||
#define __OPENSPACE_CORE___DOCUMENTATIONGENERATOR___H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
/*
|
||||
* This abstract class is used for instances when another class has the ability to
|
||||
* generate a Handlebar generated documentation file that contains valuable information
|
||||
* for the user. Instances of this are the DocumentationEngine results, the list of
|
||||
* Property%s generated by the Scene, or the FactoryEngine results. The documentation is
|
||||
* generated through the writeDocumentation method.
|
||||
*
|
||||
* The concrete subclass needs to overload the generateJson class that will return the
|
||||
* Json that is parsed by Handlebar to generate the webpage.
|
||||
*
|
||||
* A list of Handlebar templates, the variable name for the result of the generateJson
|
||||
* method, and the Javascript file that contains additional logic is passed in the
|
||||
* constructor.
|
||||
*/
|
||||
class DocumentationGenerator {
|
||||
public:
|
||||
/// This struct contains a single Handlebar template, with the name and the filename
|
||||
struct HandlebarTemplate {
|
||||
std::string name; ///< The name of the Handlebar template defined in #filename
|
||||
std::string filename; ///< The filename referenced in the #name
|
||||
};
|
||||
|
||||
/**
|
||||
* The constructor that is used to set the member variables later used in the
|
||||
* writeDocumentation method.
|
||||
*
|
||||
* \param name The name of the written documentation
|
||||
* \param jsonName The variable name of the value generated by the generateJson
|
||||
* \param handlebarTemplates A list of Handlebar templates that is added to the
|
||||
* documentation file
|
||||
*
|
||||
* \pre name must not be empty
|
||||
* \pre jsonName must not be empty
|
||||
* \pre Each handlebarTemplates' `name` must not be empty
|
||||
* \pre javascriptFilename must not be empty
|
||||
*/
|
||||
DocumentationGenerator(std::string name, std::string jsonName,
|
||||
std::vector<HandlebarTemplate> handlebarTemplates);
|
||||
|
||||
/// Default constructor
|
||||
virtual ~DocumentationGenerator() = default;
|
||||
|
||||
//getter for handlebar templates
|
||||
std::vector<HandlebarTemplate> templatesToRegister();
|
||||
|
||||
//getter for identifier
|
||||
std::string jsonName();
|
||||
|
||||
/**
|
||||
* This abstract method is used by concrete subclasses to provide the actual data that
|
||||
* is used in the documentation written by this DocumentationGenerator class. The JSON
|
||||
* string returned by this function will be stored in the variable with the
|
||||
* `jsonName` as passed in the constructor.
|
||||
*
|
||||
* \return A JSON script that is parsed and stored in the variable passed in the
|
||||
* DocumentationGenerator constructor
|
||||
*/
|
||||
virtual std::string generateJson() const = 0;
|
||||
|
||||
private:
|
||||
const std::string _name;
|
||||
const std::string _jsonName;
|
||||
const std::vector<HandlebarTemplate> _handlebarTemplates;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#endif // __OPENSPACE_CORE___DOCUMENTATIONGENERATOR___H__
|
||||
@@ -25,8 +25,6 @@
|
||||
#ifndef __OPENSPACE_CORE___KEYBINDINGMANAGER___H__
|
||||
#define __OPENSPACE_CORE___KEYBINDINGMANAGER___H__
|
||||
|
||||
#include <openspace/documentation/documentationgenerator.h>
|
||||
|
||||
#include <openspace/util/keys.h>
|
||||
|
||||
namespace openspace {
|
||||
@@ -38,7 +36,7 @@ namespace openspace::scripting { struct LuaLibrary; }
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
class KeybindingManager : public DocumentationGenerator {
|
||||
class KeybindingManager {
|
||||
public:
|
||||
KeybindingManager();
|
||||
|
||||
@@ -55,8 +53,7 @@ public:
|
||||
|
||||
void keyboardCallback(Key key, KeyModifier modifier, KeyAction action);
|
||||
|
||||
std::string generateJson() const override;
|
||||
nlohmann::json generateJsonJson() const;
|
||||
nlohmann::json generateJson() const;
|
||||
|
||||
const std::multimap<KeyWithModifier, std::string>& keyBindings() const;
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#ifndef __OPENSPACE_CORE___MISSIONMANAGER___H__
|
||||
#define __OPENSPACE_CORE___MISSIONMANAGER___H__
|
||||
|
||||
#include <openspace/documentation/documentationgenerator.h>
|
||||
#include <openspace/mission/mission.h>
|
||||
|
||||
#include <ghoul/misc/assert.h>
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#ifndef __OPENSPACE_CORE___PROPERTYOWNER___H__
|
||||
#define __OPENSPACE_CORE___PROPERTYOWNER___H__
|
||||
|
||||
#include <openspace/documentation/documentationgenerator.h>
|
||||
|
||||
#include <openspace/json.h>
|
||||
#include <map>
|
||||
#include <string>
|
||||
@@ -49,7 +47,7 @@ class Property;
|
||||
* (`.`), the first name before the separator will be used as a subOwner's name and the
|
||||
* search will proceed recursively.
|
||||
*/
|
||||
class PropertyOwner : public DocumentationGenerator {
|
||||
class PropertyOwner {
|
||||
public:
|
||||
/// The separator that is used while accessing the properties and/or sub-owners
|
||||
static constexpr char URISeparator = '.';
|
||||
@@ -76,7 +74,7 @@ public:
|
||||
* The destructor will remove all Propertys and PropertyOwners it owns along with
|
||||
* itself.
|
||||
*/
|
||||
virtual ~PropertyOwner() override;
|
||||
virtual ~PropertyOwner();
|
||||
|
||||
/**
|
||||
* Sets the identifier for this PropertyOwner. If the PropertyOwner does not have an
|
||||
@@ -297,9 +295,7 @@ public:
|
||||
void removeTag(const std::string& tag);
|
||||
|
||||
// Generate JSON for documentation
|
||||
std::string generateJson() const override;
|
||||
|
||||
nlohmann::json generateJsonJson() const;
|
||||
nlohmann::json generateJson() const;
|
||||
|
||||
protected:
|
||||
/// The unique identifier of this PropertyOwner
|
||||
|
||||
@@ -25,18 +25,16 @@
|
||||
#ifndef __OPENSPACE_CORE___SCENELICENSEWRITER___H__
|
||||
#define __OPENSPACE_CORE___SCENELICENSEWRITER___H__
|
||||
|
||||
#include <openspace/documentation/documentationgenerator.h>
|
||||
|
||||
#include <openspace/json.h>
|
||||
#include <vector>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
class SceneLicenseWriter : public DocumentationGenerator {
|
||||
class SceneLicenseWriter {
|
||||
public:
|
||||
SceneLicenseWriter();
|
||||
std::string generateJson() const override;
|
||||
nlohmann::json generateJsonJson() const;
|
||||
nlohmann::json generateJsonList() const;
|
||||
nlohmann::json generateJsonGroupedByLicense() const;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
#define __OPENSPACE_CORE___SCRIPTENGINE___H__
|
||||
|
||||
#include <openspace/util/syncable.h>
|
||||
#include <openspace/documentation/documentationgenerator.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <openspace/json.h>
|
||||
#include <ghoul/lua/luastate.h>
|
||||
@@ -49,7 +48,7 @@ namespace openspace::scripting {
|
||||
* `openspace` namespace prefix in Lua. The same functions can be exposed to
|
||||
* other Lua states by passing them to the #initializeLuaState method.
|
||||
*/
|
||||
class ScriptEngine : public Syncable, public DocumentationGenerator {
|
||||
class ScriptEngine : public Syncable {
|
||||
public:
|
||||
using ScriptCallback = std::function<void(ghoul::Dictionary)>;
|
||||
BooleanType(RemoteScripting);
|
||||
@@ -95,8 +94,7 @@ public:
|
||||
|
||||
std::vector<std::string> allLuaFunctions() const;
|
||||
|
||||
std::string generateJson() const override;
|
||||
nlohmann::json generateJsonJson() const;
|
||||
nlohmann::json generateJson() const;
|
||||
|
||||
private:
|
||||
BooleanType(Replace);
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
#ifndef __OPENSPACE_CORE___FACTORYMANAGER___H__
|
||||
#define __OPENSPACE_CORE___FACTORYMANAGER___H__
|
||||
|
||||
#include <openspace/documentation/documentationgenerator.h>
|
||||
|
||||
#include <openspace/json.h>
|
||||
#include <ghoul/misc/exception.h>
|
||||
#include <ghoul/misc/templatefactory.h>
|
||||
@@ -39,7 +37,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 : public DocumentationGenerator {
|
||||
class FactoryManager {
|
||||
public:
|
||||
/// This exception is thrown if the ghoul::TemplateFactory could not be found in the
|
||||
/// #factory method
|
||||
@@ -109,8 +107,7 @@ public:
|
||||
template <class T>
|
||||
ghoul::TemplateFactory<T>* factory() const;
|
||||
|
||||
std::string generateJson() const override;
|
||||
nlohmann::json generateJsonJson() const;
|
||||
nlohmann::json generateJson() const;
|
||||
|
||||
private:
|
||||
/// Singleton member for the Factory Manager
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#define __OPENSPACE_CORE___JSON_HELPER___H__
|
||||
|
||||
#include <string>
|
||||
#include <openspace/json.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -65,6 +66,16 @@ std::string formatJsonNumber(double d);
|
||||
template <typename T>
|
||||
std::string formatJson(T value);
|
||||
|
||||
/**
|
||||
* Sort a json object that is an array of objects with the structure
|
||||
* [ key = {}, key = {} ...]. Sorts it by the provided key
|
||||
*
|
||||
* \param json The json to sort
|
||||
* \param key The key the json should be sorted by
|
||||
* \return The sorted JSON
|
||||
*/
|
||||
void sortJson(nlohmann::json& json, const std::string& key);
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
#include "json_helper.inl"
|
||||
|
||||
@@ -47,21 +47,19 @@ void DocumentationTopic::handleJson(const nlohmann::json& json) {
|
||||
// Do not parse generated json. Instead implement ability to get
|
||||
// ghoul::Dictionary objects from ScriptEngine, FactoryManager, and KeybindingManager.
|
||||
if (requestedType == "lua") {
|
||||
response = json::parse(global::scriptEngine->generateJson());
|
||||
response = global::scriptEngine->generateJson();
|
||||
}
|
||||
else if (requestedType == "factories") {
|
||||
response = json::parse(FactoryManager::ref().generateJson());
|
||||
response = FactoryManager::ref().generateJson();
|
||||
}
|
||||
else if (requestedType == "keyboard") {
|
||||
response = json::parse(global::keybindingManager->generateJson());
|
||||
response = global::keybindingManager->generateJson();
|
||||
}
|
||||
else if (requestedType == "asset") {
|
||||
response = json::parse(global::keybindingManager->generateJson());
|
||||
response = global::keybindingManager->generateJson();
|
||||
}
|
||||
else if (requestedType == "meta") {
|
||||
std::string docs = SceneLicenseWriter().generateJson();
|
||||
nlohmann::json parsedDocs = json::parse(docs);
|
||||
response = parsedDocs;
|
||||
response = SceneLicenseWriter().generateJsonList();
|
||||
}
|
||||
|
||||
_connection->sendJson(wrappedPayload(response));
|
||||
|
||||
@@ -30,7 +30,6 @@ set(OPENSPACE_SOURCE
|
||||
documentation/core_registration.cpp
|
||||
documentation/documentation.cpp
|
||||
documentation/documentationengine.cpp
|
||||
documentation/documentationgenerator.cpp
|
||||
documentation/verifier.cpp
|
||||
engine/configuration.cpp
|
||||
engine/downloadmanager.cpp
|
||||
@@ -212,7 +211,6 @@ set(OPENSPACE_HEADER
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/documentation/core_registration.h
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/documentation/documentation.h
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/documentation/documentationengine.h
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/documentation/documentationgenerator.h
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/documentation/verifier.h
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/documentation/verifier.inl
|
||||
${PROJECT_SOURCE_DIR}/include/openspace/engine/configuration.h
|
||||
|
||||
@@ -55,15 +55,7 @@ DocumentationEngine::DuplicateDocumentationException::DuplicateDocumentationExce
|
||||
, documentation(std::move(doc))
|
||||
{}
|
||||
|
||||
DocumentationEngine::DocumentationEngine()
|
||||
: DocumentationGenerator(
|
||||
"Top Level",
|
||||
"toplevel",
|
||||
{
|
||||
{ "toplevelTemplate", "${WEB}/documentation/toplevel.hbs" },
|
||||
}
|
||||
)
|
||||
{}
|
||||
DocumentationEngine::DocumentationEngine() {}
|
||||
|
||||
void DocumentationEngine::initialize() {
|
||||
ghoul_assert(!isInitialized(), "DocumentationEngine is already initialized");
|
||||
@@ -180,142 +172,7 @@ void DocumentationEngine::addDocumentation(Documentation documentation) {
|
||||
}
|
||||
}
|
||||
|
||||
void DocumentationEngine::addHandlebarTemplates(std::vector<HandlebarTemplate> templates)
|
||||
{
|
||||
_handlebarTemplates.insert(
|
||||
_handlebarTemplates.end(),
|
||||
templates.begin(), templates.end()
|
||||
);
|
||||
}
|
||||
|
||||
std::vector<Documentation> DocumentationEngine::documentations() const {
|
||||
return _documentations;
|
||||
}
|
||||
|
||||
void DocumentationEngine::writeDocumentationHtml(const std::string& path,
|
||||
std::string data)
|
||||
{
|
||||
ZoneScoped;
|
||||
|
||||
std::ifstream handlebarsInput;
|
||||
handlebarsInput.exceptions(~std::ofstream::goodbit);
|
||||
handlebarsInput.open(absPath(HandlebarsFilename));
|
||||
const std::string handlebarsContent = std::string(
|
||||
std::istreambuf_iterator<char>(handlebarsInput),
|
||||
std::istreambuf_iterator<char>()
|
||||
);
|
||||
std::ifstream jsInput;
|
||||
jsInput.exceptions(~std::ofstream::goodbit);
|
||||
jsInput.open(absPath(JsFilename));
|
||||
const std::string jsContent = std::string(
|
||||
std::istreambuf_iterator<char>(jsInput),
|
||||
std::istreambuf_iterator<char>()
|
||||
);
|
||||
|
||||
std::ifstream bootstrapInput;
|
||||
bootstrapInput.exceptions(~std::ofstream::goodbit);
|
||||
bootstrapInput.open(absPath(BootstrapFilename));
|
||||
const std::string bootstrapContent = std::string(
|
||||
std::istreambuf_iterator<char>(bootstrapInput),
|
||||
std::istreambuf_iterator<char>()
|
||||
);
|
||||
|
||||
std::ifstream cssInput;
|
||||
cssInput.exceptions(~std::ofstream::goodbit);
|
||||
cssInput.open(absPath(CssFilename));
|
||||
const std::string cssContent = std::string(
|
||||
std::istreambuf_iterator<char>(cssInput),
|
||||
std::istreambuf_iterator<char>()
|
||||
);
|
||||
|
||||
std::string filename = path + ("index.html");
|
||||
std::ofstream file;
|
||||
file.exceptions(~std::ofstream::goodbit);
|
||||
file.open(filename);
|
||||
|
||||
// We probably should escape backslashes here?
|
||||
file << "<!DOCTYPE html>" << '\n'
|
||||
<< "<html>" << '\n'
|
||||
<< " " << "<head>" << '\n';
|
||||
|
||||
//write handlebar templates to htmlpage as script elements (as per hb)
|
||||
for (const HandlebarTemplate& t : _handlebarTemplates) {
|
||||
const char* Type = "text/x-handlebars-template";
|
||||
file << " <script id=\"" << t.name << "\" type=\"" << Type << "\">";
|
||||
file << '\n';
|
||||
|
||||
std::ifstream templateFilename(absPath(t.filename));
|
||||
std::string templateContent(
|
||||
std::istreambuf_iterator<char>{templateFilename},
|
||||
std::istreambuf_iterator<char>{}
|
||||
);
|
||||
file << templateContent << "\n </script>" << '\n';
|
||||
}
|
||||
|
||||
//write main template
|
||||
file << " <script id=\"mainTemplate\" type=\"text/x-handlebars-template\">";
|
||||
file << '\n';
|
||||
std::ifstream templateFilename(absPath("${WEB}/documentation/main.hbs"));
|
||||
std::string templateContent(
|
||||
std::istreambuf_iterator<char>{templateFilename},
|
||||
std::istreambuf_iterator<char>{}
|
||||
);
|
||||
file << templateContent << " </script>" << '\n';
|
||||
|
||||
//write scripte to register templates dynamically
|
||||
file << " <script type=\"text/javascript\">" << '\n';
|
||||
file << " templates = [];" << '\n';
|
||||
file << " registerTemplates = function() {" << '\n';
|
||||
|
||||
for (const HandlebarTemplate& t : _handlebarTemplates) {
|
||||
std::string nameOnly = t.name.substr(0, t.name.length() - 8); //-8 for Template
|
||||
file << "\t\t\t\tvar " << t.name;
|
||||
file << "Element = document.getElementById('" << t.name << "');" << '\n';
|
||||
|
||||
file << "\t\t\t\tHandlebars.registerPartial('" << nameOnly << "', ";
|
||||
file << t.name << "Element.innerHTML);" << '\n';
|
||||
|
||||
file << "\t\t\t\ttemplates['" << nameOnly << "'] = Handlebars.compile(";
|
||||
file << t.name << "Element.innerHTML);" << '\n';
|
||||
}
|
||||
file << "\t\t\t}" << '\n';
|
||||
file << "\t\t</script>" << '\n';
|
||||
|
||||
|
||||
const std::string DataId = "data";
|
||||
|
||||
const std::string Version =
|
||||
"[" +
|
||||
std::to_string(OPENSPACE_VERSION_MAJOR) + "," +
|
||||
std::to_string(OPENSPACE_VERSION_MINOR) + "," +
|
||||
std::to_string(OPENSPACE_VERSION_PATCH) +
|
||||
"]";
|
||||
|
||||
file
|
||||
<< " " << "<script id=\"" << DataId
|
||||
<< "\" type=\"text/application/json\">" << '\n'
|
||||
<< " " << std::move(data) << '\n'
|
||||
<< " " << "</script>" << '\n';
|
||||
|
||||
|
||||
file
|
||||
<< " " << "<script>" << '\n'
|
||||
<< " " << jsContent << '\n'
|
||||
<< " " << "var documentation = parseJson('" << DataId << "').documentation;\n"
|
||||
<< " " << "var version = " << Version << ";" << '\n'
|
||||
<< " " << "var currentDocumentation = documentation[0];" << '\n'
|
||||
<< " " << handlebarsContent << '\n'
|
||||
<< " " << "</script>" << '\n'
|
||||
<< " " << "<style type=\"text/css\">" << '\n'
|
||||
<< " " << cssContent << '\n'
|
||||
<< " " << bootstrapContent << '\n'
|
||||
<< " " << "</style>" << '\n'
|
||||
<< " " << "<title>OpenSpace Documentation</title>" << '\n'
|
||||
<< " " << "</head>" << '\n'
|
||||
<< " " << "<body>" << '\n'
|
||||
<< " " << "</body>" << '\n'
|
||||
<< "</html>" << '\n';
|
||||
}
|
||||
|
||||
|
||||
} // namespace openspace::documentation
|
||||
|
||||
@@ -22,40 +22,8 @@
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#include <openspace/documentation/documentationgenerator.h>
|
||||
|
||||
#include <openspace/openspace.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/misc/invariants.h>
|
||||
#include <fstream>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
DocumentationGenerator::DocumentationGenerator(std::string name,
|
||||
std::string jsonName,
|
||||
std::vector<HandlebarTemplate> handlebarTemplates)
|
||||
: _name(std::move(name))
|
||||
, _jsonName(std::move(jsonName))
|
||||
, _handlebarTemplates(std::move(handlebarTemplates))
|
||||
{
|
||||
ghoul_precondition(!_name.empty(), "name must not be empty");
|
||||
ghoul_precondition(!_jsonName.empty(), "jsonName must not be empty");
|
||||
for (const HandlebarTemplate& t : _handlebarTemplates) {
|
||||
(void)t; // Unused variable in Release mode
|
||||
ghoul_precondition(!t.name.empty(), "name must not be empty");
|
||||
ghoul_precondition(!t.filename.empty(), "filename must not be empty");
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<DocumentationGenerator::HandlebarTemplate>
|
||||
DocumentationGenerator::templatesToRegister()
|
||||
{
|
||||
return _handlebarTemplates;
|
||||
}
|
||||
|
||||
std::string DocumentationGenerator::jsonName() {
|
||||
return _jsonName;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -1039,47 +1039,34 @@ void OpenSpaceEngine::writeDocumentation() {
|
||||
|
||||
// Start the async requests as soon as possible so they are finished when we need them
|
||||
std::future<nlohmann::json> settings = std::async(
|
||||
&properties::PropertyOwner::generateJsonJson,
|
||||
&properties::PropertyOwner::generateJson,
|
||||
global::rootPropertyOwner
|
||||
);
|
||||
|
||||
std::future<nlohmann::json> scene = std::async(
|
||||
&properties::PropertyOwner::generateJsonJson,
|
||||
&properties::PropertyOwner::generateJson,
|
||||
_scene.get()
|
||||
);
|
||||
|
||||
|
||||
DocEng.addHandlebarTemplates(global::scriptEngine->templatesToRegister());
|
||||
DocEng.addHandlebarTemplates(FactoryManager::ref().templatesToRegister());
|
||||
DocEng.addHandlebarTemplates(DocEng.templatesToRegister());
|
||||
|
||||
nlohmann::json scripting;
|
||||
scripting["Name"] = "Scripting API";
|
||||
scripting["Data"] = global::scriptEngine->generateJsonJson();
|
||||
|
||||
nlohmann::json factory;
|
||||
factory["Name"] = "Asset Types";
|
||||
factory["Data"] = FactoryManager::ref().generateJsonJson();
|
||||
|
||||
nlohmann::json keybindings;
|
||||
keybindings["Name"] = "Keybindings";
|
||||
keybindings["Keybindings"] = global::keybindingManager->generateJsonJson();
|
||||
|
||||
SceneLicenseWriter writer;
|
||||
nlohmann::json license;
|
||||
license["Name"] = "Licenses";
|
||||
license["Data"] = writer.generateJsonJson();
|
||||
|
||||
nlohmann::json sceneProperties;
|
||||
sceneProperties["Name"] = "Settings";
|
||||
sceneProperties["Data"] = settings.get();
|
||||
|
||||
nlohmann::json sceneGraph;
|
||||
sceneGraph["Name"] = "Scene";
|
||||
sceneGraph["Data"] = scene.get();
|
||||
nlohmann::json scripting = global::scriptEngine->generateJson();
|
||||
nlohmann::json factory = FactoryManager::ref().generateJson();
|
||||
nlohmann::json keybindings = global::keybindingManager->generateJson();
|
||||
nlohmann::json license = writer.generateJsonGroupedByLicense();
|
||||
nlohmann::json sceneProperties = settings.get();
|
||||
nlohmann::json sceneGraph = scene.get();
|
||||
|
||||
sceneProperties["name"] = "Settings";
|
||||
sceneGraph["name"] = "Scene";
|
||||
|
||||
// Add this here so that the generateJson function is the same as before to ensure
|
||||
// backwards compatibility
|
||||
nlohmann::json scriptingResult;
|
||||
scriptingResult["name"] = "Scripting API";
|
||||
scriptingResult["data"] = scripting;
|
||||
|
||||
nlohmann::json documentation = {
|
||||
sceneGraph, sceneProperties, keybindings, license, scripting, factory
|
||||
sceneGraph, sceneProperties, keybindings, license, scriptingResult, factory
|
||||
};
|
||||
|
||||
nlohmann::json result;
|
||||
|
||||
@@ -38,39 +38,7 @@
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
void sortJson(nlohmann::json& json) {
|
||||
std::sort(
|
||||
json.begin(),
|
||||
json.end(),
|
||||
[](const nlohmann::json& lhs, const nlohmann::json& rhs) {
|
||||
std::string lhsString = lhs["Name"];
|
||||
std::string rhsString = rhs["Name"];
|
||||
std::transform(
|
||||
lhsString.begin(),
|
||||
lhsString.end(),
|
||||
lhsString.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); }
|
||||
);
|
||||
std::transform(
|
||||
rhsString.begin(),
|
||||
rhsString.end(),
|
||||
rhsString.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); }
|
||||
);
|
||||
|
||||
return rhsString > lhsString;
|
||||
});
|
||||
}
|
||||
|
||||
KeybindingManager::KeybindingManager()
|
||||
: DocumentationGenerator(
|
||||
"Keybindings",
|
||||
"keybinding",
|
||||
{
|
||||
{ "keybindingTemplate", "${WEB}/documentation/keybinding.hbs" }
|
||||
}
|
||||
)
|
||||
{}
|
||||
KeybindingManager::KeybindingManager() {}
|
||||
|
||||
void KeybindingManager::keyboardCallback(Key key, KeyModifier modifier, KeyAction action)
|
||||
{
|
||||
@@ -143,41 +111,23 @@ const std::multimap<KeyWithModifier, std::string>& KeybindingManager::keyBinding
|
||||
return _keyLua;
|
||||
}
|
||||
|
||||
std::string KeybindingManager::generateJson() const {
|
||||
ZoneScoped;
|
||||
|
||||
std::stringstream json;
|
||||
json << "[";
|
||||
bool first = true;
|
||||
for (const std::pair<const KeyWithModifier, std::string>& p : _keyLua) {
|
||||
if (!first) {
|
||||
json << ",";
|
||||
}
|
||||
first = false;
|
||||
json << "{";
|
||||
json << R"("key": ")" << ghoul::to_string(p.first) << "\",";
|
||||
json << R"("action": ")" << p.second << "\"";
|
||||
json << "}";
|
||||
}
|
||||
json << "]";
|
||||
|
||||
return json.str();
|
||||
}
|
||||
|
||||
nlohmann::json KeybindingManager::generateJsonJson() const {
|
||||
nlohmann::json KeybindingManager::generateJson() const {
|
||||
ZoneScoped;
|
||||
|
||||
nlohmann::json json;
|
||||
|
||||
for (const std::pair<const KeyWithModifier, std::string>& p : _keyLua) {
|
||||
nlohmann::json keybind;
|
||||
keybind["Name"] = ghoul::to_string(p.first);
|
||||
keybind["Action"] = p.second;
|
||||
keybind["name"] = ghoul::to_string(p.first);
|
||||
keybind["action"] = p.second;
|
||||
json.push_back(std::move(keybind));
|
||||
}
|
||||
sortJson(json);
|
||||
sortJson(json, "name");
|
||||
|
||||
return json;
|
||||
nlohmann::json result;
|
||||
result["name"] = "Keybindings";
|
||||
result["keybindings"] = json;
|
||||
return result;
|
||||
}
|
||||
|
||||
scripting::LuaLibrary KeybindingManager::luaLibrary() {
|
||||
|
||||
@@ -41,62 +41,39 @@
|
||||
namespace {
|
||||
constexpr std::string_view _loggerCat = "PropertyOwner";
|
||||
|
||||
void sortJson(nlohmann::json& json) {
|
||||
std::sort(
|
||||
json.begin(),
|
||||
json.end(),
|
||||
[](const nlohmann::json& lhs, const nlohmann::json& rhs) {
|
||||
std::string lhsString = lhs["Name"];
|
||||
std::string rhsString = rhs["Name"];
|
||||
std::transform(
|
||||
lhsString.begin(),
|
||||
lhsString.end(),
|
||||
lhsString.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); }
|
||||
);
|
||||
std::transform(
|
||||
rhsString.begin(),
|
||||
rhsString.end(),
|
||||
rhsString.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); }
|
||||
);
|
||||
|
||||
return rhsString > lhsString;
|
||||
});
|
||||
}
|
||||
|
||||
nlohmann::json createJson(openspace::properties::PropertyOwner* owner) {
|
||||
ZoneScoped
|
||||
|
||||
using namespace openspace;
|
||||
nlohmann::json json;
|
||||
json["Name"] = owner->identifier();
|
||||
json["name"] = !owner->guiName().empty() ? owner->guiName() : owner->identifier();
|
||||
|
||||
json["Description"] = owner->description();
|
||||
json["Properties"] = nlohmann::json::array();
|
||||
json["PropertyOwners"] = nlohmann::json::array();
|
||||
json["Type"] = owner->type();
|
||||
json["Tags"] = owner->tags();
|
||||
json["description"] = owner->description();
|
||||
json["properties"] = nlohmann::json::array();
|
||||
json["propertyOwners"] = nlohmann::json::array();
|
||||
json["type"] = owner->type();
|
||||
json["tags"] = owner->tags();
|
||||
|
||||
const std::vector<properties::Property*>& properties = owner->properties();
|
||||
for (properties::Property* p : properties) {
|
||||
nlohmann::json propertyJson;
|
||||
propertyJson["Name"] = p->identifier();
|
||||
propertyJson["Type"] = p->className();
|
||||
propertyJson["URI"] = p->fullyQualifiedIdentifier();
|
||||
propertyJson["Gui Name"] = p->guiName();
|
||||
propertyJson["Description"] = p->description();
|
||||
std::string name = !p->guiName().empty() ? p->guiName() : p->identifier();
|
||||
propertyJson["name"] = name;
|
||||
propertyJson["type"] = p->className();
|
||||
propertyJson["uri"] = p->fullyQualifiedIdentifier();
|
||||
propertyJson["identifier"] = p->identifier();
|
||||
propertyJson["description"] = p->description();
|
||||
|
||||
json["Properties"].push_back(propertyJson);
|
||||
json["properties"].push_back(propertyJson);
|
||||
}
|
||||
sortJson(json["Properties"]);
|
||||
sortJson(json["properties"], "name");
|
||||
|
||||
auto propertyOwners = owner->propertySubOwners();
|
||||
for (properties::PropertyOwner* o : propertyOwners) {
|
||||
nlohmann::json propertyOwner;
|
||||
json["PropertyOwners"].push_back(createJson(o));
|
||||
json["propertyOwners"].push_back(createJson(o));
|
||||
}
|
||||
sortJson(json["PropertyOwners"]);
|
||||
sortJson(json["propertyOwners"], "name");
|
||||
|
||||
return json;
|
||||
}
|
||||
@@ -105,16 +82,7 @@ namespace {
|
||||
namespace openspace::properties {
|
||||
|
||||
PropertyOwner::PropertyOwner(PropertyOwnerInfo info)
|
||||
: DocumentationGenerator(
|
||||
"Property Owners",
|
||||
"propertyOwners",
|
||||
{
|
||||
{ "propertyOwnersTemplate","${WEB}/documentation/propertyowners.hbs" },
|
||||
{ "propertyTemplate","${WEB}/documentation/property.hbs" },
|
||||
{ "propertylistTemplate","${WEB}/documentation/propertylist.hbs" }
|
||||
}
|
||||
)
|
||||
, _identifier(std::move(info.identifier))
|
||||
: _identifier(std::move(info.identifier))
|
||||
, _guiName(std::move(info.guiName))
|
||||
, _description(std::move(info.description))
|
||||
{
|
||||
@@ -418,31 +386,25 @@ void PropertyOwner::removeTag(const std::string& tag) {
|
||||
_tags.erase(std::remove(_tags.begin(), _tags.end(), tag), _tags.end());
|
||||
}
|
||||
|
||||
std::string PropertyOwner::generateJson() const {
|
||||
ZoneScoped;
|
||||
|
||||
nlohmann::json json;
|
||||
std::vector<PropertyOwner*> subOwners = propertySubOwners();
|
||||
for (PropertyOwner* owner : subOwners) {
|
||||
json["Data"].push_back(createJson(owner));
|
||||
}
|
||||
|
||||
return json.dump();
|
||||
}
|
||||
|
||||
nlohmann::json PropertyOwner::generateJsonJson() const {
|
||||
nlohmann::json PropertyOwner::generateJson() const {
|
||||
ZoneScoped
|
||||
|
||||
nlohmann::json json;
|
||||
std::vector<PropertyOwner*> subOwners = propertySubOwners();
|
||||
for (PropertyOwner* owner : subOwners) {
|
||||
if (owner->identifier() != "Scene") {
|
||||
json.push_back(createJson(owner));
|
||||
nlohmann::json jsonOwner = createJson(owner);
|
||||
|
||||
json.push_back(jsonOwner);
|
||||
}
|
||||
}
|
||||
sortJson(json);
|
||||
sortJson(json, "name");
|
||||
|
||||
return json;
|
||||
nlohmann::json result;
|
||||
result["name"] = "propertyOwner";
|
||||
result["data"] = json;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace openspace::properties
|
||||
|
||||
@@ -36,41 +36,9 @@
|
||||
|
||||
namespace openspace {
|
||||
|
||||
SceneLicenseWriter::SceneLicenseWriter()
|
||||
: DocumentationGenerator(
|
||||
"Scene Licenses",
|
||||
"sceneLicense",
|
||||
{
|
||||
{ "sceneLicenseTemplate", "${WEB}/documentation/scenelicense.hbs" }
|
||||
}
|
||||
)
|
||||
{}
|
||||
SceneLicenseWriter::SceneLicenseWriter() {}
|
||||
|
||||
void sortJson(nlohmann::json& json) {
|
||||
std::sort(
|
||||
json.begin(),
|
||||
json.end(),
|
||||
[](const nlohmann::json& lhs, const nlohmann::json& rhs) {
|
||||
std::string lhsString = lhs["Name"];
|
||||
std::string rhsString = rhs["Name"];
|
||||
std::transform(
|
||||
lhsString.begin(),
|
||||
lhsString.end(),
|
||||
lhsString.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); }
|
||||
);
|
||||
std::transform(
|
||||
rhsString.begin(),
|
||||
rhsString.end(),
|
||||
rhsString.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); }
|
||||
);
|
||||
|
||||
return rhsString > lhsString;
|
||||
});
|
||||
}
|
||||
|
||||
nlohmann::json SceneLicenseWriter::generateJsonJson() const {
|
||||
nlohmann::json SceneLicenseWriter::generateJsonGroupedByLicense() const {
|
||||
nlohmann::json json;
|
||||
|
||||
std::vector<const Asset*> assets =
|
||||
@@ -89,14 +57,14 @@ nlohmann::json SceneLicenseWriter::generateJsonJson() const {
|
||||
if (global::profile->meta.has_value()) {
|
||||
metaTotal++;
|
||||
nlohmann::json metaJson;
|
||||
metaJson["Name"] = "Profile";
|
||||
metaJson["ProfileName"] = global::profile->meta->name.value_or("");
|
||||
metaJson["Version"] = global::profile->meta->version.value_or("");
|
||||
metaJson["Description"] = global::profile->meta->description.value_or("");
|
||||
metaJson["Author"] = global::profile->meta->author.value_or("");
|
||||
metaJson["Url"] = global::profile->meta->url.value_or("");
|
||||
metaJson["License"] = global::profile->meta->license.value_or("");
|
||||
metaJson["Type"] = "license";
|
||||
metaJson["name"] = "Profile";
|
||||
metaJson["profileName"] = global::profile->meta->name.value_or("");
|
||||
metaJson["version"] = global::profile->meta->version.value_or("");
|
||||
metaJson["description"] = global::profile->meta->description.value_or("");
|
||||
metaJson["author"] = global::profile->meta->author.value_or("");
|
||||
metaJson["url"] = global::profile->meta->url.value_or("");
|
||||
metaJson["license"] = global::profile->meta->license.value_or("");
|
||||
metaJson["type"] = "license";
|
||||
json.push_back(std::move(metaJson));
|
||||
}
|
||||
|
||||
@@ -106,102 +74,69 @@ nlohmann::json SceneLicenseWriter::generateJsonJson() const {
|
||||
|
||||
nlohmann::json assetJson;
|
||||
if (!meta.has_value()) {
|
||||
assetJson["Name"] = "";
|
||||
assetJson["Version"] = "";
|
||||
assetJson["Description"] = "";
|
||||
assetJson["Author"] = "";
|
||||
assetJson["Url"] = "";
|
||||
assetJson["License"] = "No license";
|
||||
assetJson["Identifiers"] = "";
|
||||
assetJson["Path"] = asset->path().string();
|
||||
assetJson["name"] = "";
|
||||
assetJson["version"] = "";
|
||||
assetJson["description"] = "";
|
||||
assetJson["author"] = "";
|
||||
assetJson["url"] = "";
|
||||
assetJson["license"] = "No license";
|
||||
assetJson["identifiers"] = "";
|
||||
assetJson["path"] = asset->path().string();
|
||||
|
||||
assetLicenses["No license"].push_back(assetJson);
|
||||
assetLicenses["noLicense"].push_back(assetJson);
|
||||
}
|
||||
else {
|
||||
std::string license = meta->license == "" ? "No license" : meta->license;
|
||||
assetJson["Name"] = meta->name;
|
||||
assetJson["Version"] = meta->version;
|
||||
assetJson["Description"] = meta->description;
|
||||
assetJson["Author"] = meta->author;
|
||||
assetJson["Url"] = meta->url;
|
||||
assetJson["License"] = license;
|
||||
assetJson["Identifiers"] = meta->identifiers;
|
||||
assetJson["Path"] = asset->path().string();
|
||||
std::string license = meta->license == "" ? "No License" : meta->license;
|
||||
assetJson["name"] = meta->name;
|
||||
assetJson["version"] = meta->version;
|
||||
assetJson["description"] = meta->description;
|
||||
assetJson["author"] = meta->author;
|
||||
assetJson["url"] = meta->url;
|
||||
assetJson["license"] = license;
|
||||
assetJson["identifiers"] = meta->identifiers;
|
||||
assetJson["path"] = asset->path().string();
|
||||
|
||||
assetLicenses[license].push_back(assetJson);
|
||||
}
|
||||
}
|
||||
|
||||
nlohmann::json assetsJson;
|
||||
assetsJson["Name"] = "Assets";
|
||||
assetsJson["Type"] = "Licenses";
|
||||
assetsJson["name"] = "Assets";
|
||||
assetsJson["type"] = "Licenses";
|
||||
|
||||
for (const std::pair<std::string, nlohmann::json>& assetLicense : assetLicenses) {
|
||||
nlohmann::json entry;
|
||||
entry["Name"] = assetLicense.first;
|
||||
entry["Assets"] = assetLicense.second;
|
||||
sortJson(entry["Assets"]);
|
||||
assetsJson["Licenses"].push_back(entry);
|
||||
entry["name"] = assetLicense.first;
|
||||
entry["assets"] = assetLicense.second;
|
||||
sortJson(entry["assets"], "name");
|
||||
assetsJson["licenses"].push_back(entry);
|
||||
}
|
||||
json.push_back(assetsJson);
|
||||
return json;
|
||||
|
||||
nlohmann::json result;
|
||||
result["name"] = "Licenses";
|
||||
result["data"] = json;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string SceneLicenseWriter::generateJson() const {
|
||||
ZoneScoped;
|
||||
nlohmann::json SceneLicenseWriter::generateJsonList() const {
|
||||
nlohmann::json json;
|
||||
|
||||
std::stringstream json;
|
||||
json << "[";
|
||||
if (global::profile->meta.has_value()) {
|
||||
nlohmann::json profile;
|
||||
profile["name"] = global::profile->meta->name.value_or("");
|
||||
profile["version"] = global::profile->meta->version.value_or("");
|
||||
profile["description"] = global::profile->meta->description.value_or("");
|
||||
profile["author"] = global::profile->meta->author.value_or("");
|
||||
profile["url"] = global::profile->meta->url.value_or("");
|
||||
profile["license"] = global::profile->meta->license.value_or("");
|
||||
json.push_back(profile);
|
||||
}
|
||||
|
||||
std::vector<const Asset*> assets =
|
||||
global::openSpaceEngine->assetManager().allAssets();
|
||||
|
||||
int metaTotal = 0;
|
||||
int metaCount = 0;
|
||||
for (const Asset* asset : assets) {
|
||||
std::optional<Asset::MetaInformation> meta = asset->metaInformation();
|
||||
if (!meta.has_value()) {
|
||||
continue;
|
||||
}
|
||||
metaTotal++;
|
||||
}
|
||||
|
||||
if (global::profile->meta.has_value()) {
|
||||
metaTotal++;
|
||||
constexpr std::string_view replStr = R"("{}": "{}", )";
|
||||
constexpr std::string_view replStr2 = R"("{}": "{}")";
|
||||
json << "{";
|
||||
json << fmt::format(
|
||||
replStr,
|
||||
"name", escapedJson(global::profile->meta->name.value_or(""))
|
||||
);
|
||||
json << fmt::format(
|
||||
replStr,
|
||||
"version", escapedJson(global::profile->meta->version.value_or(""))
|
||||
);
|
||||
json << fmt::format(
|
||||
replStr,
|
||||
"description", escapedJson(global::profile->meta->description.value_or(""))
|
||||
);
|
||||
json << fmt::format(
|
||||
replStr,
|
||||
"author", escapedJson(global::profile->meta->author.value_or(""))
|
||||
);
|
||||
json << fmt::format(
|
||||
replStr,
|
||||
"url", escapedJson(global::profile->meta->url.value_or(""))
|
||||
);
|
||||
json << fmt::format(
|
||||
replStr2,
|
||||
"license", escapedJson(global::profile->meta->license.value_or(""))
|
||||
);
|
||||
json << "}";
|
||||
|
||||
if (++metaCount != metaTotal) {
|
||||
json << ",";
|
||||
}
|
||||
}
|
||||
|
||||
for (const Asset* asset : assets) {
|
||||
std::optional<Asset::MetaInformation> meta = asset->metaInformation();
|
||||
|
||||
@@ -209,27 +144,18 @@ std::string SceneLicenseWriter::generateJson() const {
|
||||
continue;
|
||||
}
|
||||
|
||||
constexpr std::string_view replStr = R"("{}": "{}", )";
|
||||
constexpr std::string_view replStr2 = R"("{}": "{}")";
|
||||
json << "{";
|
||||
json << fmt::format(replStr, "name", escapedJson(meta->name));
|
||||
json << fmt::format(replStr, "version", escapedJson(meta->version));
|
||||
json << fmt::format(replStr, "description", escapedJson(meta->description));
|
||||
json << fmt::format(replStr, "author", escapedJson(meta->author));
|
||||
json << fmt::format(replStr, "url", escapedJson(meta->url));
|
||||
json << fmt::format(replStr, "license", escapedJson(meta->license));
|
||||
json << fmt::format(replStr, "identifiers", escapedJson(meta->identifiers));
|
||||
json << fmt::format(replStr2, "path", escapedJson(asset->path().string()));
|
||||
json << "}";
|
||||
nlohmann::json assetJson;
|
||||
assetJson["name"] = meta->name;
|
||||
assetJson["version"] = meta->version;
|
||||
assetJson["description"] = meta->description;
|
||||
assetJson["author"] = meta->author;
|
||||
assetJson["url"] = meta->url;
|
||||
assetJson["license"] = meta->license;
|
||||
assetJson["identifiers"] = meta->identifiers;
|
||||
assetJson["path"] = asset->path().string();
|
||||
|
||||
metaCount++;
|
||||
if (metaCount != metaTotal) {
|
||||
json << ",";
|
||||
}
|
||||
json.push_back(assetJson);
|
||||
}
|
||||
|
||||
json << "]";
|
||||
return json.str();
|
||||
return json;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -81,149 +81,43 @@ namespace {
|
||||
return result;
|
||||
}
|
||||
|
||||
void sortJson(nlohmann::json& json) {
|
||||
std::sort(
|
||||
json.begin(),
|
||||
json.end(),
|
||||
[](const nlohmann::json& lhs, const nlohmann::json& rhs) {
|
||||
std::string lhsString = lhs["Name"];
|
||||
std::string rhsString = rhs["Name"];
|
||||
std::transform(
|
||||
lhsString.begin(),
|
||||
lhsString.end(),
|
||||
lhsString.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); }
|
||||
);
|
||||
std::transform(
|
||||
rhsString.begin(),
|
||||
rhsString.end(),
|
||||
rhsString.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); }
|
||||
);
|
||||
|
||||
return rhsString > lhsString;
|
||||
});
|
||||
}
|
||||
|
||||
nlohmann::json toJson(const openspace::scripting::LuaLibrary::Function& f) {
|
||||
nlohmann::json toJson(const openspace::scripting::LuaLibrary::Function& f,
|
||||
bool includeSourceLocation)
|
||||
{
|
||||
using namespace openspace;
|
||||
using namespace openspace::scripting;
|
||||
nlohmann::json function;
|
||||
function["Name"] = f.name;
|
||||
function["name"] = f.name;
|
||||
nlohmann::json arguments = nlohmann::json::array();
|
||||
|
||||
for (const LuaLibrary::Function::Argument& arg : f.arguments) {
|
||||
nlohmann::json argument;
|
||||
argument["Name"] = arg.name;
|
||||
argument["Type"] = arg.type;
|
||||
argument["Default Value"] = arg.defaultValue.value_or("");
|
||||
argument["name"] = arg.name;
|
||||
argument["type"] = arg.type;
|
||||
argument["defaultValue"] = arg.defaultValue.value_or("");
|
||||
arguments.push_back(argument);
|
||||
}
|
||||
|
||||
function["Arguments"] = arguments;
|
||||
function["Return Type"] = f.returnType;
|
||||
function["Help"] = f.helpText;
|
||||
function["arguments"] = arguments;
|
||||
function["returnType"] = f.returnType;
|
||||
function["help"] = f.helpText;
|
||||
|
||||
if (includeSourceLocation) {
|
||||
nlohmann::json sourceLocation;
|
||||
sourceLocation["file"] = f.sourceLocation.file;
|
||||
sourceLocation["line"] = f.sourceLocation.line;
|
||||
function["sourceLocation"] = sourceLocation;
|
||||
}
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
void toJson(const openspace::scripting::LuaLibrary& library, std::stringstream& json)
|
||||
{
|
||||
constexpr std::string_view replStr = R"("{}": "{}", )";
|
||||
constexpr std::string_view replStr2 = R"("{}": "{}")";
|
||||
|
||||
using namespace openspace;
|
||||
using namespace openspace::scripting;
|
||||
|
||||
json << "{";
|
||||
json << fmt::format(replStr, "library", library.name);
|
||||
json << "\"functions\": [";
|
||||
|
||||
for (const LuaLibrary::Function& f : library.functions) {
|
||||
json << "{";
|
||||
json << fmt::format(replStr, "name", f.name);
|
||||
json << "\"arguments\": [";
|
||||
for (const LuaLibrary::Function::Argument& arg : f.arguments) {
|
||||
json << "{";
|
||||
json << fmt::format(replStr, "name", escapedJson(arg.name));
|
||||
json << fmt::format(replStr, "type", escapedJson(arg.type));
|
||||
json << fmt::format(
|
||||
replStr2, "defaultValue", escapedJson(arg.defaultValue.value_or(""))
|
||||
);
|
||||
json << "}";
|
||||
|
||||
if (&arg != &f.arguments.back()) {
|
||||
json << ",";
|
||||
}
|
||||
}
|
||||
json << "],";
|
||||
json << fmt::format(replStr, "returnType", escapedJson(f.returnType));
|
||||
json << fmt::format(replStr, "help", escapedJson(f.helpText));
|
||||
json << fmt::format(
|
||||
"\"sourceLocation\": {{ \"file\": \"{}\", \"line\": {} }}",
|
||||
escapedJson(f.sourceLocation.file), f.sourceLocation.line
|
||||
);
|
||||
json << "}";
|
||||
if (&f != &library.functions.back() || !library.documentations.empty()) {
|
||||
json << ",";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (const LuaLibrary::Function& f : library.documentations) {
|
||||
json << "{";
|
||||
json << fmt::format(replStr, "name", f.name);
|
||||
json << "\"arguments\": [";
|
||||
for (const LuaLibrary::Function::Argument& arg : f.arguments) {
|
||||
json << "{";
|
||||
json << fmt::format(replStr, "name", escapedJson(arg.name));
|
||||
json << fmt::format(replStr, "type", escapedJson(arg.type));
|
||||
json << fmt::format(
|
||||
replStr2, "defaultValue", escapedJson(arg.defaultValue.value_or(""))
|
||||
);
|
||||
json << "}";
|
||||
|
||||
if (&arg != &f.arguments.back()) {
|
||||
json << ",";
|
||||
}
|
||||
}
|
||||
json << "],";
|
||||
json << fmt::format(replStr, "returnType", escapedJson(f.returnType));
|
||||
json << fmt::format(replStr2, "help", escapedJson(f.helpText));
|
||||
json << "}";
|
||||
if (&f != &library.documentations.back()) {
|
||||
json << ",";
|
||||
}
|
||||
}
|
||||
|
||||
json << "],";
|
||||
|
||||
json << "\"subLibraries\": [";
|
||||
for (const LuaLibrary& sl : library.subLibraries) {
|
||||
toJson(sl, json);
|
||||
if (&sl != &library.subLibraries.back()) {
|
||||
json << ",";
|
||||
}
|
||||
}
|
||||
json << "]}";
|
||||
}
|
||||
|
||||
#include "scriptengine_codegen.cpp"
|
||||
} // namespace
|
||||
|
||||
namespace openspace::scripting {
|
||||
|
||||
ScriptEngine::ScriptEngine()
|
||||
: DocumentationGenerator(
|
||||
"Script Documentation",
|
||||
"scripting",
|
||||
{
|
||||
{ "scriptingTemplate","${WEB}/documentation/scripting.hbs" },
|
||||
}
|
||||
)
|
||||
{
|
||||
//tracy::LuaRegister(_state);
|
||||
}
|
||||
ScriptEngine::ScriptEngine() {}
|
||||
|
||||
void ScriptEngine::initialize() {
|
||||
ZoneScoped;
|
||||
@@ -554,28 +448,7 @@ std::vector<std::string> ScriptEngine::allLuaFunctions() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string ScriptEngine::generateJson() const {
|
||||
ZoneScoped;
|
||||
|
||||
// Create JSON
|
||||
std::stringstream json;
|
||||
json << "[";
|
||||
|
||||
bool first = true;
|
||||
for (const LuaLibrary& l : _registeredLibraries) {
|
||||
if (!first) {
|
||||
json << ",";
|
||||
}
|
||||
first = false;
|
||||
|
||||
toJson(l, json);
|
||||
}
|
||||
json << "]";
|
||||
|
||||
return json.str();
|
||||
}
|
||||
|
||||
nlohmann::json ScriptEngine::generateJsonJson() const {
|
||||
nlohmann::json ScriptEngine::generateJson() const {
|
||||
ZoneScoped
|
||||
|
||||
nlohmann::json json;
|
||||
@@ -585,20 +458,26 @@ nlohmann::json ScriptEngine::generateJsonJson() const {
|
||||
using namespace openspace::scripting;
|
||||
|
||||
nlohmann::json library;
|
||||
std::string libraryName = l.name.empty() ? "openspace" : "openspace." + l.name;
|
||||
library["Name"] = libraryName;
|
||||
std::string libraryName = l.name;
|
||||
// Keep the library key for backwards compatability
|
||||
library["library"] = libraryName;
|
||||
library["name"] = libraryName;
|
||||
std::string os = "openspace";
|
||||
library["fullName"] = libraryName.empty() ? os : os + "." + libraryName;
|
||||
|
||||
for (const LuaLibrary::Function& f : l.functions) {
|
||||
library["Functions"].push_back(toJson(f));
|
||||
bool hasSourceLocation = true;
|
||||
library["functions"].push_back(toJson(f, hasSourceLocation));
|
||||
}
|
||||
|
||||
for (const LuaLibrary::Function& f : l.documentations) {
|
||||
library["Functions"].push_back(toJson(f));
|
||||
bool hasSourceLocation = false;
|
||||
library["functions"].push_back(toJson(f, hasSourceLocation));
|
||||
}
|
||||
sortJson(library["Functions"]);
|
||||
sortJson(library["functions"], "name");
|
||||
json.push_back(library);
|
||||
|
||||
sortJson(json);
|
||||
sortJson(json, "library");
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -42,43 +42,19 @@ namespace {
|
||||
using namespace openspace;
|
||||
using namespace openspace::documentation;
|
||||
|
||||
void sortJson(nlohmann::json& json) {
|
||||
std::sort(
|
||||
json.begin(),
|
||||
json.end(),
|
||||
[](const nlohmann::json& lhs, const nlohmann::json& rhs) {
|
||||
std::string lhsString = lhs["Name"];
|
||||
std::string rhsString = rhs["Name"];
|
||||
std::transform(
|
||||
lhsString.begin(),
|
||||
lhsString.end(),
|
||||
lhsString.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); }
|
||||
);
|
||||
std::transform(
|
||||
rhsString.begin(),
|
||||
rhsString.end(),
|
||||
rhsString.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); }
|
||||
);
|
||||
|
||||
return rhsString > lhsString;
|
||||
});
|
||||
}
|
||||
|
||||
nlohmann::json generateJsonDocumentation(const Documentation& d) {
|
||||
nlohmann::json json;
|
||||
|
||||
json["Name"] = d.name;
|
||||
json["Identifier"] = d.id;
|
||||
json["Members"] = nlohmann::json::array();
|
||||
json["name"] = d.name;
|
||||
json["identifier"] = d.id;
|
||||
json["members"] = nlohmann::json::array();
|
||||
|
||||
for (const DocumentationEntry& p : d.entries) {
|
||||
nlohmann::json entry;
|
||||
entry["Name"] = p.key;
|
||||
entry["Optional"] = p.optional.value;
|
||||
entry["Type"] = p.verifier->type();
|
||||
entry["Documentation"] = p.documentation;
|
||||
entry["name"] = p.key;
|
||||
entry["optional"] = p.optional.value;
|
||||
entry["type"] = p.verifier->type();
|
||||
entry["documentation"] = p.documentation;
|
||||
|
||||
TableVerifier* tv = dynamic_cast<TableVerifier*>(p.verifier.get());
|
||||
ReferencingVerifier* rv = dynamic_cast<ReferencingVerifier*>(p.verifier.get());
|
||||
@@ -92,28 +68,28 @@ nlohmann::json generateJsonDocumentation(const Documentation& d) {
|
||||
);
|
||||
|
||||
if (it == documentations.end()) {
|
||||
entry["Reference"]["Found"] = false;
|
||||
entry["reference"]["found"] = false;
|
||||
}
|
||||
else {
|
||||
nlohmann::json reference;
|
||||
reference["Found"] = true;
|
||||
reference["Name"] = it->name;
|
||||
reference["Identifier"] = rv->identifier;
|
||||
reference["found"] = true;
|
||||
reference["name"] = it->name;
|
||||
reference["identifier"] = rv->identifier;
|
||||
|
||||
entry["Reference"] = reference;
|
||||
entry["reference"] = reference;
|
||||
}
|
||||
}
|
||||
else if (tv) {
|
||||
nlohmann::json json = generateJsonDocumentation(tv->documentations);
|
||||
// We have a TableVerifier, so we need to recurse
|
||||
entry["Restrictions"] = json;
|
||||
entry["restrictions"] = json;
|
||||
}
|
||||
else {
|
||||
entry["Description"] = p.verifier->documentation();
|
||||
entry["description"] = p.verifier->documentation();
|
||||
}
|
||||
json["Members"].push_back(entry);
|
||||
json["members"].push_back(entry);
|
||||
}
|
||||
sortJson(json["Members"]);
|
||||
sortJson(json["members"], "name");
|
||||
|
||||
return json;
|
||||
}
|
||||
@@ -130,15 +106,7 @@ FactoryManager::FactoryNotFoundError::FactoryNotFoundError(std::string t)
|
||||
ghoul_assert(!type.empty(), "Type must not be empty");
|
||||
}
|
||||
|
||||
FactoryManager::FactoryManager()
|
||||
: DocumentationGenerator(
|
||||
"Factory Documentation",
|
||||
"factory",
|
||||
{
|
||||
{ "factoryTemplate", "${WEB}/documentation/factory.hbs" }
|
||||
}
|
||||
)
|
||||
{}
|
||||
FactoryManager::FactoryManager() {}
|
||||
|
||||
void FactoryManager::initialize() {
|
||||
ghoul_assert(!_manager, "Factory Manager must not have been initialized");
|
||||
@@ -172,32 +140,14 @@ FactoryManager& FactoryManager::ref() {
|
||||
return *_manager;
|
||||
}
|
||||
|
||||
std::string FactoryManager::generateJson() const {
|
||||
nlohmann::json json;
|
||||
|
||||
for (const FactoryInfo& factoryInfo : _factories) {
|
||||
nlohmann::json factory;
|
||||
factory["Name"] = factoryInfo.name;
|
||||
|
||||
ghoul::TemplateFactoryBase* f = factoryInfo.factory.get();
|
||||
const std::vector<std::string>& registeredClasses = f->registeredClasses();
|
||||
for (const std::string& c : registeredClasses) {
|
||||
json["Classes"].push_back(c);
|
||||
}
|
||||
json["Data"].push_back(factory);
|
||||
}
|
||||
|
||||
return json.dump();
|
||||
}
|
||||
|
||||
nlohmann::json FactoryManager::generateJsonJson() const {
|
||||
nlohmann::json FactoryManager::generateJson() const {
|
||||
nlohmann::json json;
|
||||
std::vector<Documentation> docs = DocEng.documentations();
|
||||
|
||||
for (const FactoryInfo& factoryInfo : _factories) {
|
||||
nlohmann::json factory;
|
||||
factory["Name"] = factoryInfo.name;
|
||||
factory["Identifier"] = "category" + factoryInfo.name;
|
||||
factory["name"] = factoryInfo.name;
|
||||
factory["identifier"] = "category" + factoryInfo.name;
|
||||
|
||||
ghoul::TemplateFactoryBase* f = factoryInfo.factory.get();
|
||||
// Add documentation about base class
|
||||
@@ -209,15 +159,15 @@ nlohmann::json FactoryManager::generateJsonJson() const {
|
||||
});
|
||||
if (factoryDoc != docs.end()) {
|
||||
nlohmann::json documentation = generateJsonDocumentation(*factoryDoc);
|
||||
factory["Classes"].push_back(documentation);
|
||||
factory["classes"].push_back(documentation);
|
||||
// Remove documentation from list check at the end if all docs got put in
|
||||
docs.erase(factoryDoc);
|
||||
}
|
||||
else {
|
||||
nlohmann::json documentation;
|
||||
documentation["Name"] = factoryInfo.name;
|
||||
documentation["Identifier"] = factoryInfo.name;
|
||||
factory["Classes"].push_back(documentation);
|
||||
documentation["name"] = factoryInfo.name;
|
||||
documentation["identifier"] = factoryInfo.name;
|
||||
factory["classes"].push_back(documentation);
|
||||
}
|
||||
|
||||
// Add documentation about derived classes
|
||||
@@ -231,32 +181,37 @@ nlohmann::json FactoryManager::generateJsonJson() const {
|
||||
});
|
||||
if (found != docs.end()) {
|
||||
nlohmann::json documentation = generateJsonDocumentation(*found);
|
||||
factory["Classes"].push_back(documentation);
|
||||
factory["classes"].push_back(documentation);
|
||||
docs.erase(found);
|
||||
}
|
||||
else {
|
||||
nlohmann::json documentation;
|
||||
documentation["Name"] = c;
|
||||
documentation["Identifier"] = c;
|
||||
factory["Classes"].push_back(documentation);
|
||||
documentation["name"] = c;
|
||||
documentation["identifier"] = c;
|
||||
factory["classes"].push_back(documentation);
|
||||
}
|
||||
}
|
||||
sortJson(factory["Classes"]);
|
||||
sortJson(factory["classes"], "name");
|
||||
json.push_back(factory);
|
||||
}
|
||||
// Add all leftover docs
|
||||
nlohmann::json leftovers;
|
||||
leftovers["Name"] = "Other";
|
||||
leftovers["Identifier"] = "other";
|
||||
leftovers["name"] = "Other";
|
||||
leftovers["identifier"] = "other";
|
||||
|
||||
for (const Documentation& doc : docs) {
|
||||
leftovers["Classes"].push_back(generateJsonDocumentation(doc));
|
||||
leftovers["classes"].push_back(generateJsonDocumentation(doc));
|
||||
}
|
||||
sortJson(leftovers["Classes"]);
|
||||
sortJson(leftovers["classes"], "name");
|
||||
json.push_back(leftovers);
|
||||
sortJson(json);
|
||||
sortJson(json, "name");
|
||||
|
||||
// I did not check the output of this for correctness ---abock
|
||||
return json;
|
||||
nlohmann::json result;
|
||||
result["name"] = "Asset Types";
|
||||
result["data"] = json;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -84,4 +84,29 @@ std::string formatJsonNumber(double d) {
|
||||
return std::to_string(d);
|
||||
}
|
||||
|
||||
void sortJson(nlohmann::json& json, const std::string& key) {
|
||||
std::sort(
|
||||
json.begin(),
|
||||
json.end(),
|
||||
[&key](const nlohmann::json& lhs, const nlohmann::json& rhs) {
|
||||
std::string lhsString = lhs[key];
|
||||
std::string rhsString = rhs[key];
|
||||
std::transform(
|
||||
lhsString.begin(),
|
||||
lhsString.end(),
|
||||
lhsString.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); }
|
||||
);
|
||||
std::transform(
|
||||
rhsString.begin(),
|
||||
rhsString.end(),
|
||||
rhsString.begin(),
|
||||
[](unsigned char c) { return std::tolower(c); }
|
||||
);
|
||||
|
||||
return rhsString > lhsString;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
Reference in New Issue
Block a user