More work on diff xmit, not finished yet
This commit is contained in:
@@ -98,6 +98,14 @@ Tangible *World::tangible_get(int64_t id) {
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Tangible*> World::tangible_get_all(const std::vector<int64_t> &ids) {
|
||||
std::vector<Tangible*> result(ids.size());
|
||||
for (int i = 0; i < int(ids.size()); i++) {
|
||||
result[i] = tangible_get(ids[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Tangible *World::tangible_get(lua_State *L, int idx) {
|
||||
Tangible *result = nullptr;
|
||||
int top = lua_gettop(L);
|
||||
@@ -144,16 +152,16 @@ void World::tangible_delete(lua_State *L, int64_t id) {
|
||||
LS.result();
|
||||
}
|
||||
|
||||
std::vector<int64_t> World::get_near(int64_t player_id, float radius, bool exclude_nowhere) {
|
||||
util::IdVector World::get_near(int64_t player_id, float radius, bool exclude_nowhere) {
|
||||
Tangible *player = tangible_get(player_id);
|
||||
if (player == nullptr) {
|
||||
return std::vector<int64_t>();
|
||||
return IdVector();
|
||||
}
|
||||
|
||||
// Find out where's the center of the world.
|
||||
const AnimStep &aqback = player->anim_queue_.back();
|
||||
if (exclude_nowhere && (aqback.plane() == "nowhere")) {
|
||||
return std::vector<int64_t>();
|
||||
return IdVector();
|
||||
}
|
||||
|
||||
return plane_map_.scan_radius(aqback.plane(), aqback.xyz().x, aqback.xyz().y, radius, player_id);
|
||||
@@ -486,6 +494,124 @@ void World::rollback() {
|
||||
deserialize(&snapshot_);
|
||||
}
|
||||
|
||||
void World::difference_transmit(int64_t actor_id, World *master, StreamBuffer *sb) {
|
||||
StreamBuffer tsb;
|
||||
|
||||
diff_actor_essentials(actor_id, master, &tsb);
|
||||
tsb.copy_into(sb);
|
||||
patch_actor_essentials(&tsb);
|
||||
|
||||
diff_visible_animations(actor_id, master, &tsb);
|
||||
tsb.copy_into(sb);
|
||||
patch_visible_animations(&tsb);
|
||||
}
|
||||
|
||||
void World::diff_actor_essentials(int64_t actor_id, World *master, StreamBuffer *sb) {
|
||||
Tangible *s_actor = tangible_get(actor_id);
|
||||
Tangible *m_actor = master->tangible_get(actor_id);
|
||||
assert(s_actor != nullptr);
|
||||
assert(m_actor != nullptr);
|
||||
sb->write_int64(actor_id);
|
||||
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);
|
||||
s_actor->update_plane_item();
|
||||
}
|
||||
|
||||
void World::diff_visible_animations(int64_t actor_id, World *master, StreamBuffer *sb) {
|
||||
// Get the list of tangibles visible in either model.
|
||||
util::IdVector visible = PlaneMap::sort_union_id_vectors(
|
||||
master->get_near(actor_id, 100.0, true),
|
||||
this->get_near(actor_id, 100.0, true));
|
||||
|
||||
// Some tangibles may be missing in the master, some may be missing in the sync.
|
||||
std::vector<Tangible *> m_visible = tangible_get_all(visible);
|
||||
std::vector<Tangible *> s_visible = tangible_get_all(visible);
|
||||
assert(m_visible.size() == s_visible.size());
|
||||
|
||||
// For each tangible missing in the synchronous model, send the
|
||||
// necessary information to create the tangible.
|
||||
sb->write_int32(0);
|
||||
int count_pos = sb->total_writes();
|
||||
int count = 0;
|
||||
for (int i = 0; i < int(s_visible.size()); i++) {
|
||||
Tangible *mt = m_visible[i];
|
||||
Tangible *st = s_visible[i];
|
||||
if (st == nullptr) {
|
||||
count += 1;
|
||||
sb->write_int64(mt->id());
|
||||
mt->anim_queue_.serialize(sb);
|
||||
}
|
||||
}
|
||||
sb->overwrite_int32(count_pos, count);
|
||||
|
||||
// For each tangible present in the synchronous model that doesn't
|
||||
// exist in the master model, send command to delete it.
|
||||
sb->write_int32(0);
|
||||
count_pos = sb->total_writes();
|
||||
count = 0;
|
||||
for (int i = 0; i < int(s_visible.size()); i++) {
|
||||
Tangible *mt = m_visible[i];
|
||||
Tangible *st = s_visible[i];
|
||||
if (mt == nullptr) {
|
||||
count += 1;
|
||||
sb->write_int64(st->id());
|
||||
}
|
||||
}
|
||||
sb->overwrite_int32(count_pos, count);
|
||||
|
||||
// For each tangible present in both models, compare
|
||||
// the animation queues.
|
||||
sb->write_int32(0);
|
||||
count_pos = sb->total_writes();
|
||||
count = 0;
|
||||
for (int i = 0; i < int(s_visible.size()); i++) {
|
||||
Tangible *mt = m_visible[i];
|
||||
Tangible *st = s_visible[i];
|
||||
if ((mt != nullptr) && (st != nullptr)) {
|
||||
if (st->anim_queue_.need_patch(mt->anim_queue_)) {
|
||||
count++;
|
||||
sb->write_int64(st->id());
|
||||
st->anim_queue_.diff(mt->anim_queue_, sb);
|
||||
}
|
||||
}
|
||||
}
|
||||
sb->overwrite_int32(count_pos, count);
|
||||
}
|
||||
|
||||
void World::patch_visible_animations(StreamBuffer *sb) {
|
||||
// Receive create messages.
|
||||
int count = sb->read_int32();
|
||||
for (int i = 0; i < count; i++) {
|
||||
int64_t id = sb->read_int64();
|
||||
Tangible *t = tangible_make(state(), id, false);
|
||||
t->anim_queue_.deserialize(sb);
|
||||
t->update_plane_item();
|
||||
}
|
||||
|
||||
// Receive delete messages
|
||||
count = sb->read_int32();
|
||||
for (int i = 0; i < count; i++) {
|
||||
int64_t id = sb->read_int64();
|
||||
tangible_delete(state(), id);
|
||||
}
|
||||
|
||||
// Receive update messages
|
||||
count = sb->read_int32();
|
||||
for (int i = 0; i < count; i++) {
|
||||
int64_t id = sb->read_int64();
|
||||
Tangible *t = tangible_get(id);
|
||||
assert(t != nullptr);
|
||||
t->anim_queue_.patch(sb);
|
||||
}
|
||||
}
|
||||
|
||||
LuaDefine(tangible_animstate, "c") {
|
||||
LuaArg tanobj;
|
||||
LuaRet graphic, plane, x, y, z, facing;
|
||||
|
||||
Reference in New Issue
Block a user