Working on unit tests for class world
This commit is contained in:
@@ -31,7 +31,7 @@ World::World(util::WorldType wt) {
|
||||
world_type_ = wt;
|
||||
|
||||
// Initialize the ID allocator in master mode.
|
||||
if (wt == util::WORLD_TYPE_MASTER) {
|
||||
if (wt == util::WORLD_TYPE_MASTER || wt == util::WORLD_TYPE_STANDALONE) {
|
||||
id_global_pool_.init_master();
|
||||
} else {
|
||||
id_global_pool_.init_synch();
|
||||
@@ -50,19 +50,11 @@ World::World(util::WorldType wt) {
|
||||
// Create the tangibles table in the registry.
|
||||
LS.rawset(LuaRegistry, "tangibles", LuaNewTable);
|
||||
|
||||
// Initialize the SourceDB
|
||||
// Initialize the SourceDB. At this stage, the sourcedb is
|
||||
// empty, so it's just populating the lua builtins.
|
||||
source_db_.init(state());
|
||||
source_db_.rebuild();
|
||||
|
||||
// Do standalone initializations.
|
||||
if (world_type_ == util::WORLD_TYPE_STANDALONE) {
|
||||
// Load the lua source from disk then rebuild the environment.
|
||||
source_db_.update();
|
||||
source_db_.rebuild();
|
||||
|
||||
// Run unit tests.
|
||||
source_db_.run_unittests();
|
||||
}
|
||||
LS.result();
|
||||
assert (stack_is_clear());
|
||||
}
|
||||
@@ -161,6 +153,29 @@ void World::tangible_delete(lua_State *L, int64_t id) {
|
||||
LS.result();
|
||||
}
|
||||
|
||||
|
||||
void World::tangible_walkto(int64_t id, int64_t animid, float x, float y) {
|
||||
Tangible *t = tangible_get(id);
|
||||
assert(animid != 0);
|
||||
assert(t != nullptr);
|
||||
AnimStep step;
|
||||
step.set_action("walkto");
|
||||
step.set_x(x);
|
||||
step.set_y(y);
|
||||
t->anim_queue_.add(animid, step);
|
||||
}
|
||||
|
||||
|
||||
std::string World::tangible_ids_debug_string() const {
|
||||
util::IdVector idv;
|
||||
for (const auto &pair : tangibles_) {
|
||||
idv.push_back(pair.first);
|
||||
}
|
||||
std::sort(idv.begin(), idv.end());
|
||||
return util::id_vector_debug_string(idv);
|
||||
}
|
||||
|
||||
|
||||
util::IdVector World::get_near(int64_t player_id, float radius, bool exclude_nowhere) const {
|
||||
const Tangible *player = tangible_get(player_id);
|
||||
if (player == nullptr) {
|
||||
@@ -177,6 +192,12 @@ util::IdVector World::get_near(int64_t player_id, float radius, bool exclude_now
|
||||
}
|
||||
|
||||
Tangible *World::tangible_make(lua_State *L, int64_t id, bool pushdb) {
|
||||
// Get a state if we don't already have one.
|
||||
if (L == nullptr) {
|
||||
L = state();
|
||||
assert(!pushdb);
|
||||
}
|
||||
|
||||
LuaVar tangibles, metatab;
|
||||
LuaRet database;
|
||||
LuaStack LS(L, tangibles, database, metatab);
|
||||
@@ -446,7 +467,7 @@ void World::run_scheduled_threads(int64_t clk) {
|
||||
void World::serialize(StreamBuffer *sb) {
|
||||
assert(stack_is_clear());
|
||||
assert(redirects_.empty());
|
||||
int64_t wc0 = sb->total_writes();
|
||||
// int64_t wc0 = sb->total_writes();
|
||||
lua_snap_.serialize(sb);
|
||||
id_global_pool_.serialize(sb);
|
||||
thread_sched_.serialize(sb);
|
||||
@@ -455,8 +476,8 @@ void World::serialize(StreamBuffer *sb) {
|
||||
sb->write_int64(p.first);
|
||||
p.second->serialize(sb);
|
||||
}
|
||||
int64_t wc1 = sb->total_writes();
|
||||
std::cerr << "World serialized to " << wc1-wc0 << " bytes." << std::endl;
|
||||
// int64_t wc1 = sb->total_writes();
|
||||
// std::cerr << "World serialized to " << wc1-wc0 << " bytes." << std::endl;
|
||||
assert(stack_is_clear());
|
||||
}
|
||||
|
||||
@@ -506,13 +527,12 @@ void World::rollback() {
|
||||
void World::difference_transmit(int64_t actor_id, const World *master, StreamBuffer *sb) {
|
||||
StreamBuffer tsb;
|
||||
|
||||
// Get the actor in both models.
|
||||
// Get the actor in both models. s_actor may be nil.
|
||||
const Tangible *s_actor = tangible_get(actor_id);
|
||||
const Tangible *m_actor = master->tangible_get(actor_id);
|
||||
assert(s_actor != nullptr);
|
||||
assert(m_actor != nullptr);
|
||||
|
||||
// Pass one: update the actor essentials.
|
||||
// Pass one: update the actor essentials. Create actor if doesn't exist.
|
||||
assert(tsb.at_eof());
|
||||
diff_actor_essentials(m_actor, s_actor, &tsb);
|
||||
tsb.copy_into(sb);
|
||||
@@ -523,7 +543,7 @@ void World::difference_transmit(int64_t actor_id, const World *master, StreamBuf
|
||||
util::IdVector visible = util::sort_union_id_vectors(
|
||||
master->get_near(actor_id, 100.0, true),
|
||||
this->get_near(actor_id, 100.0, true));
|
||||
TanVector m_visible = tangible_get_all(visible);
|
||||
TanVector m_visible = master->tangible_get_all(visible);
|
||||
TanVector s_visible = tangible_get_all(visible);
|
||||
assert(m_visible.size() == s_visible.size());
|
||||
|
||||
@@ -549,17 +569,33 @@ void World::difference_transmit(int64_t actor_id, const World *master, StreamBuf
|
||||
assert(tsb.at_eof());
|
||||
}
|
||||
|
||||
void World::apply_differences(StreamBuffer *sb) {
|
||||
patch_actor_essentials(sb);
|
||||
patch_visible_animations(sb);
|
||||
}
|
||||
|
||||
void World::diff_actor_essentials(const Tangible *m_actor, const Tangible *s_actor, StreamBuffer *sb) {
|
||||
sb->write_int64(m_actor->id());
|
||||
s_actor->id_player_pool_.diff(m_actor->id_player_pool_, sb);
|
||||
s_actor->anim_queue_.diff(m_actor->anim_queue_, sb);
|
||||
if (s_actor == nullptr) {
|
||||
m_actor->id_player_pool_.serialize(sb);
|
||||
m_actor->anim_queue_.serialize(sb);
|
||||
} else {
|
||||
s_actor->id_player_pool_.diff(m_actor->id_player_pool_, sb);
|
||||
s_actor->anim_queue_.diff(m_actor->anim_queue_, sb);
|
||||
}
|
||||
}
|
||||
|
||||
void World::patch_actor_essentials(StreamBuffer *sb) {
|
||||
int64_t actor_id = sb->read_int64();
|
||||
Tangible *s_actor = tangible_get(actor_id);
|
||||
s_actor->id_player_pool_.patch(sb);
|
||||
s_actor->anim_queue_.patch(sb);
|
||||
if (s_actor == nullptr) {
|
||||
s_actor = tangible_make(nullptr, actor_id, false);
|
||||
s_actor->id_player_pool_.deserialize(sb);
|
||||
s_actor->anim_queue_.deserialize(sb);
|
||||
} else {
|
||||
s_actor->id_player_pool_.patch(sb);
|
||||
s_actor->anim_queue_.patch(sb);
|
||||
}
|
||||
s_actor->update_plane_item();
|
||||
}
|
||||
|
||||
@@ -575,7 +611,7 @@ void World::diff_visible_animations(const TanVector &mvis, const TanVector &svis
|
||||
if (st == nullptr) {
|
||||
count += 1;
|
||||
sb->write_int64(mt->id());
|
||||
mt->anim_queue_.serialize_size_and_steps(sb);
|
||||
mt->anim_queue_.serialize(sb);
|
||||
}
|
||||
}
|
||||
sb->overwrite_int32(count_pos, count);
|
||||
@@ -620,7 +656,7 @@ void World::patch_visible_animations(StreamBuffer *sb) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
int64_t id = sb->read_int64();
|
||||
Tangible *t = tangible_make(state(), id, false);
|
||||
t->anim_queue_.deserialize_size_and_steps(sb);
|
||||
t->anim_queue_.deserialize(sb);
|
||||
t->update_plane_item();
|
||||
}
|
||||
|
||||
@@ -791,3 +827,30 @@ LuaDefine(world_getregistry, "f") {
|
||||
lua_pushvalue(L, LUA_REGISTRYINDEX);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool worlds_identical(const std::unique_ptr<World> &w1, const std::unique_ptr<World> &w2) {
|
||||
StreamBuffer sbw1, sbw2;
|
||||
w1->serialize(&sbw1);
|
||||
w2->serialize(&sbw2);
|
||||
return sbw1.contents_equal(&sbw2);
|
||||
}
|
||||
|
||||
LuaDefine(unittests_world, "c") {
|
||||
std::unique_ptr<World> m, ss, cs;
|
||||
StreamBuffer sb;
|
||||
|
||||
m.reset(new World(util::WORLD_TYPE_MASTER));
|
||||
ss.reset(new World(util::WORLD_TYPE_S_SYNC));
|
||||
cs.reset(new World(util::WORLD_TYPE_C_SYNC));
|
||||
|
||||
m->tangible_make(0, 123, false);
|
||||
m->tangible_make(0, 345, false);
|
||||
LuaAssertStrEq(L, m->tangible_ids_debug_string(), "123,345");
|
||||
|
||||
ss->difference_transmit(123, m.get(), &sb);
|
||||
cs->apply_differences(&sb);
|
||||
LuaAssertStrEq(L, ss->tangible_ids_debug_string(), "123,345");
|
||||
LuaAssert(L, worlds_identical(ss, cs));
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user