cLuaState: Added support for optional params and AStringMap values.
This commit is contained in:
parent
e9d1a942d1
commit
89c9c6fe46
@ -341,6 +341,33 @@ void cLuaState::cStackTable::ForEachArrayElement(std::function<bool(cLuaState &
|
||||
|
||||
|
||||
|
||||
void cLuaState::cStackTable::ForEachElement(std::function<bool(cLuaState & a_LuaState)> a_ElementCallback) const
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
auto stackTop = lua_gettop(m_LuaState);
|
||||
#endif
|
||||
lua_pushvalue(m_LuaState, m_StackPos); // Stk: <table>
|
||||
lua_pushnil(m_LuaState); // Stk: <table> nil
|
||||
while (lua_next(m_LuaState, -2)) // Stk: <table> <key> <val>
|
||||
{
|
||||
auto shouldAbort = a_ElementCallback(m_LuaState);
|
||||
ASSERT(lua_gettop(m_LuaState) == stackTop + 3); // The element callback must not change the Lua stack below the value
|
||||
lua_pop(m_LuaState, 1); // Stk: <table> <key>
|
||||
if (shouldAbort)
|
||||
{
|
||||
// The callback wants to abort
|
||||
lua_pop(m_LuaState, 2); // Stk: empty
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Stk: <table>
|
||||
lua_pop(m_LuaState, 1); // Stk: empty
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cLuaState:
|
||||
|
||||
@ -748,6 +775,24 @@ void cLuaState::Push(const AString & a_String)
|
||||
|
||||
|
||||
|
||||
void cLuaState::Push(const AStringMap & a_Dictionary)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
|
||||
lua_createtable(m_LuaState, 0, static_cast<int>(a_Dictionary.size()));
|
||||
int newTable = lua_gettop(m_LuaState);
|
||||
for (const auto & item: a_Dictionary)
|
||||
{
|
||||
Push(item.first); // key
|
||||
Push(item.second); // value
|
||||
lua_rawset(m_LuaState, newTable);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaState::Push(const AStringVector & a_Vector)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
@ -1113,6 +1158,37 @@ bool cLuaState::GetStackValue(int a_StackPos, AString & a_Value)
|
||||
|
||||
|
||||
|
||||
bool cLuaState::GetStackValue(int a_StackPos, AStringMap & a_Value)
|
||||
{
|
||||
// Retrieve all values in a string => string dictionary table:
|
||||
if (!lua_istable(m_LuaState, a_StackPos))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
cStackTable tbl(*this, a_StackPos);
|
||||
bool isValid = true;
|
||||
tbl.ForEachElement([&isValid, &a_Value](cLuaState & a_LuaState)
|
||||
{
|
||||
AString key, val;
|
||||
if (a_LuaState.GetStackValues(-2, key, val))
|
||||
{
|
||||
a_Value[key] = val;
|
||||
}
|
||||
else
|
||||
{
|
||||
isValid = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
return isValid;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaState::GetStackValue(int a_StackPos, bool & a_ReturnedVal)
|
||||
{
|
||||
a_ReturnedVal = (tolua_toboolean(m_LuaState, a_StackPos, a_ReturnedVal ? 1 : 0) > 0);
|
||||
|
@ -309,6 +309,24 @@ public:
|
||||
typedef UniquePtr<cTableRef> cTableRefPtr;
|
||||
|
||||
|
||||
/** Represents a parameter that is optional - calling a GetStackValue() with this object will not fail if the value on the Lua stack is nil.
|
||||
Note that the GetStackValue() will still fail if the param is present but of a different type.
|
||||
The class itself is just a marker so that the template magic will select the correct GetStackValue() overload. */
|
||||
template <typename T>
|
||||
class cOptionalParam
|
||||
{
|
||||
public:
|
||||
explicit cOptionalParam(T & a_Dest):
|
||||
m_Dest(a_Dest)
|
||||
{
|
||||
}
|
||||
|
||||
T & GetDest(void) { return m_Dest; }
|
||||
|
||||
protected:
|
||||
T & m_Dest;
|
||||
};
|
||||
|
||||
/** A dummy class that's used only to delimit function args from return values for cLuaState::Call() */
|
||||
class cRet
|
||||
{
|
||||
@ -475,6 +493,7 @@ public:
|
||||
|
||||
// Push a const value onto the stack (keep alpha-sorted):
|
||||
void Push(const AString & a_String);
|
||||
void Push(const AStringMap & a_Dictionary);
|
||||
void Push(const AStringVector & a_Vector);
|
||||
void Push(const cCraftingGrid * a_Grid);
|
||||
void Push(const cCraftingRecipe * a_Recipe);
|
||||
@ -508,6 +527,7 @@ public:
|
||||
// Returns whether value was changed
|
||||
// Enum values are checked for their allowed values and fail if the value is not assigned.
|
||||
bool GetStackValue(int a_StackPos, AString & a_Value);
|
||||
bool GetStackValue(int a_StackPos, AStringMap & a_Value);
|
||||
bool GetStackValue(int a_StackPos, bool & a_Value);
|
||||
bool GetStackValue(int a_StackPos, cCallback & a_Callback);
|
||||
bool GetStackValue(int a_StackPos, cCallbackPtr & a_Callback);
|
||||
@ -549,6 +569,17 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Retrieves an optional value on the stack - doesn't fail if the stack contains nil instead of the value. */
|
||||
template <typename T>
|
||||
bool GetStackValue(int a_StackPos, cOptionalParam<T> && a_ReturnedVal)
|
||||
{
|
||||
if (lua_isnoneornil(m_LuaState, a_StackPos))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return GetStackValue(a_StackPos, a_ReturnedVal.GetDest());
|
||||
}
|
||||
|
||||
/** Pushes the named value in the table at the top of the stack.
|
||||
a_Name may be a path containing multiple table levels, such as "cChatColor.Blue".
|
||||
If the value is found, it is pushed on top of the stack and the returned cStackValue is valid.
|
||||
@ -606,14 +637,14 @@ public:
|
||||
}
|
||||
|
||||
/** Retrieves a list of values from the Lua stack, starting at the specified index. */
|
||||
template <typename T, typename... Args>
|
||||
inline bool GetStackValues(int a_StartStackPos, T & a_Ret, Args &&... args)
|
||||
template <typename Arg1, typename... Args>
|
||||
inline bool GetStackValues(int a_StartStackPos, Arg1 && a_Arg1, Args &&... args)
|
||||
{
|
||||
if (!GetStackValue(a_StartStackPos, a_Ret))
|
||||
if (!GetStackValue(a_StartStackPos, std::forward<Arg1>(a_Arg1)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return GetStackValues(a_StartStackPos + 1, args...);
|
||||
return GetStackValues(a_StartStackPos + 1, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/** Returns true if the specified parameters on the stack are of the specified usertable type; also logs warning if not. Used for static functions */
|
||||
|
Loading…
Reference in New Issue
Block a user