Commit dc76b535 authored by Artur Grunau's avatar Artur Grunau
Browse files

Improve documentation of LuaPipeline and related classes

Glue classes that live in the `scripting/glue` directory were mostly
undocumented, and the documentation of LuaPipeline was incomplete.

Improve the documentation of LuaPipeline and LuaVmState. Document
LuaTable, RegularLuaTable and GlobalLuaTable from the `scripting/glue`
directory.

References #1
parent 080b3ae3
......@@ -7,17 +7,39 @@
namespace campvis {
/**
* Class representing global Lua tables.
*
* Global tables store references to all objects that live in the global scope of a Lua VM. As
* a result, they must be used in order to interact with Lua states and access user-defined
* values.
*/
class GlobalLuaTable : public LuaTable
{
public:
/**
* Creates a new GlobalLuaTable.
*
* \param luaVmState Reference to the LuaVmState object from which the table originates
*/
GlobalLuaTable(LuaVmState& luaVmState);
/**
* Virtual destructor.
*/
virtual ~GlobalLuaTable();
/// \see LuaTable::isValid()
virtual bool isValid();
/// \see LuaTable::getTable(const std::string&)
virtual std::shared_ptr<LuaTable> getTable(const std::string& name);
/// \see LuaTable::callInstanceMethod(const std::string&)
virtual void callInstanceMethod(const std::string& name);
protected:
/// \see LuaTable::pushField(const std::string&)
virtual void pushField(const std::string& name);
};
}
......
......@@ -12,23 +12,83 @@ namespace campvis {
class RegularLuaTable;
class GlobalLuaTable;
/**
* Base class for all Lua tables.
*
* LuaTable specifies the interface common to all concrete classes representing Lua tables.
*
* It's important to note that LuaTable and its subclasses are lazy: they don't access the Lua
* VM unless it's necessary (e.g. on method call or field extraction). This helps to keep them
* lightweight as they only have to know how to find the objects they correspond to in a Lua
* state.
*
* Another defining characteristic of LuaTable and its subclasses is the fact that they need to
* cooperate to access to the Lua VM. For instance, to call a function stored in a regular Lua
* table, that table must first be extracted from the global Lua table. This is implemented by
* calling pushField on the global table from the regular table. Nested regular tables require
* such calls to be propagated through their enclosing tables all the way up to the global
* table.
*/
class LuaTable : private std::enable_shared_from_this<LuaTable>
{
friend RegularLuaTable;
friend GlobalLuaTable;
public:
/**
* Creates a new LuaTable.
*
* \param luaVmState Reference to the LuaVmState object from which the table originates
*/
LuaTable(LuaVmState& luaVmState) : _luaVmState(luaVmState) {}
/**
* Virtual destructor.
*/
virtual ~LuaTable() {}
/**
* Checks if this Lua table is valid.
*
* This method examines the table's associated Lua state to verify that it holds an object
* corresponding to this Lua table.
*
* \return true if this Lua table is valid, false otherwise
*/
virtual bool isValid() = 0;
/**
* Returns a subtable of this Lua table.
*
* This method creates and returns an object representing a named Lua table nested in this
* table.
*
* \param name Name of the subtable to return
*/
virtual std::shared_ptr<LuaTable> getTable(const std::string& name) = 0;
/**
* Calls this table's instance method.
*
* callInstanceMethod invokes the specified function stored in this Lua table, passing it
* the table as the first argument (instance).
*
* \param name Name of the instance method to call
*/
virtual void callInstanceMethod(const std::string& name) = 0;
protected:
/**
* Pushes a field of this Lua table onto the Lua VM's stack.
*
* This helper method is used to set up Lua's stack in order to access nested tables or
* call methods.
*
* \param name Name of the field to push onto the stack
*/
virtual void pushField(const std::string& name) = 0;
LuaVmState& _luaVmState;
LuaVmState& _luaVmState; ///< Reference to the LuaVmState from which the table originates
};
}
......
......@@ -29,17 +29,62 @@ namespace campvis {
*/
typedef tbb::recursive_mutex LuaStateMutexType;
/**
* Class used to create and manage a Lua state.
*
* LuaVmState provides a thin wrapper around Lua's struct lua_State. It implements helpers for
* common operations (e.g. script execution) while still giving access to the underlying raw
* Lua state.
*/
class LuaVmState
{
public:
/**
* Creates a new LuaVmState.
*
* \param loadStdLibs Should standard Lua libraries be loaded into the state created by
* LuaVmState?
*/
LuaVmState(bool loadStdLibs = true);
/**
* Virtual destructor.
*/
~LuaVmState();
/**
* Executes a Lua script in the context of this VM.
*
* \param scriptPath Path to a file containing the Lua script to execute
* \return true if the script could be located and executed successfully, false otherwise
*/
bool execFile(const std::string& scriptPath);
/**
* Executes a Lua script in the context of this VM.
*
* \param scriptString String containing the Lua script to execute
* \return true if the script could be executed successfully, false otherwise
*/
bool execString(const std::string& scriptString);
/**
* Returns the global table of the Lua state managed by LuaVmState.
*/
std::shared_ptr<GlobalLuaTable> getGlobalTable();
/**
* Wraps a C++ object using SWIG and injects it into the Lua state managed by LuaVmState.
*
* SWIG glue for the object to be injected must be loaded (using execFile or execString)
* into the Lua state before calling this method or the injection will fail. The Lua VM
* doesn't take ownership of the object.
*
* \param objPointer Pointer to the C++ object to inject into the Lua state
* \param typeName SWIG name of the object's type
* \param luaVarName Name under which to store the object in the Lua state
* \return true if the object was injected into the Lua state successfully, false otherwise
*/
template<typename T>
bool injectObjectPointer(T* objPointer, const std::string& typeName, const std::string& luaVarName);
......@@ -58,10 +103,19 @@ namespace campvis {
/**
* Call the Lua function that's at the top of the stack.
*
* The caller is responsible for setting up the Lua VM in preparation of the call by
* placing the function and all of its arguments on Lua's stack.
*
* \param nargs Number of arguments to pass to the function
* \param nresults Number of expected results
*/
void callLuaFunc(int nargs, int nresults);
private:
/**
* Logs a Lua error to stderr.
*/
void logLuaError();
lua_State* _luaState; ///< Lua state managed by LuaVmState
......
......@@ -6,22 +6,45 @@
namespace campvis {
/**
* Class representing regular Lua tables.
*
* Regular tables can be defined by exclusion: any Lua table that is not a global table is
* a regular one. Tables are Lua's only built-in composite data type. Consequently, they serve
* multiple purposes, including emulation of classes and objects.
*/
class RegularLuaTable : public LuaTable
{
public:
/**
* Creates a new RegularLuaTable.
*
* \param parent Lua table (regular or global) that stores this table
* \param name name of this table (key under which it is stored in its parent)
*/
RegularLuaTable(std::shared_ptr<LuaTable> parent, std::string name);
/**
* Virtual destructor.
*/
virtual ~RegularLuaTable();
/// \see LuaTable::isValid()
virtual bool isValid();
/// \see LuaTable::getTable(const std::string&)
virtual std::shared_ptr<LuaTable> getTable(const std::string& name);
/// \see LuaTable::callInstanceMethod(const std::string&)
virtual void callInstanceMethod(const std::string& name);
protected:
/// \see LuaTable::pushField(const std::string&)
virtual void pushField(const std::string& name);
private:
std::shared_ptr<LuaTable> _parent;
std::string _name;
std::shared_ptr<LuaTable> _parent; ///< Lua table in which this table is stored
std::string _name; ///< Name of this table
};
}
......
......@@ -23,9 +23,11 @@ namespace campvis {
if (!_luaVmState->execString("package.cpath = '" CAMPVIS_LUA_MODS_PATH "'"))
return;
// Load CAMPVis' core Lua module to have SWIG glue for AutoEvaluationPipeline available
if (!_luaVmState->execString("require(\"campvis\")"))
return;
// Make this pipeline object available to the script so that it can configure it
if (!_luaVmState->injectObjectPointer(this, "campvis::AutoEvaluationPipeline *", "instance"))
return;
......
......@@ -9,11 +9,15 @@ namespace campvis {
class LuaTable;
class LuaVmState;
/**
* Class representing CAMPVis pipelines defined in Lua.
*/
class LuaPipeline : public AutoEvaluationPipeline {
public:
/**
* Create a new Lua pipeline.
*
* \param name Name of this pipeline
* \param scriptPath Path to the Lua script defining the pipeline
* \param dc DataContainer containing local working set of data for this pipeline
*/
......@@ -34,8 +38,8 @@ namespace campvis {
virtual void deinit();
protected:
const std::string _name; ///< the name of this pipeline
const std::string _scriptPath; ///< path to the Lua script defining the pipeline
const std::string _name; ///< The name of this pipeline
const std::string _scriptPath; ///< Path to the Lua script defining the pipeline
LuaVmState* _luaVmState; ///< Lua VM state used to evaluate the pipeline
std::shared_ptr<LuaTable> _pipelineTable; ///< Pointer to the Lua table associated with the pipeline
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment