From 1e90dad2456f383c2624acc85ab62445440e1156 Mon Sep 17 00:00:00 2001 From: "madmaxoft@gmail.com" Date: Mon, 19 Mar 2012 09:37:10 +0000 Subject: Basic cWindow thread-safety git-svn-id: http://mc-server.googlecode.com/svn/trunk@420 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- source/cFurnaceEntity.cpp | 58 +++++++++++++++---------------------- source/cInventory.h | 11 +++++++- source/cSurvivalInventory.h | 9 ++++++ source/cWindow.cpp | 69 ++++++++++++++++++++++++++++++++++++--------- source/cWindow.h | 33 +++++++++++++++------- source/cWindowOwner.h | 15 ++++++++-- 6 files changed, 132 insertions(+), 63 deletions(-) diff --git a/source/cFurnaceEntity.cpp b/source/cFurnaceEntity.cpp index 3c4a7403d..389d4af54 100644 --- a/source/cFurnaceEntity.cpp +++ b/source/cFurnaceEntity.cpp @@ -122,11 +122,7 @@ bool cFurnaceEntity::Tick( float a_Dt ) cWindow* Window = GetWindow(); if( Window ) { - const std::list< cPlayer* > & OpenedBy = Window->GetOpenedBy(); - for( std::list< cPlayer* >::const_iterator itr = OpenedBy.begin(); itr != OpenedBy.end(); ++itr ) - { - Window->SendWholeWindow( (*itr)->GetClientHandle() ); - } + Window->BroadcastWholeWindow(); } m_TimeCooked = 0.f; @@ -135,19 +131,13 @@ bool cFurnaceEntity::Tick( float a_Dt ) cWindow* Window = GetWindow(); if( Window ) { - const std::list< cPlayer* > & OpenedBy = Window->GetOpenedBy(); - for( std::list< cPlayer* >::const_iterator itr = OpenedBy.begin(); itr != OpenedBy.end(); ++itr ) - { - cClientHandle* Client = (*itr)->GetClientHandle(); - - cPacket_InventoryProgressBar Progress; - Progress.m_ProgressBar = 0; - Progress.m_WindowID = (char)Window->GetWindowID(); - Progress.m_Value = (short)( m_TimeCooked * (180.f/m_CookTime) ); - if( Progress.m_Value > 180 ) Progress.m_Value = 180; - if( Progress.m_Value < 0 ) Progress.m_Value = 0; - Client->Send( Progress ); - } + cPacket_InventoryProgressBar Progress; + Progress.m_ProgressBar = 0; + Progress.m_WindowID = (char)Window->GetWindowID(); + Progress.m_Value = (short)( m_TimeCooked * (180.f/m_CookTime) ); + if( Progress.m_Value > 180 ) Progress.m_Value = 180; + if( Progress.m_Value < 0 ) Progress.m_Value = 0; + Window->Broadcast(Progress); } } } @@ -161,30 +151,26 @@ bool cFurnaceEntity::Tick( float a_Dt ) m_BurnTime = 0; if( StartCooking() && Window ) { - const std::list< cPlayer* > & OpenedBy = Window->GetOpenedBy(); - for( std::list< cPlayer* >::const_iterator itr = OpenedBy.begin(); itr != OpenedBy.end(); ++itr ) - { - Window->SendWholeWindow( (*itr)->GetClientHandle() ); - } + Window->BroadcastWholeWindow(); } } if( Window ) { - const std::list< cPlayer* > & OpenedBy = Window->GetOpenedBy(); - for( std::list< cPlayer* >::const_iterator itr = OpenedBy.begin(); itr != OpenedBy.end(); ++itr ) - { - cClientHandle* Client = (*itr)->GetClientHandle(); + cPacket_InventoryProgressBar Progress; + Progress.m_WindowID = (char)Window->GetWindowID(); + Progress.m_ProgressBar = 1; - cPacket_InventoryProgressBar Progress; - Progress.m_WindowID = (char)Window->GetWindowID(); - Progress.m_ProgressBar = 1; - - if( m_BurnTime > 0.f ) Progress.m_Value = (short)( m_TimeBurned * (150.f/m_BurnTime) ); - else Progress.m_Value = 0; - if( Progress.m_Value > 150 ) Progress.m_Value = 150; - if( Progress.m_Value < 0 ) Progress.m_Value = 0; - Client->Send( Progress ); + if ( m_BurnTime > 0.f ) + { + Progress.m_Value = (short)( m_TimeBurned * (150.f / m_BurnTime) ); + if ( Progress.m_Value > 150 ) Progress.m_Value = 150; + if ( Progress.m_Value < 0 ) Progress.m_Value = 0; + } + else + { + Progress.m_Value = 0; } + Window->Broadcast( Progress ); } return ((m_CookingItem != 0) || (m_TimeBurned < m_BurnTime)) && m_BurnTime > 0.f; // Keep on ticking, if there's more to cook, or if it's cooking } diff --git a/source/cInventory.h b/source/cInventory.h index 8d4b13fcb..b7e91195b 100644 --- a/source/cInventory.h +++ b/source/cInventory.h @@ -1,6 +1,6 @@ + #pragma once -#include "MemoryLeak.h" #include "cWindowOwner.h" #include "FileDefine.h" @@ -14,6 +14,11 @@ class cClientHandle; class cPlayer; class cPacket; class cPacket_EntityEquipment; + + + + + class cInventory //tolua_export : public cWindowOwner { //tolua_export @@ -71,3 +76,7 @@ protected: cPlayer* m_Owner; }; //tolua_export + + + + diff --git a/source/cSurvivalInventory.h b/source/cSurvivalInventory.h index 270f18dcd..6c527f1d2 100644 --- a/source/cSurvivalInventory.h +++ b/source/cSurvivalInventory.h @@ -1,7 +1,12 @@ + #pragma once #include "cInventory.h" + + + + class cSurvivalInventory //tolua_export : public cInventory { //tolua_export @@ -11,3 +16,7 @@ public: virtual void Clicked( cPacket* a_ClickPacket ); }; //tolua_export + + + + diff --git a/source/cWindow.cpp b/source/cWindow.cpp index 1914daa40..548d80975 100644 --- a/source/cWindow.cpp +++ b/source/cWindow.cpp @@ -26,7 +26,9 @@ cWindow::cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ) , m_NumSlots( 0 ) , m_Slots( 0 ) , m_DraggingItem( 0 ) + , m_IsDestroyed(false) { + LOGD("Created a window at %p", this); if( !m_bInventoryVisible ) m_DraggingItem = new cItem(); } @@ -36,11 +38,13 @@ cWindow::cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible ) cWindow::~cWindow() { + LOGD("Deleting a window at %p", this); if( !m_bInventoryVisible && m_DraggingItem ) { delete m_DraggingItem; m_DraggingItem = 0; } + LOGD("Deleted a window at %p", this); } @@ -204,10 +208,13 @@ void cWindow::Clicked( cPacket_WindowClick* a_ClickPacket, cPlayer & a_Player ) void cWindow::Open( cPlayer & a_Player ) { - // If player is already in OpenedBy remove player first - m_OpenedBy.remove( &a_Player ); - // Then add player - m_OpenedBy.push_back( &a_Player ); + { + cCSLock Lock(m_CS); + // If player is already in OpenedBy remove player first + m_OpenedBy.remove( &a_Player ); + // Then add player + m_OpenedBy.push_back( &a_Player ); + } cPacket_WindowOpen WindowOpen; WindowOpen.m_WindowID = (char)m_WindowID; @@ -232,13 +239,23 @@ void cWindow::Close( cPlayer & a_Player ) cPacket_WindowClose WindowClose; WindowClose.m_Close = (char)m_WindowID; - cClientHandle* ClientHandle = a_Player.GetClientHandle(); - if( ClientHandle ) ClientHandle->Send( WindowClose ); + cClientHandle * ClientHandle = a_Player.GetClientHandle(); + if ( ClientHandle != NULL) + { + ClientHandle->Send( WindowClose ); + } - m_OpenedBy.remove( &a_Player ); - if( m_OpenedBy.size() == 0 ) { - Destroy(); + cCSLock Lock(m_CS); + m_OpenedBy.remove( &a_Player ); + if( m_OpenedBy.size() == 0 ) + { + Destroy(); + } + } + if (m_IsDestroyed) + { + delete this; } } @@ -262,13 +279,13 @@ void cWindow::OwnerDestroyed() void cWindow::Destroy() { - LOG("DESTROY WINDOW"); - if( m_Owner ) + LOG("Destroying window %p (type %d)", this, m_WindowType); + if (m_Owner != NULL) { m_Owner->CloseWindow(); - m_Owner = 0; + m_Owner = NULL; } - delete this; + m_IsDestroyed = true; } @@ -284,3 +301,29 @@ void cWindow::SendWholeWindow( cClientHandle* a_Client ) + +void cWindow::BroadcastWholeWindow(void) +{ + cCSLock Lock(m_CS); + for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr) + { + SendWholeWindow((*itr)->GetClientHandle()); + } // for itr - m_OpenedBy[] +} + + + + + +void cWindow::Broadcast(const cPacket & a_Packet) +{ + cCSLock Lock(m_CS); + for (cPlayerList::iterator itr = m_OpenedBy.begin(); itr != m_OpenedBy.end(); ++itr) + { + (*itr)->GetClientHandle()->Send(a_Packet); + } // for itr - m_OpenedBy[] +} + + + + diff --git a/source/cWindow.h b/source/cWindow.h index a6885a7cc..d9f4226a6 100644 --- a/source/cWindow.h +++ b/source/cWindow.h @@ -6,6 +6,14 @@ class cPlayer; class cItem; class cWindowOwner; class cClientHandle; +class cPacket; + +typedef std::list cPlayerList; + + + + + class cWindow { public: @@ -49,25 +57,30 @@ public: void SetOwner( cWindowOwner* a_Owner ) { m_Owner = a_Owner; } void SendWholeWindow( cClientHandle* a_Client ); + void BroadcastWholeWindow(void); + void Broadcast(const cPacket & a_Packet); - const std::string & GetWindowTitle() const { return m_WindowTitle; } + const AString & GetWindowTitle() const { return m_WindowTitle; } void SetWindowTitle( const std::string & a_WindowTitle ) { m_WindowTitle = a_WindowTitle; } - const std::list & GetOpenedBy() const { return m_OpenedBy; } - void OwnerDestroyed(); + private: + void Destroy(); int m_WindowID; int m_WindowType; - std::string m_WindowTitle; + AString m_WindowTitle; - cWindowOwner* m_Owner; + cWindowOwner * m_Owner; - std::list m_OpenedBy; - bool m_bInventoryVisible; - int m_NumSlots; - cItem* m_Slots; - cItem* m_DraggingItem; + cCriticalSection m_CS; + cPlayerList m_OpenedBy; + + bool m_bInventoryVisible; + int m_NumSlots; + cItem * m_Slots; + cItem * m_DraggingItem; + bool m_IsDestroyed; }; \ No newline at end of file diff --git a/source/cWindowOwner.h b/source/cWindowOwner.h index 91d78848c..71691aaed 100644 --- a/source/cWindowOwner.h +++ b/source/cWindowOwner.h @@ -3,11 +3,16 @@ class cWindow; class cBlockEntity; + + + + + class cWindowOwner { public: - cWindowOwner() : m_Window( 0 ) {} - void CloseWindow() { m_Window = 0; } + cWindowOwner() : m_Window( NULL ) {} + void CloseWindow() { m_Window = NULL; } void OpenWindow( cWindow* a_Window ) { m_Window = a_Window; } cWindow* GetWindow() { return m_Window; } @@ -17,4 +22,8 @@ public: private: cWindow* m_Window; cBlockEntity *m_Entity; -}; \ No newline at end of file +}; + + + + -- cgit v1.2.3