Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use standard pairs/ipairs implementation #137

Merged
merged 6 commits into from
Oct 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Source/Core/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,9 @@ Context* GetContext(int index)
{
ContextMap::iterator i = contexts.begin();
int count = 0;

if (index >= GetNumContexts())
index = GetNumContexts() - 1;
if (index < 0 || index >= GetNumContexts())
return nullptr;

while (count < index)
{
Expand Down
106 changes: 47 additions & 59 deletions Source/Lua/ContextDocumentsProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ template<> void ExtraInit<ContextDocumentsProxy>(lua_State* L, int metatable_ind
lua_setfield(L,metatable_index,"__index");
lua_pushcfunction(L,ContextDocumentsProxy__pairs);
lua_setfield(L,metatable_index,"__pairs");
lua_pushcfunction(L,ContextDocumentsProxy__ipairs);
lua_setfield(L,metatable_index,"__ipairs");
}

int ContextDocumentsProxy__index(lua_State* L)
Expand All @@ -53,7 +51,7 @@ int ContextDocumentsProxy__index(lua_State* L)
if(type == LUA_TSTRING)
ret = proxy->owner->GetDocument(luaL_checkstring(L,2));
else
ret = proxy->owner->GetDocument((int)luaL_checkinteger(L,2));
ret = proxy->owner->GetDocument((int)luaL_checkinteger(L,2)-1);
LuaType<Document>::push(L,ret,false);
return 1;
}
Expand All @@ -62,75 +60,65 @@ int ContextDocumentsProxy__index(lua_State* L)

}

//[1] is the object, [2] is the last used key, [3] is the userdata
int ContextDocumentsProxy__pairs(lua_State* L)
struct ContextDocumentsProxyPairs
{
Document* doc = nullptr;
ContextDocumentsProxy* obj = LuaType<ContextDocumentsProxy>::check(L,1);
RMLUI_CHECK_OBJ(obj);
int* pindex = (int*)lua_touserdata(L,3);
if((*pindex) == -1)
*pindex = 0;

int num_docs = obj->owner->GetNumDocuments();
//because there can be missing indexes, make sure to continue until there
//is actually a document at the index
while((*pindex) < num_docs)
{
doc = obj->owner->GetDocument((*pindex)++);
if(doc != nullptr)
break;
}

//If we found a document
if(doc != nullptr)
static int next(lua_State* L)
{
ContextDocumentsProxy* obj = LuaType<ContextDocumentsProxy>::check(L,1);
ContextDocumentsProxyPairs* self = static_cast<ContextDocumentsProxyPairs*>(lua_touserdata(L, lua_upvalueindex(1)));
Document* doc = nullptr;
int num_docs = obj->owner->GetNumDocuments();
//because there can be missing indexes, make sure to continue until there
//is actually a document at the index
while (self->m_cur < num_docs)
{
doc = obj->owner->GetDocument(self->m_cur++);
if (doc != nullptr)
break;
}
if (doc == nullptr)
{
return 0;
}
lua_pushstring(L,doc->GetId().c_str());
LuaType<Document>::push(L,doc);
return 2;
}
else //if we were at the end and didn't find a document
static int destroy(lua_State* L)
{
lua_pushnil(L);
lua_pushnil(L);
static_cast<ContextDocumentsProxyPairs*>(lua_touserdata(L, 1))->~ContextDocumentsProxyPairs();
return 0;
}
return 2;
}

//same as __pairs, but putting an integer key instead of a string key
int ContextDocumentsProxy__ipairs(lua_State* L)
{
Document* doc = nullptr;
ContextDocumentsProxy* obj = LuaType<ContextDocumentsProxy>::check(L,1);
RMLUI_CHECK_OBJ(obj);
int* pindex = (int*)lua_touserdata(L,3);
if((*pindex) == -1)
*pindex = 0;

int num_docs = obj->owner->GetNumDocuments();
//because there can be missing indexes, make sure to continue until there
//is actually a document at the index
while((*pindex) < num_docs)
static int constructor(lua_State* L)
{
doc = obj->owner->GetDocument((*pindex)++);
if(doc != nullptr)
break;
void* storage = lua_newuserdata(L, sizeof(ContextDocumentsProxyPairs));
if (luaL_newmetatable(L, "RmlUi::Lua::ContextDocumentsProxyPairs"))
{
static luaL_Reg mt[] =
{
{"__gc", destroy},
{NULL, NULL},
};
luaL_setfuncs(L, mt, 0);
}
lua_setmetatable(L, -2);
lua_pushcclosure(L, next, 1);
new (storage) ContextDocumentsProxyPairs();
return 1;
}
ContextDocumentsProxyPairs()
: m_cur(0)
{ }
int m_cur;
};

//we found a document
if(doc != nullptr)
{
lua_pushinteger(L,(*pindex)-1);
LuaType<Document>::push(L,doc);
}
else //we got to the end and didn't find another document
{
lua_pushnil(L);
lua_pushnil(L);
}
int ContextDocumentsProxy__pairs(lua_State* L)
{
ContextDocumentsProxyPairs::constructor(L);
lua_pushvalue(L, 1);
return 2;
}


RegType<ContextDocumentsProxy> ContextDocumentsProxyMethods[] =
{
{ nullptr, nullptr },
Expand Down
1 change: 0 additions & 1 deletion Source/Lua/ContextDocumentsProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ struct ContextDocumentsProxy { Context* owner; };
template<> void ExtraInit<ContextDocumentsProxy>(lua_State* L, int metatable_index);
int ContextDocumentsProxy__index(lua_State* L);
int ContextDocumentsProxy__pairs(lua_State* L);
int ContextDocumentsProxy__ipairs(lua_State* L);

extern RegType<ContextDocumentsProxy> ContextDocumentsProxyMethods[];
extern luaL_Reg ContextDocumentsProxyGetters[];
Expand Down
34 changes: 2 additions & 32 deletions Source/Lua/ElementAttributesProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "ElementAttributesProxy.h"
#include <RmlUi/Lua/Utilities.h>
#include <RmlUi/Core/Variant.h>
#include "Pairs.h"

namespace Rml {
namespace Lua {
Expand All @@ -38,8 +39,6 @@ template<> void ExtraInit<ElementAttributesProxy>(lua_State* L, int metatable_in
lua_setfield(L,metatable_index,"__index");
lua_pushcfunction(L,ElementAttributesProxy__pairs);
lua_setfield(L,metatable_index,"__pairs");
lua_pushcfunction(L,ElementAttributesProxy__ipairs);
lua_setfield(L,metatable_index,"__ipairs");
}

int ElementAttributesProxy__index(lua_State* L)
Expand All @@ -59,40 +58,11 @@ int ElementAttributesProxy__index(lua_State* L)
return LuaType<ElementAttributesProxy>::index(L);
}

//[1] is the object, [2] is the key that was used previously, [3] is the userdata
int ElementAttributesProxy__pairs(lua_State* L)
{
ElementAttributesProxy* obj = LuaType<ElementAttributesProxy>::check(L,1);
RMLUI_CHECK_OBJ(obj);
int& pindex = *(int*)lua_touserdata(L,3);
if ((pindex) == -1)
pindex = 0;
const ElementAttributes& attributes = obj->owner->GetAttributes();

if(pindex >= 0 && pindex < (int)attributes.size())
{
auto it = attributes.begin();
for (int i = 0; i < pindex; ++i)
++it;
const String& key = it->first;
const Variant* value = &it->second;
lua_pushstring(L,key.c_str());
PushVariant(L,value);
}
else
{
lua_pushnil(L);
lua_pushnil(L);
}
return 2;
}

//Doesn't index by integer, so don't return anything
int ElementAttributesProxy__ipairs(lua_State* L)
{
lua_pushnil(L);
lua_pushnil(L);
return 2;
return MakePairs(L, obj->owner->GetAttributes());
}

RegType<ElementAttributesProxy> ElementAttributesProxyMethods[] =
Expand Down
1 change: 0 additions & 1 deletion Source/Lua/ElementAttributesProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ struct ElementAttributesProxy { Element* owner; };
template<> void ExtraInit<ElementAttributesProxy>(lua_State* L, int metatable_index);
int ElementAttributesProxy__index(lua_State* L);
int ElementAttributesProxy__pairs(lua_State* L);
int ElementAttributesProxy__ipairs(lua_State* L);

extern RegType<ElementAttributesProxy> ElementAttributesProxyMethods[];
extern luaL_Reg ElementAttributesProxyGetters[];
Expand Down
32 changes: 3 additions & 29 deletions Source/Lua/ElementChildNodesProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

#include "ElementChildNodesProxy.h"
#include "Element.h"
#include "Pairs.h"

namespace Rml {
namespace Lua {
Expand All @@ -38,8 +39,6 @@ template<> void ExtraInit<ElementChildNodesProxy>(lua_State* L, int metatable_in
lua_setfield(L,metatable_index,"__index");
lua_pushcfunction(L,ElementChildNodesProxy__pairs);
lua_setfield(L,metatable_index,"__pairs");
lua_pushcfunction(L,ElementChildNodesProxy__ipairs);
lua_setfield(L,metatable_index,"__ipairs");
}

int ElementChildNodesProxy__index(lua_State* L)
Expand All @@ -51,7 +50,7 @@ int ElementChildNodesProxy__index(lua_State* L)
ElementChildNodesProxy* obj = LuaType<ElementChildNodesProxy>::check(L,1);
RMLUI_CHECK_OBJ(obj);
int key = (int)luaL_checkinteger(L,2);
Element* child = obj->owner->GetChild(key);
Element* child = obj->owner->GetChild(key-1);
LuaType<Element>::push(L,child,false);
return 1;
}
Expand All @@ -61,32 +60,7 @@ int ElementChildNodesProxy__index(lua_State* L)

int ElementChildNodesProxy__pairs(lua_State* L)
{
//because it is only indexed by integer, just go through ipairs
return ElementChildNodesProxy__ipairs(L);
}


//[1] is the object, [2] is the key that was just used, [3] is the userdata
int ElementChildNodesProxy__ipairs(lua_State* L)
{
ElementChildNodesProxy* obj = LuaType<ElementChildNodesProxy>::check(L,1);
RMLUI_CHECK_OBJ(obj);
int* pindex = (int*)lua_touserdata(L,3);
if((*pindex) == -1) //initial value
(*pindex) = 0;
int num_children = obj->owner->GetNumChildren();
if((*pindex) < num_children)
{
lua_pushinteger(L,*pindex); //key
LuaType<Element>::push(L,obj->owner->GetChild(*pindex)); //value
(*pindex) += 1;
}
else
{
lua_pushnil(L);
lua_pushnil(L);
}
return 2;
return MakeIntPairs(L);
}

RegType<ElementChildNodesProxy> ElementChildNodesProxyMethods[] =
Expand Down
1 change: 0 additions & 1 deletion Source/Lua/ElementChildNodesProxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ struct ElementChildNodesProxy { Element* owner; };
template<> void ExtraInit<ElementChildNodesProxy>(lua_State* L, int metatable_index);
int ElementChildNodesProxy__index(lua_State* L);
int ElementChildNodesProxy__pairs(lua_State* L);
int ElementChildNodesProxy__ipairs(lua_State* L);

extern RegType<ElementChildNodesProxy> ElementChildNodesProxyMethods[];
extern luaL_Reg ElementChildNodesProxyGetters[];
Expand Down
77 changes: 43 additions & 34 deletions Source/Lua/ElementStyleProxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,6 @@ template<> void ExtraInit<ElementStyleProxy>(lua_State* L, int metatable_index)

lua_pushcfunction(L,ElementStyleProxy__pairs);
lua_setfield(L,metatable_index,"__pairs");

lua_pushcfunction(L,ElementStyleProxy__ipairs);
lua_setfield(L,metatable_index,"__ipairs");
}

int ElementStyleProxy__index(lua_State* L)
Expand Down Expand Up @@ -101,46 +98,58 @@ int ElementStyleProxy__newindex(lua_State* L)

}

//[1] is the object, [2] is the last used key, [3] is the userdata
int ElementStyleProxy__pairs(lua_State* L)
struct ElementStyleProxyPairs
{
ElementStyleProxy* obj = LuaType<ElementStyleProxy>::check(L,1);
RMLUI_CHECK_OBJ(obj);
int* pindex = (int*)lua_touserdata(L,3);
if ((*pindex) == -1)
*pindex = 0;

int i = 0;
auto it = obj->owner->IterateLocalProperties();
while (i < (*pindex) && !it.AtEnd())
{
++it;
++i;
}

if(!it.AtEnd())
static int next(lua_State* L)
{
const String& key = it.GetName();
const Property& property = it.GetProperty();
ElementStyleProxyPairs* self = static_cast<ElementStyleProxyPairs*>(lua_touserdata(L, lua_upvalueindex(1)));
if (self->m_view.AtEnd())
{
return 0;
}
const String& key = self->m_view.GetName();
const Property& property = self->m_view.GetProperty();
String val;
property.definition->GetValue(val, property);
lua_pushstring(L,key.c_str());
lua_pushstring(L,val.c_str());
lua_pushlstring(L, key.c_str(), key.size());
lua_pushlstring(L, val.c_str(), val.size());
++self->m_view;
return 2;
}
else
static int destroy(lua_State* L)
{
lua_pushnil(L);
lua_pushnil(L);
static_cast<ElementStyleProxyPairs*>(lua_touserdata(L, 1))->~ElementStyleProxyPairs();
return 0;
}
return 2;
}
static int constructor(lua_State* L, ElementStyleProxy* obj)
{
void* storage = lua_newuserdata(L, sizeof(ElementStyleProxyPairs));
if (luaL_newmetatable(L, "RmlUi::Lua::ElementStyleProxyPairs"))
{
static luaL_Reg mt[] =
{
{"__gc", destroy},
{NULL, NULL},
};
luaL_setfuncs(L, mt, 0);
}
lua_setmetatable(L, -2);
lua_pushcclosure(L, next, 1);
new (storage) ElementStyleProxyPairs(obj);
return 1;
}
ElementStyleProxyPairs(ElementStyleProxy* obj)
: m_view(obj->owner->IterateLocalProperties())
{ }
PropertiesIteratorView m_view;
};

//only indexed by string
int ElementStyleProxy__ipairs(lua_State* L)
int ElementStyleProxy__pairs(lua_State* L)
{
lua_pushnil(L);
lua_pushnil(L);
return 2;
ElementStyleProxy* obj = LuaType<ElementStyleProxy>::check(L,1);
RMLUI_CHECK_OBJ(obj);
ElementStyleProxyPairs::constructor(L, obj);
return 1;
}

RegType<ElementStyleProxy> ElementStyleProxyMethods[] =
Expand Down
Loading