73 lines
1.9 KiB
C++
73 lines
1.9 KiB
C++
|
|
#include "luasnap.hpp"
|
|
#include "luastack.hpp"
|
|
#include <iostream>
|
|
#include <cassert>
|
|
#include <sstream>
|
|
|
|
|
|
LuaSnap::LuaSnap() {
|
|
state_ = luaL_newstate();
|
|
LuaStack LS(state_);
|
|
LS.rawset(LuaRegistry, "persist", LuaNewTable);
|
|
LS.rawset(LuaRegistry, "unpersist", LuaNewTable);
|
|
}
|
|
|
|
LuaSnap::~LuaSnap() {
|
|
std::cerr << "LuaSnap destructor not implemented yet" << std::endl;
|
|
}
|
|
|
|
bool LuaSnap::have_snapshot() const {
|
|
return !snapshot_.empty();
|
|
}
|
|
|
|
static void oss_writer(lua_State *L, const void *p, size_t sz, void *ud) {
|
|
std::ostringstream *oss = (std::ostringstream *)ud;
|
|
oss->write((const char *)p, sz);
|
|
}
|
|
|
|
void LuaSnap::snapshot() {
|
|
// Snapshot and the lua stack should both be empty.
|
|
assert(snapshot_.empty());
|
|
assert(lua_gettop(state_) == 0);
|
|
|
|
// lua variables that we'll need.
|
|
LuaVar key, value;
|
|
LuaRet permstable, regcopy;
|
|
LuaStack LS(state_, permstable, regcopy, key, value);
|
|
|
|
// Construct a copy of the registry table.
|
|
LS.set(regcopy, LuaNewTable);
|
|
LS.set(key, LuaNil);
|
|
while (LS.next(LuaRegistry, key, value) != 0) {
|
|
LS.rawset(regcopy, key, value);
|
|
}
|
|
|
|
// Remove certain things from the copy.
|
|
LS.rawset(regcopy, LUA_RIDX_MAINTHREAD, LuaNil);
|
|
LS.rawset(regcopy, "persist", LuaNil);
|
|
LS.rawset(regcopy, "unpersist", LuaNil);
|
|
LS.rawset(regcopy, "world", LuaNil);
|
|
LS.rawset(regcopy, "gui", LuaNil);
|
|
LS.result();
|
|
|
|
// Get the permanents table from the registry.
|
|
LS.rawget(permstable, LuaRegistry, "persist");
|
|
|
|
// When we call 'LS.result', this should leave the
|
|
// permstable and the regcopy on the stack.
|
|
LS.result();
|
|
assert(lua_gettop(state_) == 2);
|
|
|
|
// Call eris to dump the state to an ostringstream,
|
|
// then save the result.
|
|
std::ostringstream oss;
|
|
eris_dump(state_, oss_writer, (void *)&oss);
|
|
snapshot_ = oss.str();
|
|
}
|
|
|
|
void LuaSnap::rollback() {
|
|
assert(!snapshot_.empty());
|
|
}
|
|
|