VR-Engage  2.2
Loading...
Searching...
No Matches
luaState.h
Go to the documentation of this file.
1/*******************************************************************************
2** Copyright (c) 2025 MAK Technologies
3** All rights reserved.
4*******************************************************************************/
5
6//! \file luaState.h
7//! \ingroup vreUtil
8//! \brief Provides an interface for interacting with a Lua state in VREngage
9//!
10//! This file defines the DtLuaState class which provides a high-level interface
11//! for working with Lua states, including executing scripts, manipulating the stack,
12//! and encoding/decoding values between C++ and Lua.
13
14#pragma once
15
16#include "vreUtil/export.h"
17#include "vreUtil/assert.h"
18
20#include "vreUtil/luaObject.h"
21
22#include <string>
23#include <map>
24
25struct lua_State;
26
27namespace makVre
28{
29//! \brief Error handler function for Lua errors
30//! \param L Pointer to the Lua state
31//! \return Number of values returned on the Lua stack
32//!
33//! This function captures Lua errors, formats them with additional information,
34//! and returns them as a string on the Lua stack.
35int UTIL_DLL DtLuaErrorHandler(lua_State* L);
36
37//! \brief Class for managing a Lua state and providing high-level operations
38//!
39//! This class encapsulates a Lua state and provides methods for executing scripts,
40//! accessing Lua objects, and converting between C++ and Lua data types. It also
41//! manages the encoder/decoder registry for type conversion.
43{
44private:
45 //! \brief Copy constructor (not implemented)
46 //!
47 //! Copying a Lua state is not supported
48 DtLuaState(const DtLuaState& orig); // not implemented
49
50public:
51 //! \brief Default constructor
52 //!
53 //! Creates a new Lua state and initializes it with standard libraries
55
56 //! \brief Constructor with existing Lua state
57 //! \param L Reference to an existing Lua state to use
58 DtLuaState(lua_State& L);
59
60 //! \brief Virtual destructor
61 //!
62 //! Closes the Lua state if it was created by this object
63 virtual ~DtLuaState();
64
65 //! \brief Assignment operator
66 //! \param orig The Lua state to copy from
67 //! \return Reference to this object
68 //!
69 //! Copies the Lua state reference but does not copy the actual Lua state
71
72 //! \brief Gets the underlying Lua state
73 //! \return Pointer to the Lua state
74 lua_State* state();
75
76 //! \brief Checks if an object exists in the Lua state
77 //! \param name Name of the object to check for
78 //! \return True if the object exists, false otherwise
79 virtual bool hasObject(const std::string& name);
80
81 //! \brief Finds and returns a Lua object
82 //! \param name Name of the object to find
83 //! \return The Lua object if found
84 virtual DtLuaObject findObject(const std::string& name);
85
86 //! \brief Executes a Lua script from a file
87 //! \param filename Path to the Lua script file
88 //! \return True if execution succeeded, false otherwise
89 virtual bool doFile(const std::string& filename);
90
91 //! \brief Executes a Lua script from a string
92 //! \param data The Lua script code as a string
93 //! \return True if execution succeeded, false otherwise
94 virtual bool doScript(const std::string& data);
95
96 //! \brief Gets a value from the Lua stack and converts it to a C++ type
97 //! \tparam RT Return type to convert the Lua value to
98 //! \param stackIndex Index on the Lua stack
99 //! \return The value converted to the requested C++ type
100 //! \throw std::string if a decoder for the requested type is not found
101 template <typename RT>
102 RT get(int stackIndex);
103
104 //! \brief Gets a named value from Lua and converts it to a C++ type
105 //! \tparam RT Return type to convert the Lua value to
106 //! \param name Name of the Lua variable/object to get
107 //! \param resolveDots Whether to resolve dotted names (e.g., 'table.field')
108 //! \return The value converted to the requested C++ type
109 //! \throw std::string if the variable doesn't exist or a decoder for the type is not found
110 template <typename RT>
111 RT get(const std::string& name, bool resolveDots = true);
112
113 //! \brief Pushes a C++ value onto the Lua stack
114 //! \tparam T Type of the value to push
115 //! \param data The value to push onto the Lua stack
116 //! \throw std::string if an encoder for the specified type is not found
117 template <typename T>
118 void push(const T& data);
119
120 //! \brief Stores a C++ value as a named variable in Lua
121 //! \tparam T Type of the value to store
122 //! \param name Name to give the variable in Lua
123 //! \param data The value to store
124 //! \return True if storage succeeded, false otherwise
125 template <typename T>
126 bool store(const std::string& name, const T& data);
127
128 //! \brief Creates a new Lua table
129 //! \param narr Pre-allocated array slots (optimization hint)
130 //! \param nrec Pre-allocated record slots (optimization hint)
131 //! \return A Lua object representing the new table
132 virtual DtLuaObject createTable(int narr = 0, int nrec = 0);
133
134 //! \brief Clears the Lua stack
135 //!
136 //! Removes all items from the Lua stack
137 virtual void clearStack();
138
139 //! \brief Dumps the contents of the Lua stack for debugging
140 //!
141 //! Prints each item on the stack to standard output
142 virtual void stackDump();
143
144 //! \brief Forces a full Lua garbage collection cycle
146
147 //! \brief Registers an encoder for a specific C++ type
148 //! \tparam T The C++ type to register an encoder for
149 //! \param encoder Pointer to the encoder implementation
150 template <typename T>
151 static void addEncoder(DtBaseEncoder* encoder);
152
153 //! \brief Registers a decoder for a specific C++ type
154 //! \tparam T The C++ type to register a decoder for
155 //! \param decoder Pointer to the decoder implementation
156 template <typename T>
157 static void addDecoder(DtBaseDecoder* decoder);
158
159 //! \brief Retrieves a named item and pushes it onto the stack
160 //! \param name Name of the item to retrieve
161 //! \param resolveDots Whether to resolve dotted names (e.g., 'table.field')
162 //! \return True if the item was found and pushed, false otherwise
163 virtual bool getItemOnStack(const std::string& name, bool resolveDots = true);
164
165 //! \brief Checks if the top stack value is valid
166 //! \return True if the top stack value is valid, false otherwise
167 virtual bool topStackValueOk();
168
169 //! \brief Gets the current size of the Lua stack
170 //! \return Number of items on the stack
171 virtual int stackSize();
172
173protected:
174 //! \brief Prints a single value from the stack for debugging
175 //! \param index Index of the value to print
176 virtual void printValue(int index);
177
178 //! \brief Prints a table from the stack for debugging
179 //! \param index Index of the table to print
180 virtual void printTable(int index);
181
182 //! \brief Pointer to the Lua state
183 lua_State* myState;
184
185 //! \brief Flag indicating if the state should be closed on destruction
187
188 //! \brief Type definition for the encoder registry map
189 using EncoderMap = std::map<std::string, DtBaseEncoder*>;
190
191 //! \brief Type definition for the decoder registry map
192 using DecoderMap = std::map<std::string, DtBaseDecoder*>;
193
194 //! \brief Static map of type names to encoder implementations
196
197 //! \brief Static map of type names to decoder implementations
199
200 //! \brief Initializes the standard encoders
201 static void initEncoders();
202
203 //! \brief Initializes the standard decoders
204 static void initDecoders();
205
206 //! \brief Flag indicating if encoders and decoders have been initialized
208};
209
210template <typename RT>
211RT DtLuaState::get(int stackIndex)
212{
213 DtLuaStackCleaner cleaner(*myState);
214 DecoderMap::iterator iter = theDecoders.find(typeid(RT).name());
215 if (iter == theDecoders.end())
216 {
217 std::string error = std::string("Cannot find data type decoder for type") + std::string(typeid(RT).name());
218 DtASSERT(0, error.c_str());
219 throw error;
220 }
221
222 DtTypeDecoder<RT>* decoder = (DtTypeDecoder<RT>*)iter->second;
223 return decoder->get(myState, stackIndex);
224};
225
226template <typename RT>
227RT DtLuaState::get(const std::string& name, bool resolveDots /* = true */)
228{
229 DtLuaStackCleaner cleaner(*myState);
230 getItemOnStack(name, resolveDots);
231
232 return get<RT>(-1);
233};
234
235template <typename T>
236void DtLuaState::push(const T& data)
237{
238 EncoderMap::iterator iter = theEncoders.find(typeid(T).name());
239 if (iter == theEncoders.end())
240 {
241 std::string error = std::string("Cannot find data type encoder for type") + std::string(typeid(T).name());
242 DtASSERT(0, error.c_str());
243 throw error;
244 }
245
246 DtTypeEncoder<T>* encoder = (DtTypeEncoder<T>*)iter->second;
247
248 encoder->push(myState, data);
249};
250
251template <typename T>
253{
254 theEncoders[typeid(T).name()] = encoder;
255};
256
257template <typename T>
259{
260 theDecoders[typeid(T).name()] = decoder;
261};
262
263} // namespace makVre
Provides assertion macros and functions for error detection and handling.
#define DtASSERT(exp, description)
Primary assertion macro for runtime validation.
Definition assert.h:53
Base class for all Lua to C++ decoders.
Definition luaEncoderDecoder.h:30
Base class for all C++ to Lua encoders.
Definition luaEncoderDecoder.h:59
Represents a Lua object (typically a table) in C++.
Definition luaObject.h:37
A utility class for automatically cleaning the Lua stack.
Definition luaStackCleaner.h:28
virtual bool hasObject(const std::string &name)
Checks if an object exists in the Lua state.
bool myNeedToCloseState
Flag indicating if the state should be closed on destruction.
Definition luaState.h:186
static bool theInitializedEncoderDecoders
Flag indicating if encoders and decoders have been initialized.
Definition luaState.h:207
static void addDecoder(DtBaseDecoder *decoder)
Registers a decoder for a specific C++ type.
virtual DtLuaObject findObject(const std::string &name)
Finds and returns a Lua object.
virtual bool getItemOnStack(const std::string &name, bool resolveDots=true)
Retrieves a named item and pushes it onto the stack.
DtLuaState & operator=(const DtLuaState &orig)
Assignment operator.
void push(const T &data)
Pushes a C++ value onto the Lua stack.
Definition luaState.h:236
static void addEncoder(DtBaseEncoder *encoder)
Registers an encoder for a specific C++ type.
virtual int stackSize()
Gets the current size of the Lua stack.
DtLuaState(lua_State &L)
Constructor with existing Lua state.
RT get(int stackIndex)
Gets a value from the Lua stack and converts it to a C++ type.
Definition luaState.h:211
virtual void forceGarbageCollection()
Forces a full Lua garbage collection cycle.
virtual bool doFile(const std::string &filename)
Executes a Lua script from a file.
virtual void printValue(int index)
Prints a single value from the stack for debugging.
virtual void stackDump()
Dumps the contents of the Lua stack for debugging.
DtLuaState(const DtLuaState &orig)
Copy constructor (not implemented)
lua_State * myState
Pointer to the Lua state.
Definition luaState.h:183
virtual ~DtLuaState()
Virtual destructor.
virtual void printTable(int index)
Prints a table from the stack for debugging.
static EncoderMap theEncoders
Static map of type names to encoder implementations.
Definition luaState.h:195
lua_State * state()
Gets the underlying Lua state.
static DecoderMap theDecoders
Static map of type names to decoder implementations.
Definition luaState.h:198
std::map< std::string, DtBaseDecoder * > DecoderMap
Type definition for the decoder registry map.
Definition luaState.h:192
bool store(const std::string &name, const T &data)
Stores a C++ value as a named variable in Lua.
virtual void clearStack()
Clears the Lua stack.
static void initDecoders()
Initializes the standard decoders.
DtLuaState()
Default constructor.
std::map< std::string, DtBaseEncoder * > EncoderMap
Type definition for the encoder registry map.
Definition luaState.h:189
virtual bool topStackValueOk()
Checks if the top stack value is valid.
virtual bool doScript(const std::string &data)
Executes a Lua script from a string.
static void initEncoders()
Initializes the standard encoders.
virtual DtLuaObject createTable(int narr=0, int nrec=0)
Creates a new Lua table.
Type-specific decoder for converting Lua values to C++ values.
Definition luaEncoderDecoder.h:46
virtual T get(lua_State *state, int index)
Converts a Lua value to a C++ value.
Type-specific encoder for converting C++ values to Lua values.
Definition luaEncoderDecoder.h:76
virtual void push(lua_State *state, const T &data)
Pushes a C++ value onto the Lua stack.
Defines export macros for the VREngage Utility library.
#define UTIL_DLL
Export/import macro for non-Windows platforms.
Definition export.h:39
Provides type conversion between C++ and Lua.
Provides access to Lua tables and objects with C++ wrappers.
Include export definitions for this library.
Definition glsVreMessageUtil.h:49
int UTIL_DLL DtLuaErrorHandler(lua_State *L)
Error handler function for Lua errors.