Skip to content

Commit

Permalink
refact(syncable): clarify interface
Browse files Browse the repository at this point in the history
  • Loading branch information
Insineer committed Oct 8, 2019
1 parent 6fa30d9 commit b570353
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 27 deletions.
10 changes: 6 additions & 4 deletions OSS13 Server/Sources/World/Objects/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,12 @@ void Object::AddObject(Object *obj) {
if (obj->GetHolder()) {
if (!obj->GetHolder()->RemoveObject(obj))
return;
} else if (obj->GetTile())
} else if (obj->GetTile()) {
obj->GetTile()->RemoveObject(obj);
obj->DropUpdateState();
} else {
obj->ResetChanges();
}


content.push_back(obj);
obj->holder = this;
Expand All @@ -161,10 +164,9 @@ bool Object::RemoveObject(Object *obj) {
if (obj->IsChanged()) {
auto fieldsDiff = std::make_shared<network::protocol::FieldsDiff>();
fieldsDiff->objId = obj->ID();
fieldsDiff->fieldsChanges = obj->GetChanges();
fieldsDiff->fieldsChanges = obj->PopChanges();
GetTile()->AddDiff(std::move(fieldsDiff), obj);
}
obj->DropUpdateState();

obj->setTile(nullptr);
obj->holder = nullptr;
Expand Down
10 changes: 6 additions & 4 deletions OSS13 Server/Sources/World/Tile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ bool Tile::RemoveObject(Object *obj) {
if (obj->IsChanged()) {
auto fieldsDiff = std::make_shared<network::protocol::FieldsDiff>();
fieldsDiff->objId = obj->ID();
fieldsDiff->fieldsChanges = obj->GetChanges();
fieldsDiff->fieldsChanges = obj->PopChanges();
AddDiff(std::move(fieldsDiff), obj);
}
obj->DropUpdateState();

if (removeObject(obj)) {
auto diff = std::make_shared<network::protocol::RemoveDiff>();
diff->objId = obj->ID();
Expand Down Expand Up @@ -193,15 +193,17 @@ void Tile::PlaceTo(Object *obj) {
if (obj->IsChanged()) {
auto fieldsDiff = std::make_shared<network::protocol::FieldsDiff>();
fieldsDiff->objId = obj->ID();
fieldsDiff->fieldsChanges = obj->GetChanges();
fieldsDiff->fieldsChanges = obj->PopChanges();
lastTile->AddDiff(std::move(fieldsDiff), obj);
}
auto relocateAwayDiff = std::make_shared<network::protocol::RelocateAwayDiff>();
relocateAwayDiff->objId = obj->ID();
relocateAwayDiff->newCoords = pos;
lastTile->AddDiff(relocateAwayDiff, obj);
} else {
obj->ResetChanges();
}
obj->DropUpdateState();

addObject(obj);

auto relocateDiff = std::make_shared<network::protocol::RelocateDiff>();
Expand Down
3 changes: 1 addition & 2 deletions OSS13 Server/Sources/World/World.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,8 @@ void World::Update(std::chrono::microseconds timeElapsed) {
if (object && object->GetTile() && object->IsChanged()) {
auto diff = std::make_shared<network::protocol::FieldsDiff>();
diff->objId = object->ID();
diff->fieldsChanges = object->GetChanges();
diff->fieldsChanges = object->PopChanges();
object->GetTile()->AddDiff(std::move(diff), object.get());
object->DropUpdateState();
}
}
}
Expand Down
19 changes: 7 additions & 12 deletions SharedLibrary/Sources/Shared/Network/Syncable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,51 +9,46 @@ void GeneralSyncField::setChanged() { changed = true; syncable->changed = true;

} // namespace detail

SyncableChanges Syncable::GetChanges() {
SyncableChanges Syncable::PopChanges() {
SyncableChanges changes;
changes.archive.SetMode(Archive::Mode::Input);
std::size_t changedCount = 0;
for (std::size_t i = 0; i < fieldsOffsets.size(); i++) {
if (getField(i)->changed)
changedCount++;
}
EXPECT_WITH_MSG(changedCount, "Empty SyncableChanges are created!");
changes.archive << sf::Int32(changedCount);

for (std::size_t i = 0; i < fieldsOffsets.size(); i++) {
if (getField(i)->changed) {
changes.archive << sf::Int32(i);
getField(i)->Serialize(changes.archive);
getField(i)->changed = false;
}
}
changed = false;
return changes;
}

void Syncable::AmendChanges(SyncableChanges &&changes) {
changes.archive.SetMode(Archive::Mode::Output);
sf::Int32 changedCount;
changes.archive >> changedCount;
do {
while (changedCount--) {
sf::Int32 fieldNumber;
changes.archive >> fieldNumber;
changes.archive >> *getField(std::size_t(fieldNumber));
} while (--changedCount);
};
}

void Syncable::DropUpdateState() {
void Syncable::ResetChanges() {
for (std::size_t i = 0; i < fieldsOffsets.size(); i++)
getField(i)->changed = false;
changed = false;
}

bool Syncable::IsChanged() {
bool t = false;
for (std::size_t i = 0; i < fieldsOffsets.size(); i++) {
if (getField(i)->changed)
t = true;
}
EXPECT(t || !changed);
return changed;
return changed;
}

void Syncable::Serialize(Archive &ar) {
Expand Down
6 changes: 3 additions & 3 deletions SharedLibrary/Sources/Shared/Network/Syncable.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct SyncField : public detail::GeneralSyncField {
SyncField &operator=(const T &value) { this->value = value; setChanged(); return *this; }
operator const T &() const { return value; }

T &GetValue() { return value; };
const T &GetValue() { return value; };

void Serialize(Archive &ar) final {
uf::ISerializable::Serialize(ar);
Expand Down Expand Up @@ -74,10 +74,10 @@ DEFINE_SERIALIZABLE_END
struct Syncable : public uf::ISerializable {
friend detail::GeneralSyncField;

SyncableChanges GetChanges();
SyncableChanges PopChanges();
void AmendChanges(SyncableChanges &&changes);
void ResetChanges();

void DropUpdateState();
bool IsChanged();

void Serialize(Archive &ar) final;
Expand Down
23 changes: 21 additions & 2 deletions SharedLibrary/Tests/Sources/Syncable_Tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,31 @@ DEFINE_SYNCABLE(TestSyncable)
}
DEFINE_SYNCABLE_END

TEST(Syncable, test) {
TEST(Syncable, IsChangedReturnsTrueAfterFieldChange) {
TestSyncable testSyncable;
testSyncable.a = 12345;

CHECK(testSyncable.IsChanged());
}

TEST(Syncable, CorrectValuesAfterAmend) {
TestSyncable testSyncable;
testSyncable.a = 12345;
testSyncable.b = "test string";

auto changes = testSyncable.GetChanges();
auto changes = testSyncable.PopChanges();

TestSyncable otherSyncable;
otherSyncable.AmendChanges(std::move(changes));

CHECK(testSyncable.a.GetValue() == otherSyncable.a.GetValue());
CHECK(testSyncable.b.GetValue() == otherSyncable.b.GetValue());
}

TEST(Syncable, AmendDefaultValues) {
TestSyncable testSyncable;

auto changes = testSyncable.PopChanges();

TestSyncable otherSyncable;
otherSyncable.AmendChanges(std::move(changes));
Expand Down

0 comments on commit b570353

Please sign in to comment.