From b9dce95940f443d6cfb78b51f5b32e9ad8eb442d Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Tue, 10 Aug 2021 08:55:19 +0000 Subject: [PATCH] add EntityWeakPtr --- server/gameserver/creature.h | 1 - server/gameserver/entity.cc | 17 +++++- server/gameserver/entity.h | 8 +++ server/gameserver/weakptr.cc | 108 +++++++++++++++++++++++++++++++++++ server/gameserver/weakptr.h | 39 +++++++++++++ 5 files changed, 171 insertions(+), 2 deletions(-) diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index 5c704ea..55c8128 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -1,6 +1,5 @@ #pragma once -#include "weakptr.h" #include "moveableentity.h" #include "buff.h" #include "trigger.h" diff --git a/server/gameserver/entity.cc b/server/gameserver/entity.cc index 895718d..acaccea 100644 --- a/server/gameserver/entity.cc +++ b/server/gameserver/entity.cc @@ -10,7 +10,7 @@ Entity::Entity() { - + entity_weak_ptr_chunk_.Set(this); } Entity::~Entity() @@ -235,3 +235,18 @@ void Entity::AddClientCache(Human* hum) sync_flags->last_sync_frameno = hum->room->GetFrameNo(); } } + +EntityWeakPtr Entity::AllocEntityWeakPtr() +{ + EntityWeakPtr ptr; + ptr.Attach(this); + return ptr; +} + +EntityWeakPtr& Entity::GetEntityWeakPtrRef() +{ + if (!entity_weak_ptr_.Get()) { + entity_weak_ptr_.Attach(this); + } + return entity_weak_ptr_; +} diff --git a/server/gameserver/entity.h b/server/gameserver/entity.h index afcc601..a4f7d03 100644 --- a/server/gameserver/entity.h +++ b/server/gameserver/entity.h @@ -1,5 +1,7 @@ #pragma once +#include "weakptr.h" + namespace cs { class MFObjectPart; @@ -63,6 +65,9 @@ class Entity float GetY() { return pos_.y; } void SetX(float x) { pos_.x = x; } void SetY(float y) { pos_.y = y; } + EntityWeakPtrChunk* GetEntityWeakPtrChunk() { return &entity_weak_ptr_chunk_; }; + EntityWeakPtr AllocEntityWeakPtr(); + EntityWeakPtr& GetEntityWeakPtrRef(); protected: bool IsClientCached(Human* hum); @@ -81,6 +86,9 @@ private: EntityType_e entity_type_ = ET_None; EntitySubType_e entity_subtype_ = EST_None; + EntityWeakPtr entity_weak_ptr_; + EntityWeakPtrChunk entity_weak_ptr_chunk_; + a8::Vec2 pos_; int grid_id_ = 0; diff --git a/server/gameserver/weakptr.cc b/server/gameserver/weakptr.cc index f13d65b..473a2c6 100644 --- a/server/gameserver/weakptr.cc +++ b/server/gameserver/weakptr.cc @@ -218,3 +218,111 @@ void RoomObstacleWeakPtr::Detach() list_del_init(&entry_); } } + +EntityWeakPtrChunk::EntityWeakPtrChunk() +{ + INIT_LIST_HEAD(&ptrs_); +} + +EntityWeakPtrChunk::~EntityWeakPtrChunk() +{ + Clear(); +} + +void EntityWeakPtrChunk::Clear() +{ + struct EntityWeakPtr *weakptr, *tmp; + struct list_head ptr_list; + + list_replace_init(&ptrs_, &ptr_list); + list_for_each_entry_safe(weakptr, tmp, &ptr_list, entry_) { + weakptr->Reset(); + } +} + +void EntityWeakPtrChunk::Set(Entity* c) +{ + ptr_ = c; +} + +EntityWeakPtr::EntityWeakPtr() +{ + INIT_LIST_HEAD(&entry_); +} + +EntityWeakPtr::EntityWeakPtr(const EntityWeakPtr& x) +{ + INIT_LIST_HEAD(&entry_); + if (x.ptr_) { + Attach(x.ptr_); + } +} + +EntityWeakPtr::EntityWeakPtr(EntityWeakPtr&& x) +{ + INIT_LIST_HEAD(&entry_); + if (x.ptr_) { + Attach(x.ptr_); + x.Detach(); + } +} + +EntityWeakPtr& EntityWeakPtr::operator=(const EntityWeakPtr& x) +{ + if (ptr_) { + Detach(); + } + if (x.ptr_) { + Attach(x.ptr_); + } + return *this; +} + +EntityWeakPtr&& EntityWeakPtr::operator=(EntityWeakPtr&& x) +{ + if (ptr_) { + Detach(); + } + if (x.ptr_) { + Attach(x.ptr_); + x.Detach(); + } + abort(); + // return *this; +} + +EntityWeakPtr::~EntityWeakPtr() +{ + Reset(); +} + +void EntityWeakPtr::Reset() +{ + if (ptr_) { + Detach(); + } +} + +Entity* EntityWeakPtr::Get() +{ + return ptr_; +} + +void EntityWeakPtr::Attach(Entity* c) +{ + Reset(); + EntityWeakPtrChunk* chunk = c->GetEntityWeakPtrChunk(); + if (c != chunk->ptr_) { + abort(); + } + ptr_ = c; + list_add_tail(&entry_, &chunk->ptrs_); +} + +void EntityWeakPtr::Detach() +{ + if (ptr_) { + ptr_ = nullptr; + list_del_init(&entry_); + } +} diff --git a/server/gameserver/weakptr.h b/server/gameserver/weakptr.h index 3fb14ad..a49fdb3 100644 --- a/server/gameserver/weakptr.h +++ b/server/gameserver/weakptr.h @@ -80,3 +80,42 @@ class RoomObstacleWeakPtr friend class RoomObstacleWeakPtrChunk; }; + +class Entity; + +class EntityWeakPtrChunk +{ + public: + + EntityWeakPtrChunk(); + ~EntityWeakPtrChunk(); + void Clear(); + void Set(Entity* c); + + private: + Entity* ptr_ = nullptr; + list_head ptrs_; + friend class EntityWeakPtr; +}; + +class EntityWeakPtr +{ + public: + + EntityWeakPtr(); + EntityWeakPtr(const EntityWeakPtr& x); + EntityWeakPtr(EntityWeakPtr&& x); + EntityWeakPtr& operator=(const EntityWeakPtr& x); + EntityWeakPtr&& operator=(EntityWeakPtr&& x); + ~EntityWeakPtr(); + void Reset(); + Entity* Get(); + void Attach(Entity* c); + void Detach(); + + private: + Entity* ptr_ = nullptr; + list_head entry_; + + friend class EntityWeakPtrChunk; +};