From b6cb96c11c4aadcbee9d351a8267df4a4b5a91fc Mon Sep 17 00:00:00 2001 From: aozhiwei Date: Tue, 30 Mar 2021 11:46:18 +0800 Subject: [PATCH] add weakptr --- server/gameserver/creature.cc | 5 +++ server/gameserver/creature.h | 4 ++ server/gameserver/weakptr.cc | 70 +++++++++++++++++++++++++++++++++++ server/gameserver/weakptr.h | 36 ++++++++++++++++++ 4 files changed, 115 insertions(+) create mode 100644 server/gameserver/weakptr.cc create mode 100644 server/gameserver/weakptr.h diff --git a/server/gameserver/creature.cc b/server/gameserver/creature.cc index e6bcea3..2e024aa 100644 --- a/server/gameserver/creature.cc +++ b/server/gameserver/creature.cc @@ -66,6 +66,11 @@ void InternalShot(Creature* c, } } +Creature::Creature():MoveableEntity() +{ + weak_ptr_chunk_.Set(this); +} + Creature::~Creature() { for (auto& pair : skill_hash_) { diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index cfd9928..1755e04 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -1,5 +1,6 @@ #pragma once +#include "weakptr.h" #include "moveableentity.h" #include "buff.h" @@ -32,6 +33,7 @@ class Creature : public MoveableEntity bool need_sync_active_player = false; + Creature(); virtual ~Creature() override; virtual void Initialize() override; bool HasBuffEffect(int buff_effect_id); @@ -92,6 +94,7 @@ class Creature : public MoveableEntity int GetActionTargetId() { return action_target_id; } void TouchProperTargets(std::function func); + CreatureWeakPtrChunk* GetWeakPtrChunk() { return &weak_ptr_chunk_; }; private: @@ -119,6 +122,7 @@ protected: int action_target_id = 0; private: + CreatureWeakPtrChunk weak_ptr_chunk_; std::array buff_attr_abs_ = {}; std::array buff_attr_rate_ = {}; std::array buff_effect_ = {}; diff --git a/server/gameserver/weakptr.cc b/server/gameserver/weakptr.cc new file mode 100644 index 0000000..71d38af --- /dev/null +++ b/server/gameserver/weakptr.cc @@ -0,0 +1,70 @@ +#include "precompile.h" +#include "weakptr.h" +#include "creature.h" + +CreatureWeakPtrChunk::CreatureWeakPtrChunk() +{ + INIT_LIST_HEAD(&ptrs_); +} + +CreatureWeakPtrChunk::~CreatureWeakPtrChunk() +{ + Clear(); +} + +void CreatureWeakPtrChunk::Clear() +{ + struct CreatureWeakPtr *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 CreatureWeakPtrChunk::Set(Creature* c) +{ + ptr_ = c; +} + +CreatureWeakPtr::CreatureWeakPtr() +{ + INIT_LIST_HEAD(&entry_); +} + +CreatureWeakPtr::~CreatureWeakPtr() +{ + Reset(); +} + +void CreatureWeakPtr::Reset() +{ + if (ptr_) { + Detach(); + } +} + +Creature* CreatureWeakPtr::Get() +{ + return ptr_; +} + +void CreatureWeakPtr::Attach(Creature* c) +{ + Reset(); + CreatureWeakPtrChunk* chunk = c->GetWeakPtrChunk(); + if (c != chunk->ptr_) { + abort(); + } + ptr_ = c; + list_add_tail(&entry_, &chunk->ptrs_); +} + +void CreatureWeakPtr::Detach() +{ + if (ptr_) { + ptr_ = nullptr; + list_del_init(&entry_); + } +} diff --git a/server/gameserver/weakptr.h b/server/gameserver/weakptr.h new file mode 100644 index 0000000..62a82f9 --- /dev/null +++ b/server/gameserver/weakptr.h @@ -0,0 +1,36 @@ +#pragma once + +class Creature; + +class CreatureWeakPtrChunk +{ + public: + + CreatureWeakPtrChunk(); + ~CreatureWeakPtrChunk(); + void Clear(); + void Set(Creature* c); + + private: + Creature* ptr_ = nullptr; + list_head ptrs_; + friend class CreatureWeakPtr; +}; + +class CreatureWeakPtr +{ + public: + + CreatureWeakPtr(); + ~CreatureWeakPtr(); + void Reset(); + Creature* Get(); + void Attach(Creature* c); + void Detach(); + + private: + Creature* ptr_ = nullptr; + list_head entry_; + + friend class CreatureWeakPtrChunk; +};