Skip to content

Commit

Permalink
fully decouple LuaRef and PropertyMap from Pi::
Browse files Browse the repository at this point in the history
the trick here is that we store a pointer to the serializer in the
registry so we can always get it with just the lua context, without
having to bounce through Pi:: for it

ended up mostly reverting @4ef4c004
  • Loading branch information
robn committed Feb 5, 2015
1 parent 0a517db commit 85c1f2f
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 40 deletions.
4 changes: 2 additions & 2 deletions src/CargoBody.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
void CargoBody::Save(Serializer::Writer &wr, Space *space)
{
DynamicBody::Save(wr, space);
Pi::luaSerializer->WrLuaRef(m_cargo, wr);
m_cargo.Save(wr);
wr.Float(m_hitpoints);
wr.Float(m_selfdestructTimer);
wr.Bool(m_hasSelfdestruct);
Expand All @@ -26,7 +26,7 @@ void CargoBody::Save(Serializer::Writer &wr, Space *space)
void CargoBody::Load(Serializer::Reader &rd, Space *space)
{
DynamicBody::Load(rd, space);
Pi::luaSerializer->RdLuaRef(m_cargo, rd);
m_cargo.Load(rd);
Init();
m_hitpoints = rd.Float();
m_selfdestructTimer = rd.Float();
Expand Down
60 changes: 60 additions & 0 deletions src/LuaRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,63 @@ void LuaRef::PushCopyToStack() const {
lua_remove(m_lua, -2);
}

void LuaRef::Save(Serializer::Writer &wr)
{
assert(m_lua && m_id != LUA_NOREF);

LUA_DEBUG_START(m_lua);

lua_getfield(m_lua, LUA_REGISTRYINDEX, "PiSerializer");
LuaSerializer *serializer = static_cast<LuaSerializer*>(lua_touserdata(m_lua, -1));
lua_pop(m_lua, 1);

if (!serializer) {
LUA_DEBUG_END(m_lua, 0);
return;
}

std::string out;
PushCopyToStack();
serializer->pickle(m_lua, -1, out);
lua_pop(m_lua, 1);
wr.String(out);

LUA_DEBUG_END(m_lua, 0);
}

void LuaRef::Load(Serializer::Reader &rd)
{
std::string pickled = rd.String();

LUA_DEBUG_START(m_lua);

lua_getfield(m_lua, LUA_REGISTRYINDEX, "PiSerializer");
LuaSerializer *serializer = static_cast<LuaSerializer*>(lua_touserdata(m_lua, -1));
lua_pop(m_lua, 1);

if (!serializer) {
LUA_DEBUG_END(m_lua, 0);
return;
}

serializer->unpickle(m_lua, pickled.c_str()); // loaded
lua_getfield(m_lua, LUA_REGISTRYINDEX, "PiLuaRefLoadTable"); // loaded, reftable
lua_pushvalue(m_lua, -2); // loaded, reftable, copy
lua_gettable(m_lua, -2); // loaded, reftable, luaref
// Check whether this table has been referenced before
if (lua_isnil(m_lua, -1)) {
// If not, mark it as referenced
*this = LuaRef(m_lua, -3);
lua_pushvalue(m_lua, -3);
lua_pushlightuserdata(m_lua, this);
lua_settable(m_lua, -4);
} else {
LuaRef *origin = static_cast<LuaRef *>(lua_touserdata(m_lua, -1));
*this = *origin;
}

lua_pop(m_lua, 3);

LUA_DEBUG_END(m_lua, 0);
}

3 changes: 3 additions & 0 deletions src/LuaRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ class LuaRef {

bool IsValid() const { return m_lua && m_id != LUA_NOREF; }

void Save(Serializer::Writer &wr);
void Load(Serializer::Reader &rd);

private:
lua_State * m_lua;
int m_id;
Expand Down
41 changes: 6 additions & 35 deletions src/LuaSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,9 @@ const char *LuaSerializer::unpickle(lua_State *l, const char *pos)
void LuaSerializer::InitTableRefs() {
lua_State *l = Lua::manager->GetLuaState();

lua_pushlightuserdata(l, this);
lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializer");

lua_newtable(l);
lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");

Expand All @@ -463,6 +466,9 @@ void LuaSerializer::InitTableRefs() {
void LuaSerializer::UninitTableRefs() {
lua_State *l = Lua::manager->GetLuaState();

lua_pushnil(l);
lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializer");

lua_pushnil(l);
lua_setfield(l, LUA_REGISTRYINDEX, "PiSerializerTableRefs");

Expand Down Expand Up @@ -550,41 +556,6 @@ void LuaSerializer::Unserialize(Serializer::Reader &rd)
LUA_DEBUG_END(l, 0);
}

void LuaSerializer::WrLuaRef(LuaRef &ref, Serializer::Writer &wr)
{
lua_State *l = Lua::manager->GetLuaState();
std::string out;
LUA_DEBUG_START(l);
ref.PushCopyToStack();
pickle(l, -1, out);
lua_pop(l, 1);
wr.String(out);
LUA_DEBUG_END(l, 0);
}

void LuaSerializer::RdLuaRef(LuaRef &ref, Serializer::Reader &rd)
{
lua_State *l = Lua::manager->GetLuaState();
std::string pickled = rd.String();
unpickle(l, pickled.c_str()); // loaded
lua_getfield(l, LUA_REGISTRYINDEX, "PiLuaRefLoadTable"); // loaded, reftable
lua_pushvalue(l, -2); // loaded, reftable, copy
lua_gettable(l, -2); // loaded, reftable, luaref
// Check whether this table has been referenced before
if (lua_isnil(l, -1)) {
// If not, mark it as referenced
ref = LuaRef(l, -3);
lua_pushvalue(l, -3);
lua_pushlightuserdata(l, this);
lua_settable(l, -4);
} else {
LuaRef *origin = static_cast<LuaRef *>(lua_touserdata(l, -1));
ref = *origin;
}

lua_pop(l, 3);
}

int LuaSerializer::l_register(lua_State *l)
{
LUA_DEBUG_START(l);
Expand Down
2 changes: 2 additions & 0 deletions src/LuaSerializer.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

class LuaSerializer : public DeleteEmitter {
friend class LuaObject<LuaSerializer>;
friend void LuaRef::Save(Serializer::Writer &wr);
friend void LuaRef::Load(Serializer::Reader &rd);

public:
void Serialize(Serializer::Writer &wr);
Expand Down
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@ uitest_SOURCES = \
LuaConstants.cpp \
LuaRef.cpp \
LuaPropertiedObject.cpp \
LuaSerializer.cpp \
PngWriter.cpp \
EnumStrings.cpp \
PropertyMap.cpp \
Expand Down
6 changes: 3 additions & 3 deletions src/PropertyMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include "PropertyMap.h"
#include "LuaUtils.h"
#include "Pi.h"
#include "LuaSerializer.h"

PropertyMap::PropertyMap(LuaManager *lua)
{
Expand Down Expand Up @@ -31,11 +31,11 @@ void PropertyMap::PushLuaTable()

void PropertyMap::Save(Serializer::Writer &wr)
{
Pi::luaSerializer->WrLuaRef(m_table, wr);
m_table.Save(wr);
}


void PropertyMap::Load(Serializer::Reader &rd)
{
Pi::luaSerializer->RdLuaRef(m_table, rd);
m_table.Load(rd);
}

0 comments on commit 85c1f2f

Please sign in to comment.