VR-Engage  2.2
Loading...
Searching...
No Matches
luaObject.h
Go to the documentation of this file.
1/*******************************************************************************
2** Copyright (c) 2025 MAK Technologies
3** All rights reserved.
4*******************************************************************************/
5
6//! \file luaObject.h
7//! \ingroup vreUtil
8//! \brief Provides access to Lua tables and objects with C++ wrappers
9//!
10//! This file defines the DtLuaObject class which provides a C++ interface to
11//! Lua objects. It allows for retrieval and manipulation of Lua tables and values
12//! through C++ methods, simplifying the interaction between C++ and Lua.
13
14#pragma once
15
16#include "vreUtil/export.h"
17#include "vreUtil/luaValue.h"
19#include "vreUtil/logger.h"
20
21#include <string>
22#include <vector>
23
24struct lua_State;
25
26namespace makVre
27{
28class DtLuaReference;
29class DtLuaState;
30
31//! \brief Represents a Lua object (typically a table) in C++
32//!
33//! This class provides a C++ interface to Lua objects, primarily tables.
34//! It allows for retrieval and manipulation of Lua values through C++ methods,
35//! simplifying the interaction between C++ and Lua code.
37{
38public:
39 //! \brief Default constructor
40 //!
41 //! Creates an empty, invalid Lua object reference
43
44 //! \brief Constructor from Lua stack value
45 //! \param state The Lua state containing the object
46 //! \param index Index of the object on the Lua stack
47 DtLuaObject(lua_State& state, int index);
48
49 //! \brief Virtual destructor
50 //!
51 //! Releases the reference to the Lua object
52 virtual ~DtLuaObject() override;
53
54 //! \brief Copy constructor
55 //! \param orig The source object to copy from
57
58 //! \brief Assignment operator
59 //! \param orig The source object to assign from
60 //! \return Reference to this object
62
63 //! \brief Equality comparison operator
64 //! \param rhs Right-hand side object to compare with
65 //! \return True if objects reference the same Lua object, false otherwise
66 virtual bool operator==(const DtLuaObject& rhs);
67
68 //! \brief Gets the value of this object converted to a C++ type
69 //! \tparam RT The C++ type to convert the Lua value to
70 //! \return The Lua value converted to the specified C++ type
71 //! \throw std::string if the object is invalid or conversion fails
72 template <typename RT>
73 RT get();
74
75 //! \brief Pushes this object onto the Lua stack
76 //!
77 //! This method pushes a reference to the Lua object onto the Lua stack
78 //! for operations that require the object to be on the stack.
79 virtual void push() const;
80
81 //! \name Table Access Methods
82 //! \brief Methods for accessing table fields
83 //! @{
84
85 //! \brief Checks if the table has a field with the given name
86 //! \param name The name of the field to check for
87 //! \param resolveDots If true, handles dotted notation for nested tables (e.g., "table.field")
88 //! \return True if the field exists, false otherwise
89 virtual bool hasField(const std::string& name, bool resolveDots = true);
90
91 //! \brief Checks if the table has a field at the given numeric index
92 //! \param index The numeric index to check
93 //! \return True if the field exists, false otherwise
94 virtual bool hasField(int index);
95 //! \brief Gets a field by name
96 //! \param name The name of the field to retrieve
97 //! \return A new DtLuaObject referencing the field
98 virtual DtLuaObject operator[](std::string name);
99
100 //! \brief Gets a field by numeric index
101 //! \param index The numeric index of the field to retrieve
102 //! \return A new DtLuaObject referencing the field
103 virtual DtLuaObject operator[](int index);
104 //! \brief Gets the number of elements in the table
105 //! \return The number of elements in the table
106 virtual int tableSize();
107
108 //! \brief Gets all string keys in the table
109 //! \return Vector of all string keys in the table
110 std::vector<std::string> keys();
111 //! \brief Sets a field value by name
112 //! \tparam T The C++ type of the value to set
113 //! \param name The name of the field to set
114 //! \param val The value to set the field to
115 //! \throw std::string if the object is invalid or not a table
116 template <typename T>
117 void setField(const std::string& name, const T& val);
118
119 //! \brief Sets a field value by numeric index
120 //! \tparam T The C++ type of the value to set
121 //! \param index The numeric index of the field to set
122 //! \param val The value to set the field to
123 template <typename T>
124 void setField(int index, const T& val);
125 //! @}
126
127 //! \brief Gets the Lua state associated with this object
128 //! \return Pointer to the Lua state
129 virtual lua_State* state();
130
131 //! \brief Serializes the object to a string representation
132 //! \return String representation of the Lua object
133 virtual std::string serialize();
134
135 //! \brief Checks if this object is valid
136 //! \return True if the object is valid, false otherwise
137 //!
138 //! An object is valid if it has a valid Lua state and reference
139 virtual bool isValid() const;
140
141protected:
142 //! \brief Retrieves a named item from the table and pushes it onto the stack
143 //! \param name The name of the item to retrieve
144 //! \param resolveDots If true, handles dotted notation for nested tables
145 //! \return True if the item was found and pushed, false otherwise
146 virtual bool getItemOnStack(const std::string& name, bool resolveDots);
147
148 //! \brief Retrieves an indexed item from the table and pushes it onto the stack
149 //! \param index The numeric index of the item to retrieve
150 //! \return True if the item was found and pushed, false otherwise
151 virtual bool getItemOnStack(int index);
152
153 //! \brief Sets a table field with values already on the Lua stack
154 //! \param index The stack index of the table
155 //!
156 //! This method expects the key and value to already be on the stack
157 virtual void setTable(int index);
158
159 //! \brief Reference to the Lua object
161
162 //! \brief Pointer to the Lua state
163 lua_State* myState;
164};
165
166} // namespace makVre
167
168#include "vreUtil/luaState.h"
169
170template <typename RT>
172{
173 if (isValid() == false)
174 {
175 throw "Cannot set a field on a non-valid table";
176 }
177
178 DtLuaStackCleaner cleaner(*myState);
180 push();
181 return state.get<RT>(-1);
182};
183
184template <typename T>
185void makVre::DtLuaObject::setField(const std::string& name, const T& val)
186{
187 if (isValid() == false)
188 {
189 throw "Cannot set a field on a non-valid table";
190 }
191
192 if (myType != SCRIPT_TABLE)
193 {
194 LOG_FATAL("Lua") << "Cannot set field in non-table type" << std::endl;
195 return;
196 }
197
198 // use a stack cleaner to reset the stack after this function
199 DtLuaStackCleaner cleaner(*myState);
200
201 // In DtLuaState, the DtLuaState(lua_State& L) constructor (called below) doesnt actually copy, the state is pointing
202 // to myState.
203 // Also in this class, there is a flag call myNeedToCloseState which actually deletes the lua state.
204 // The constructor used above sets this flag to false. So when the localstate gets deleted at the end of this
205 // function, it does not call lua_close().
206 DtLuaState localState(*myState);
207
208 push(); // get the table on the stack
209
210 // TPC: This is a short hand way to call lua_push{boolean|string|number|...}
211 // It is still pushing to the current state (myState) but we are using helper functions.
212 // see luaEncoderDecoder.h
213 localState.push(name); // push the key name on the stack
214 localState.push(val); // push the value on the stack
215
216 // lua_settable(state(), -3);
217 setTable(-3);
218};
219
220template <typename T>
221void makVre::DtLuaObject::setField(int index, const T& val)
222{
223 if (isValid() == false)
224 {
225 LOG_WARN("Lua") << "Cannot set a field on a non-valid table" << std::endl;
226 return;
227 }
228
229 if (myType != SCRIPT_TABLE)
230 {
231 LOG_WARN("Lua") << "Cannot set field in non-table type" << std::endl;
232 return;
233 }
234
235 // use a stack cleaner to reset the stack after this function
236 DtLuaStackCleaner cleaner(*myState);
237
238 // In DtLuaState, the DtLuaState(lua_State& L) constructor (called below) doesnt actually copy, the state is pointing
239 // to myState.
240 // Also in this class, there is a flag call myNeedToCloseState which actually deletes the lua state.
241 // The constructor used above sets this flag to false. So when the localstate gets deleted at the end of this
242 // function, it does not call lua_close().
243 DtLuaState localState(*myState);
244
245 push(); // get the table on the stack
246
247 // TPC: This is a short hand way to call lua_push{boolean|string|number|...}
248 // It is still pushing to the current state (myState) but we are using helper functions.
249 // see luaEncoderDecoder.h
250 localState.push(index); // push the key index on the stack
251 localState.push(val); // push the value on the stack
252
253 // lua_settable(state(), -3);
254 setTable(-3);
255};
DtLuaObject & operator=(const DtLuaObject &orig)
Assignment operator.
virtual DtLuaObject operator[](int index)
Gets a field by numeric index.
virtual lua_State * state()
Gets the Lua state associated with this object.
DtLuaObject(lua_State &state, int index)
Constructor from Lua stack value.
DtLuaReference * myReference
Reference to the Lua object.
Definition luaObject.h:160
void setField(const std::string &name, const T &val)
Sets a field value by name.
Definition luaObject.h:185
virtual void push() const
Pushes this object onto the Lua stack.
virtual bool isValid() const
Checks if this object is valid.
virtual void setTable(int index)
Sets a table field with values already on the Lua stack.
virtual std::string serialize()
Serializes the object to a string representation.
virtual bool hasField(const std::string &name, bool resolveDots=true)
Checks if the table has a field with the given name.
virtual bool getItemOnStack(int index)
Retrieves an indexed item from the table and pushes it onto the stack.
virtual ~DtLuaObject() override
Virtual destructor.
virtual bool getItemOnStack(const std::string &name, bool resolveDots)
Retrieves a named item from the table and pushes it onto the stack.
DtLuaObject()
Default constructor.
std::vector< std::string > keys()
Gets all string keys in the table.
virtual bool hasField(int index)
Checks if the table has a field at the given numeric index.
RT get()
Gets the value of this object converted to a C++ type.
Definition luaObject.h:171
virtual int tableSize()
Gets the number of elements in the table.
virtual DtLuaObject operator[](std::string name)
Gets a field by name.
lua_State * myState
Pointer to the Lua state.
Definition luaObject.h:163
DtLuaObject(const DtLuaObject &orig)
Copy constructor.
virtual bool operator==(const DtLuaObject &rhs)
Equality comparison operator.
Manages references to Lua objects through the Lua registry.
Definition luaReference.h:28
A utility class for automatically cleaning the Lua stack.
Definition luaStackCleaner.h:28
Class for managing a Lua state and providing high-level operations.
Definition luaState.h:43
void push(const T &data)
Pushes a C++ value onto the Lua stack.
Definition luaState.h:236
@ SCRIPT_TABLE
Table reference.
Definition luaValue.h:45
DtLuaValue()
Default constructor.
ScriptDataTypeEnum myType
The type of the stored value.
Definition luaValue.h:187
Defines export macros for the VREngage Utility library.
#define UTIL_DLL
Export/import macro for non-Windows platforms.
Definition export.h:39
Provides logging functionality with various severity levels and channels.
#define LOG_WARN(channel)
Macro to log a warning message to log files.
Definition logger.h:69
#define LOG_FATAL(channel)
Macro to log a fatal message to log files.
Definition logger.h:64
Provides a RAII mechanism for automatically cleaning the Lua stack.
Provides an interface for interacting with a Lua state in VREngage.
Provides a C++ wrapper for Lua values.
Include export definitions for this library.
Definition glsVreMessageUtil.h:49