Add capabilities to write out documentation of all Lua functions on startup

This commit is contained in:
Alexander Bock
2014-11-29 14:03:49 +01:00
parent 4de8071efe
commit b05c4cf30f
6 changed files with 90 additions and 6 deletions

1
.gitignore vendored
View File

@@ -27,3 +27,4 @@ html/
latex/
shaders/ABuffer/constants.hglsl
*.OpenSpaceGenerated.glsl
LuaScripting.txt

View File

@@ -57,12 +57,13 @@ public:
void initializeLuaState(lua_State* state);
void addLibrary(const LuaLibrary& library);
void addLibrary(LuaLibrary library);
bool hasLibrary(const std::string& name);
bool runScript(const std::string& script);
bool runScriptFile(const std::string& filename);
bool writeDocumentation(const std::string& filename, const std::string& type) const;
private:
bool registerLuaLibrary(lua_State* state, const LuaLibrary& library);

View File

@@ -42,6 +42,8 @@ namespace configurationmanager {
const std::string keyCachePath = keyPaths + "." + keyCache;
const std::string keyFonts = "Fonts";
const std::string keyConfigSgct = "SGCTConfig";
const std::string keyLuaDocumentationType = "LuaDocumentationFile.Type";
const std::string keyLuaDocumentationFile = "LuaDocumentationFile.File";
const std::string keyConfigScene = "Scene";
const std::string keyStartupScript = "StartupScripts";
const std::string keySpiceTimeKernel = "SpiceKernel.Time";

View File

@@ -26,5 +26,9 @@ return {
Scene = "${OPENSPACE_DATA}/scene/default.scene",
StartupScripts = {
"${SCRIPTS}/default_startup.lua"
},
LuaDocumentationFile = {
Type = "text",
File = "${BASE_PATH}/LuaScripting.txt"
}
}

View File

@@ -344,6 +344,22 @@ bool OpenSpaceEngine::initialize() {
// TODO: Maybe move all scenegraph and renderengine stuff to initializeGL
scriptEngine().initialize();
// If a LuaDocumentationFile was specified, generate it now
using constants::configurationmanager::keyLuaDocumentationType;
using constants::configurationmanager::keyLuaDocumentationFile;
const bool hasType = configurationManager().hasKey(keyLuaDocumentationType);
const bool hasFile = configurationManager().hasKey(keyLuaDocumentationFile);
if (hasType && hasFile) {
std::string luaDocumentationType;
configurationManager().getValue(keyLuaDocumentationType, luaDocumentationType);
std::string luaDocumentationFile;
configurationManager().getValue(keyLuaDocumentationFile, luaDocumentationFile);
luaDocumentationFile = absPath(luaDocumentationFile);
_scriptEngine.writeDocumentation(luaDocumentationFile, luaDocumentationType);
}
// Load scenegraph
SceneGraph* sceneGraph = new SceneGraph;
_renderEngine.setSceneGraph(sceneGraph);

View File

@@ -29,6 +29,7 @@
#include <ghoul/lua/lua_helper.h>
#include <fstream>
#include <iomanip>
namespace openspace {
@@ -208,14 +209,21 @@ void ScriptEngine::deinitialize() {
_state = nullptr;
}
void ScriptEngine::addLibrary(const ScriptEngine::LuaLibrary& library) {
void ScriptEngine::addLibrary(LuaLibrary library) {
auto sortFunc = [](const LuaLibrary::Function& lhs, const LuaLibrary::Function& rhs)
{
return lhs.name < rhs.name;
};
// do we have a library with the same name as the incoming one
auto it = std::find_if(_registeredLibraries.begin(), _registeredLibraries.end(),
[&library](const LuaLibrary& lib) { return lib.name == library.name; });
if (it == _registeredLibraries.end())
// If not, we can add it
_registeredLibraries.insert(library);
if (it == _registeredLibraries.end()) {
// If not, we can add it after we sorted it
std::sort(library.functions.begin(), library.functions.end(), sortFunc);
_registeredLibraries.insert(std::move(library));
}
else {
// otherwise, we merge the libraries
@@ -235,7 +243,10 @@ void ScriptEngine::addLibrary(const ScriptEngine::LuaLibrary& library) {
}
_registeredLibraries.erase(it);
_registeredLibraries.insert(merged);
// Sort the merged library before inserting it
std::sort(merged.functions.begin(), merged.functions.end(), sortFunc);
_registeredLibraries.insert(std::move(merged));
}
}
@@ -475,6 +486,55 @@ bool ScriptEngine::registerLuaLibrary(lua_State* state, const LuaLibrary& librar
return true;
}
bool ScriptEngine::writeDocumentation(const std::string& filename, const std::string& type) const {
if (type == "text") {
// The additional space between the longest function name and the descriptions
const size_t AdditionalSpace = 5;
LDEBUG("Writing Lua documentation of type '" << type <<
"' to file '" << filename << "'");
std::ofstream file(filename);
if (file.good()) {
auto concatenate = [](std::string library, std::string function) {
std::string total = "openspace.";
if (!library.empty())
total += std::move(library) + ".";
total += std::move(function);
return std::move(total);
};
// First iterate over all libraries and functions to find the longest
// combination so that can be used as the 'width' parameter for the output
// stream
size_t maxLength = 0;
for (auto library : _registeredLibraries) {
for (auto function : library.functions) {
std::string functionName = concatenate(library.name, function.name);
maxLength = std::max(maxLength, functionName.size());
}
}
maxLength += AdditionalSpace;
// Now write out the functions
for (auto library : _registeredLibraries) {
for (auto function : library.functions) {
std::string functionName = concatenate(library.name, function.name);
file << std::setw(maxLength) << std::left << functionName;
file << std::setw(0) << function.helpText << std::endl;
}
}
return true;
}
else {
LERROR("Could not open file '" << filename << "' for writing documentation");
return false;
}
}
else {
LERROR("Undefined type '" << type << "' for Lua documentation");
return false;
}
}
} // namespace scripting
} // namespace openspace