World serialization done (not well-tested yet)
This commit is contained in:
@@ -229,7 +229,6 @@ void AnimQueue::serialize(StreamBuffer *sb) {
|
||||
void AnimQueue::deserialize(StreamBuffer *sb) {
|
||||
size_limit_ = sb->read_int32();
|
||||
size_t nsteps = sb->read_size();
|
||||
steps_.clear();
|
||||
steps_.resize(nsteps);
|
||||
for (size_t i = 0; i < nsteps; i++) {
|
||||
AnimStep &step = steps_[i];
|
||||
|
||||
@@ -122,21 +122,4 @@ void LuaSnap::deserialize(StreamBuffer *sb) {
|
||||
// functionality. So for now, we're sticking with this design, which doesn't
|
||||
// require us to maintain any additional code.
|
||||
|
||||
bool LuaSnap::have_snapshot() const {
|
||||
return snapshot_.write_count() != 0;
|
||||
}
|
||||
|
||||
void LuaSnap::snapshot() {
|
||||
assert(snapshot_.write_count() == 0);
|
||||
serialize(&snapshot_);
|
||||
}
|
||||
|
||||
void LuaSnap::rollback() {
|
||||
assert(snapshot_.write_count() != 0);
|
||||
deserialize(&snapshot_);
|
||||
assert(snapshot_.at_eof());
|
||||
snapshot_.clear();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
class LuaSnap {
|
||||
private:
|
||||
lua_State *state_;
|
||||
StreamBuffer snapshot_;
|
||||
|
||||
public:
|
||||
LuaSnap();
|
||||
@@ -37,22 +36,6 @@ public:
|
||||
// Restore the the lua interpreter given a serialized state.
|
||||
//
|
||||
void deserialize(StreamBuffer *sb);
|
||||
|
||||
// Return true if there's a saved snapshot.
|
||||
//
|
||||
bool have_snapshot() const;
|
||||
|
||||
// snapshot the state of the lua interpreter.
|
||||
//
|
||||
// If there is already a snapshot, this panics.
|
||||
//
|
||||
void snapshot();
|
||||
|
||||
// Rollback the lua intepreter to the snapshotted state.
|
||||
//
|
||||
// If there is no snapshot, this panics.
|
||||
//
|
||||
void rollback();
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -24,4 +24,23 @@ SchedEntry Schedule::pop() {
|
||||
schedule_.erase(schedule_.begin());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void Schedule::serialize(StreamBuffer *sb) {
|
||||
sb->write_size(schedule_.size());
|
||||
for (const SchedEntry &entry : schedule_) {
|
||||
sb->write_int64(entry.clock_);
|
||||
sb->write_int64(entry.thread_id_);
|
||||
sb->write_int64(entry.place_id_);
|
||||
}
|
||||
}
|
||||
|
||||
void Schedule::deserialize(StreamBuffer *sb) {
|
||||
schedule_.clear();
|
||||
size_t nentry = sb->read_size();
|
||||
for (size_t i = 0; i < nentry; i++) {
|
||||
int64_t clock = sb->read_int64();
|
||||
int64_t thread_id = sb->read_int64();
|
||||
int64_t place_id = sb->read_int64();
|
||||
add(clock, thread_id, place_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,15 +3,14 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <set>
|
||||
#include "streambuffer.hpp"
|
||||
|
||||
class SchedEntry {
|
||||
private:
|
||||
friend class Schedule;
|
||||
|
||||
int64_t clock_;
|
||||
int64_t thread_id_;
|
||||
int64_t place_id_;
|
||||
int func_args_;
|
||||
|
||||
public:
|
||||
int64_t clock() const { return clock_; }
|
||||
@@ -34,6 +33,9 @@ public:
|
||||
void add(int64_t clk, int64_t thid, int64_t plid);
|
||||
bool ready(int64_t clk) const;
|
||||
SchedEntry pop();
|
||||
|
||||
void serialize(StreamBuffer *sb);
|
||||
void deserialize(StreamBuffer *sb);
|
||||
};
|
||||
|
||||
#endif // SCHED_HPP
|
||||
|
||||
@@ -302,6 +302,7 @@ public:
|
||||
int64_t write_count() const;
|
||||
|
||||
// Delete all data and (if not fixed-size) free the buffer.
|
||||
// Also resets the read and write counts.
|
||||
void clear();
|
||||
|
||||
// Alloc_space and wrote_space need to be invoked together.
|
||||
|
||||
@@ -46,14 +46,11 @@ void Tangible::update_plane_item() {
|
||||
}
|
||||
|
||||
void Tangible::serialize(StreamBuffer *sb) {
|
||||
sb->write_int64(id());
|
||||
anim_queue_.serialize(sb);
|
||||
id_player_pool_.serialize(sb);
|
||||
}
|
||||
|
||||
void Tangible::deserialize(StreamBuffer *sb) {
|
||||
int64_t id = sb->read_int64();
|
||||
plane_item_.set_id(id);
|
||||
anim_queue_.deserialize(sb);
|
||||
id_player_pool_.deserialize(sb);
|
||||
update_plane_item();
|
||||
@@ -365,6 +362,60 @@ void World::run_scheduled_threads(int64_t clk) {
|
||||
LS.result();
|
||||
}
|
||||
|
||||
void World::serialize(StreamBuffer *sb) {
|
||||
int64_t wc0 = sb->write_count();
|
||||
lua_snap_.serialize(sb);
|
||||
id_global_pool_.serialize(sb);
|
||||
thread_sched_.serialize(sb);
|
||||
sb->write_size(tangibles_.size());
|
||||
for (const auto &p : tangibles_) {
|
||||
sb->write_int64(p.first);
|
||||
p.second->serialize(sb);
|
||||
}
|
||||
int64_t wc1 = sb->write_count();
|
||||
std::cerr << "World serialized to " << wc1-wc0 << " bytes." << std::endl;
|
||||
}
|
||||
|
||||
void World::deserialize(StreamBuffer *sb) {
|
||||
lua_snap_.deserialize(sb);
|
||||
id_global_pool_.deserialize(sb);
|
||||
thread_sched_.deserialize(sb);
|
||||
// Mark all tangibles for deletion by setting ID to zero.
|
||||
for (const auto &p : tangibles_) {
|
||||
p.second->plane_item_.set_id(0);
|
||||
}
|
||||
// Deserialize tangibles.
|
||||
size_t ntan = sb->read_size();
|
||||
for (size_t i = 0; i < ntan; i++) {
|
||||
int64_t id = sb->read_int64();
|
||||
std::unique_ptr<Tangible> &t = tangibles_[id];
|
||||
if (t == nullptr) {
|
||||
t.reset(new Tangible(this, id));
|
||||
} else {
|
||||
t->plane_item_.set_id(id);
|
||||
}
|
||||
t->deserialize(sb);
|
||||
}
|
||||
// Delete tangibles that didn't get deserialized.
|
||||
for (auto iter = tangibles_.begin(); iter != tangibles_.end(); ) {
|
||||
if (iter->second->plane_item_.id() == 0) {
|
||||
tangibles_.erase(iter++);
|
||||
} else {
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void World::snapshot() {
|
||||
snapshot_.clear();
|
||||
serialize(&snapshot_);
|
||||
}
|
||||
|
||||
void World::rollback() {
|
||||
assert(!snapshot_.at_eof());
|
||||
deserialize(&snapshot_);
|
||||
}
|
||||
|
||||
LuaDefine(tangible_xyz, "c") {
|
||||
LuaArg tanobj;
|
||||
LuaRet X, Y, Z;
|
||||
|
||||
@@ -18,6 +18,25 @@
|
||||
class World;
|
||||
|
||||
class Tangible {
|
||||
private:
|
||||
friend class World;
|
||||
|
||||
// Serialize and deserialize
|
||||
//
|
||||
// The tangible's ID is not serialized. When you serialize a tangible, you
|
||||
// should probably serialize the ID separately.
|
||||
//
|
||||
// The Lua portion of the tangible is not serialized here. Instead, the lua
|
||||
// portion is serialized when you serialize the lua state as a whole.
|
||||
//
|
||||
// PlaneItem is not serialized. The deserialize routine rebuilds the
|
||||
// PlaneItem from the AnimQueue.
|
||||
//
|
||||
// World pointer is not serialized.
|
||||
//
|
||||
void serialize(StreamBuffer *sb);
|
||||
void deserialize(StreamBuffer *sb);
|
||||
|
||||
public:
|
||||
// Always points back to the world model.
|
||||
World *world_;
|
||||
@@ -50,15 +69,6 @@ public:
|
||||
int64_t id() { return plane_item_.id(); }
|
||||
void be_a_player();
|
||||
void update_plane_item();
|
||||
|
||||
// Serialize and deserialize
|
||||
//
|
||||
// PlaneItem is not serialized except the ID. The deserialize routine
|
||||
// rebuilds the PlaneItem from the AnimQueue. World pointer is not
|
||||
// serialized.
|
||||
//
|
||||
void serialize(StreamBuffer *sb);
|
||||
void deserialize(StreamBuffer *sb);
|
||||
};
|
||||
|
||||
class World {
|
||||
@@ -75,6 +85,9 @@ public:
|
||||
//
|
||||
SourceDB source_db_;
|
||||
PlaneMap plane_map_;
|
||||
|
||||
// Tangibles table.
|
||||
//
|
||||
std::unordered_map<int64_t, std::unique_ptr<Tangible>> tangibles_;
|
||||
|
||||
// Thread schedule: must include every thread, except
|
||||
@@ -82,6 +95,9 @@ public:
|
||||
//
|
||||
Schedule thread_sched_;
|
||||
|
||||
// Serialized snapshot of world model.
|
||||
StreamBuffer snapshot_;
|
||||
|
||||
void run_scheduled_threads(int64_t clk);
|
||||
public:
|
||||
// Constructor.
|
||||
@@ -158,10 +174,15 @@ public:
|
||||
static void store_global_pointer(lua_State *L, World *w);
|
||||
static World *fetch_global_pointer(lua_State *L);
|
||||
|
||||
// Serialize and deserialize.
|
||||
//
|
||||
void serialize(StreamBuffer *sb);
|
||||
void deserialize(StreamBuffer *sb);
|
||||
|
||||
// Snapshot and rollback - temporary.
|
||||
//
|
||||
void snapshot() { lua_snap_.snapshot(); }
|
||||
void rollback() { lua_snap_.rollback(); }
|
||||
void snapshot();
|
||||
void rollback();
|
||||
};
|
||||
|
||||
#endif // WORLD_HPP
|
||||
|
||||
Reference in New Issue
Block a user