Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
SirLynix committed Sep 12, 2024
1 parent dc508ba commit 5ad23e1
Show file tree
Hide file tree
Showing 17 changed files with 152 additions and 59 deletions.
37 changes: 29 additions & 8 deletions include/CommonLib/Components/ClassInstanceComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,46 @@
#define TSOM_COMMONLIB_COMPONENTS_CLASSINSTANCECOMPONENT_HPP

#include <CommonLib/EntityProperties.hpp>
#include <NazaraUtils/MovablePtr.hpp>
#include <NazaraUtils/Signal.hpp>
#include <string_view>
#include <vector>

namespace tsom
{
class EntityClass;

struct TSOM_COMMONLIB_API ClassInstanceComponent
class TSOM_COMMONLIB_API ClassInstanceComponent
{
std::vector<EntityProperty> properties;
const EntityClass* entityClass;
public:
using PropertyUpdateSignal = Nz::Signal<Nz::UInt32, const EntityProperty&>;

template<EntityPropertyType Property> auto GetProperty(std::size_t propertyIndex) const;
template<EntityPropertyType Property> auto GetProperty(std::string_view propertyName) const;
ClassInstanceComponent(const EntityClass* entityClass);
ClassInstanceComponent(const ClassInstanceComponent&) = delete;
ClassInstanceComponent(ClassInstanceComponent&&) noexcept = default;
~ClassInstanceComponent() = default;

Nz::UInt32 GetPropertyIndex(std::string_view propertyName) const;
Nz::UInt32 FindPropertyIndex(std::string_view propertyName) const;

template<EntityPropertyType Property, typename T> void UpdateProperty(std::size_t propertyIndex, T&& value);
template<EntityPropertyType Property, typename T> void UpdateProperty(std::string_view propertyName, T&& value);
inline const EntityClass* GetClass() const;
inline const EntityProperty& GetProperty(Nz::UInt32 propertyIndex) const;
template<EntityPropertyType Property> auto GetProperty(Nz::UInt32 propertyIndex) const;
template<EntityPropertyType Property> auto GetProperty(std::string_view propertyName) const;

Nz::UInt32 GetPropertyIndex(std::string_view propertyName) const;

inline void UpdateProperty(Nz::UInt32 propertyIndex, EntityProperty&& value);
template<EntityPropertyType Property, typename T> void UpdateProperty(Nz::UInt32 propertyIndex, T&& value);
template<EntityPropertyType Property, typename T> void UpdateProperty(std::string_view propertyName, T&& value);

ClassInstanceComponent& operator=(const ClassInstanceComponent&) = delete;
ClassInstanceComponent& operator=(ClassInstanceComponent&&) noexcept = default;

NazaraSignal(OnPropertyUpdate, ClassInstanceComponent* /*classInstance*/, Nz::UInt32 /*propertyIndex*/, const EntityProperty& /*newValue*/);

private:
std::vector<EntityProperty> m_properties;
Nz::MovablePtr<const EntityClass> m_entityClass;
};
}

Expand Down
29 changes: 23 additions & 6 deletions include/CommonLib/Components/ClassInstanceComponent.inl
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,22 @@

namespace tsom
{
inline const EntityClass* ClassInstanceComponent::GetClass() const
{
return m_entityClass;
}

inline const EntityProperty& ClassInstanceComponent::GetProperty(Nz::UInt32 propertyIndex) const
{
assert(propertyIndex < m_properties.size());
return m_properties[propertyIndex];
}

template<EntityPropertyType Property>
auto ClassInstanceComponent::GetProperty(std::size_t propertyIndex) const
auto ClassInstanceComponent::GetProperty(Nz::UInt32 propertyIndex) const
{
assert(propertyIndex < properties.size());
return std::get<EntityPropertySingleValue<Property>>(properties[propertyIndex]);
assert(propertyIndex < m_properties.size());
return std::get<EntityPropertySingleValue<Property>>(m_properties[propertyIndex].value);
}

template<EntityPropertyType Property>
Expand All @@ -19,11 +30,17 @@ namespace tsom
return GetProperty<Property>(GetPropertyIndex(propertyName));
}

inline void ClassInstanceComponent::UpdateProperty(Nz::UInt32 propertyIndex, EntityProperty&& value)
{
assert(propertyIndex < m_properties.size());
OnPropertyUpdate(this, propertyIndex, value);
m_properties[propertyIndex] = std::move(value);
}

template<EntityPropertyType Property, typename T>
void ClassInstanceComponent::UpdateProperty(std::size_t propertyIndex, T&& value)
void ClassInstanceComponent::UpdateProperty(Nz::UInt32 propertyIndex, T&& value)
{
assert(propertyIndex < properties.size());
std::get<EntityPropertySingleValue<Property>>(properties[propertyIndex]) = std::forward<T>(value);
return UpdateProperty(propertyIndex, EntityPropertySingleValue<Property>(std::forward<T>(value)));
}

template<EntityPropertyType Property, typename T>
Expand Down
2 changes: 0 additions & 2 deletions include/CommonLib/EntityClass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ namespace tsom
inline const Property& GetProperty(Nz::UInt32 propertyIndex) const;
inline Nz::UInt32 GetPropertyCount() const;

ClassInstanceComponent& SetupEntity(entt::handle entity) const;

EntityClass& operator=(const EntityClass&) = delete;
EntityClass& operator=(EntityClass&&) noexcept = default;

Expand Down
1 change: 1 addition & 0 deletions include/CommonLib/Protocol/PacketList.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ TSOM_NETWORK_PACKET(EntitiesCreation)
TSOM_NETWORK_PACKET(EntitiesDelete)
TSOM_NETWORK_PACKET(EntitiesStateUpdate)
TSOM_NETWORK_PACKET(EntityEnvironmentUpdate)
TSOM_NETWORK_PACKET(EntityPropertyUpdate)
TSOM_NETWORK_PACKET(EnvironmentCreate)
TSOM_NETWORK_PACKET(EnvironmentDestroy)
TSOM_NETWORK_PACKET(EnvironmentUpdate)
Expand Down
9 changes: 9 additions & 0 deletions include/CommonLib/Protocol/Packets.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,14 @@ namespace tsom
Helper::EnvironmentId newEnvironmentId;
};

struct EntityPropertyUpdate
{
Nz::UInt16 tickIndex;
Helper::EntityId entity;
CompressedUnsigned<Nz::UInt32> propertyIndex;
EntityProperty propertyValue;
};

struct EnvironmentCreate
{
Nz::UInt16 tickIndex;
Expand Down Expand Up @@ -325,6 +333,7 @@ namespace tsom
TSOM_COMMONLIB_API void Serialize(PacketSerializer& serializer, EntitiesDelete& data);
TSOM_COMMONLIB_API void Serialize(PacketSerializer& serializer, EntitiesStateUpdate& data);
TSOM_COMMONLIB_API void Serialize(PacketSerializer& serializer, EntityEnvironmentUpdate& data);
TSOM_COMMONLIB_API void Serialize(PacketSerializer& serializer, EntityPropertyUpdate& data);
TSOM_COMMONLIB_API void Serialize(PacketSerializer& serializer, EnvironmentCreate& data);
TSOM_COMMONLIB_API void Serialize(PacketSerializer& serializer, EnvironmentDestroy& data);
TSOM_COMMONLIB_API void Serialize(PacketSerializer& serializer, EnvironmentUpdate& data);
Expand Down
2 changes: 2 additions & 0 deletions include/ServerLib/SessionVisibilityHandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ namespace tsom
inline void MoveEnvironment(ServerEnvironment& environment, const EnvironmentTransform& transform);

inline void UpdateControlledEntity(entt::handle entity, CharacterController* controller);
inline void UpdateEntityProperty(entt::handle entity, Nz::UInt32 propertyIndex);
void UpdateEntityEnvironment(ServerEnvironment& newEnvironment, entt::handle oldEntity, entt::handle newEntity);
inline void UpdateLastInputIndex(InputIndex inputIndex);
inline void UpdateRootEnvironment(ServerEnvironment& environment);
Expand Down Expand Up @@ -137,6 +138,7 @@ namespace tsom

tsl::hopscotch_map<entt::handle, EntityId, HandlerHasher> m_entityIndices;
tsl::hopscotch_map<entt::handle, CreateEntityData, HandlerHasher> m_createdEntities;
tsl::hopscotch_map<entt::handle, Nz::UInt32, HandlerHasher> m_propertyUpdatedEntities;
tsl::hopscotch_map<entt::handle, ChunkNetworkMap, HandlerHasher> m_chunkNetworkMaps;
tsl::hopscotch_map<const ServerEnvironment*, EnvironmentId> m_environmentIndices;
tsl::hopscotch_set<entt::handle, HandlerHasher> m_deletedEntities;
Expand Down
6 changes: 6 additions & 0 deletions include/ServerLib/SessionVisibilityHandler.inl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in LICENSE

#include <NazaraUtils/Algorithm.hpp>
#include "SessionVisibilityHandler.hpp"

namespace tsom
{
Expand Down Expand Up @@ -78,6 +79,11 @@ namespace tsom
m_movingEntities.erase(m_controlledEntity);
}

inline void SessionVisibilityHandler::UpdateEntityProperty(entt::handle entity, Nz::UInt32 propertyIndex)
{
m_propertyUpdatedEntities[entity] |= propertyIndex;
}

inline void SessionVisibilityHandler::UpdateLastInputIndex(InputIndex inputIndex)
{
m_lastInputIndex = inputIndex;
Expand Down
10 changes: 8 additions & 2 deletions include/ServerLib/Systems/NetworkedEntitiesSystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@
#define TSOM_SERVERLIB_SYSTEMS_NETWORKEDENTITIESSYSTEM_HPP

#include <ServerLib/Export.hpp>
#include <CommonLib/Components/ClassInstanceComponent.hpp>
#include <ServerLib/SessionVisibilityHandler.hpp>
#include <Nazara/Core/Time.hpp>
#include <NazaraUtils/FunctionRef.hpp>
#include <NazaraUtils/TypeList.hpp>
#include <entt/entt.hpp>
#include <tsl/hopscotch_map.h>
#include <tsl/hopscotch_set.h>

namespace tsom
Expand Down Expand Up @@ -46,8 +48,12 @@ namespace tsom
void CreateEntity(SessionVisibilityHandler& visibility, entt::handle entity, const SessionVisibilityHandler::CreateEntityData& createData) const;
void OnNetworkedDestroy(entt::registry& registry, entt::entity entity);

tsl::hopscotch_set<entt::entity> m_movingEntities;
tsl::hopscotch_set<entt::entity> m_networkedEntities;
struct EntityData
{
NazaraSlot(ClassInstanceComponent, OnPropertyUpdate, onPropertyUpdate);
};

tsl::hopscotch_map<entt::entity, EntityData> m_networkedEntities;
entt::observer m_networkedConstructObserver;
entt::scoped_connection m_disabledConstructConnection;
entt::scoped_connection m_networkedDestroyConnection;
Expand Down
5 changes: 2 additions & 3 deletions src/ClientLib/ClientSessionHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,14 +252,13 @@ namespace tsom
std::string entityClassName = GetSession()->GetStringStore().GetString(entityData.entityClass);
if (const EntityClass* entityClass = m_entityRegistry.FindClass(entityClassName))
{
entityClass->SetupEntity(entity);
auto& entityClassData = entity.get<ClassInstanceComponent>();
auto& entityInstance = entity.emplace<ClassInstanceComponent>(entityClass);

std::size_t networkedPropertyIndex = 0;
for (Nz::UInt32 i = 0; i < entityClass->GetPropertyCount(); ++i)
{
if (entityClass->GetProperty(i).isNetworked)
entityClassData.properties[i] = entityData.properties[networkedPropertyIndex++];
entityInstance.UpdateProperty(i, std::move(entityData.properties[networkedPropertyIndex++]));
}

entityClass->ActivateEntity(entity);
Expand Down
17 changes: 16 additions & 1 deletion src/CommonLib/Components/ClassInstanceComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,24 @@

namespace tsom
{
ClassInstanceComponent::ClassInstanceComponent(const EntityClass* entityClass) :
m_entityClass(entityClass)
{
std::size_t propertyCount = entityClass->GetPropertyCount();

m_properties.reserve(propertyCount);
for (std::size_t i = 0; i < propertyCount; ++i)
m_properties.emplace_back(entityClass->GetProperty(i).defaultValue);
}

Nz::UInt32 ClassInstanceComponent::FindPropertyIndex(std::string_view propertyName) const
{
return m_entityClass->FindProperty(propertyName);
}

Nz::UInt32 ClassInstanceComponent::GetPropertyIndex(std::string_view propertyName) const
{
Nz::UInt32 propertyIndex = entityClass->FindProperty(propertyName);
Nz::UInt32 propertyIndex = FindPropertyIndex(propertyName);
if (propertyIndex == EntityClass::InvalidIndex)
throw std::runtime_error(fmt::format("invalid property {}", propertyName));

Expand Down
13 changes: 1 addition & 12 deletions src/CommonLib/EntityClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,8 @@ namespace tsom

void EntityClass::ActivateEntity(entt::handle entity) const
{
assert(entity.get<ClassInstanceComponent>().entityClass == this);
assert(entity.get<ClassInstanceComponent>().GetClass() == this);
if (m_callbacks.onInit)
m_callbacks.onInit(entity);
}

ClassInstanceComponent& EntityClass::SetupEntity(entt::handle entity) const
{
auto& entityInstance = entity.emplace<ClassInstanceComponent>();
entityInstance.entityClass = this;
entityInstance.properties.reserve(m_properties.size());
for (const auto& property : m_properties)
entityInstance.properties.emplace_back(property.defaultValue);

return entityInstance;
}
}
8 changes: 8 additions & 0 deletions src/CommonLib/Protocol/Packets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,14 @@ namespace tsom
serializer &= data.newEnvironmentId;
}

TSOM_COMMONLIB_API void Serialize(PacketSerializer& serializer, EntityPropertyUpdate& data)
{
serializer &= data.tickIndex;
serializer &= data.entity;
serializer &= data.propertyIndex;
serializer &= data.propertyValue;
}

void Serialize(PacketSerializer& serializer, EnvironmentCreate& data)
{
serializer &= data.tickIndex;
Expand Down
12 changes: 6 additions & 6 deletions src/CommonLib/Scripting/EntityScriptingLibrary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,25 +169,25 @@ namespace tsom
entt::handle entity = AssertScriptEntity(entityTable);

auto& classComponent = entity.get<ClassInstanceComponent>();
Nz::UInt32 propertyIndex = classComponent.entityClass->FindProperty(propertyName);
Nz::UInt32 propertyIndex = classComponent.FindPropertyIndex(propertyName);
if (propertyIndex == EntityClass::InvalidIndex)
TriggerLuaArgError(L, 2, fmt::format("invalid property {}", propertyName));

sol::state_view state(L);
return TranslatePropertyToLua(state, classComponent.properties[propertyIndex]);
return TranslatePropertyToLua(state, classComponent.GetProperty(propertyIndex));
});

entityMetatable["UpdateProperty"] = LuaFunction([this](sol::this_state L, sol::table entityTable, std::string_view propertyName, sol::object value)
{
entt::handle entity = AssertScriptEntity(entityTable);

auto& classComponent = entity.get<ClassInstanceComponent>();
Nz::UInt32 propertyIndex = classComponent.entityClass->FindProperty(propertyName);
auto& classInstance = entity.get<ClassInstanceComponent>();
Nz::UInt32 propertyIndex = classInstance.FindPropertyIndex(propertyName);
if (propertyIndex == EntityClass::InvalidIndex)
TriggerLuaArgError(L, 2, fmt::format("invalid property {}", propertyName));

const auto& property = classComponent.entityClass->GetProperty(propertyIndex);
classComponent.properties[propertyIndex] = TranslatePropertyFromLua(value, property.type, property.isArray);
const auto& property = classInstance.GetClass()->GetProperty(propertyIndex);
classInstance.UpdateProperty(propertyIndex, TranslatePropertyFromLua(value, property.type, property.isArray));
});
}

Expand Down
2 changes: 1 addition & 1 deletion src/ServerLib/ServerPlanetEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace tsom

const EntityClass* planetClass = serverInstance.GetEntityRegistry().FindClass("planet");

auto& entityInstance = planetClass->SetupEntity(m_planetEntity);
auto& entityInstance = m_planetEntity.emplace<ClassInstanceComponent>(planetClass);
entityInstance.UpdateProperty<EntityPropertyType::Float>("CellSize", 1.f);
entityInstance.UpdateProperty<EntityPropertyType::Float>("CornerRadius", 16.f);
entityInstance.UpdateProperty<EntityPropertyType::Float>("Gravity", 9.81f);
Expand Down
2 changes: 1 addition & 1 deletion src/ServerLib/ServerShipEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace tsom

const EntityClass* shipClass = serverInstance.GetEntityRegistry().FindClass("ship");

auto& entityInstance = shipClass->SetupEntity(m_shipEntity);
auto& entityInstance = m_shipEntity.emplace<ClassInstanceComponent>(shipClass);
entityInstance.UpdateProperty<EntityPropertyType::Float>("CellSize", 1.f);

shipClass->ActivateEntity(m_shipEntity);
Expand Down
23 changes: 21 additions & 2 deletions src/ServerLib/SessionVisibilityHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ namespace tsom
// Schedule deletion
m_deletedEntities.emplace(entity);
}
m_movingEntities.erase(entity);
}

void SessionVisibilityHandler::DestroyEnvironment(ServerEnvironment& environment)
Expand Down Expand Up @@ -167,6 +166,12 @@ namespace tsom
if (m_movingEntities.erase(oldEntity) > 0)
m_movingEntities.insert(newEntity);

if (auto it = m_propertyUpdatedEntities.find(oldEntity); it != m_propertyUpdatedEntities.end())
{
m_propertyUpdatedEntities[newEntity] = it->second;
m_propertyUpdatedEntities.erase(it);
}

auto it = m_entityIndices.find(oldEntity);
EntityId entityIndex = it.value();
m_entityIndices.erase(it);
Expand Down Expand Up @@ -448,6 +453,18 @@ namespace tsom
m_environmentUpdates.clear();
}

if (!m_propertyUpdatedEntities.empty())
{
for (auto&& [entity, propertyFlags] : m_propertyUpdatedEntities)
{
EntityId entityIndex = Nz::Retrieve(m_entityIndices, entity);

Packets::EntityPropertyUpdate propertyUpdatePacket;
propertyUpdatePacket.entity = entityIndex;
}
m_propertyUpdatedEntities.clear();
}

Packets::EntitiesStateUpdate stateUpdate;
stateUpdate.tickIndex = tickIndex;
stateUpdate.lastInputIndex = m_lastInputIndex;
Expand Down Expand Up @@ -497,7 +514,6 @@ namespace tsom

m_createdEntities.erase(entityData.entity);
m_deletedEntities.erase(entityData.entity);
m_movingEntities.erase(entityData.entity);
m_entityIndices.erase(entityData.entity);
m_freeEntityIds.Set(entityIndex, true);

Expand Down Expand Up @@ -590,6 +606,9 @@ namespace tsom

void SessionVisibilityHandler::HandleEntityDestruction(entt::handle entity)
{
m_movingEntities.erase(entity);
m_propertyUpdatedEntities.erase(entity);

// handle chunks owned by this entity if any
if (auto it = m_chunkNetworkMaps.find(entity); it != m_chunkNetworkMaps.end())
{
Expand Down
Loading

0 comments on commit 5ad23e1

Please sign in to comment.