1
0

Basic cWindow thread-safety

git-svn-id: http://mc-server.googlecode.com/svn/trunk@420 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
madmaxoft@gmail.com 2012-03-19 09:37:10 +00:00
parent f72d1e1821
commit 1e90dad245
6 changed files with 133 additions and 64 deletions

View File

@ -122,11 +122,7 @@ bool cFurnaceEntity::Tick( float a_Dt )
cWindow* Window = GetWindow(); cWindow* Window = GetWindow();
if( Window ) if( Window )
{ {
const std::list< cPlayer* > & OpenedBy = Window->GetOpenedBy(); Window->BroadcastWholeWindow();
for( std::list< cPlayer* >::const_iterator itr = OpenedBy.begin(); itr != OpenedBy.end(); ++itr )
{
Window->SendWholeWindow( (*itr)->GetClientHandle() );
}
} }
m_TimeCooked = 0.f; m_TimeCooked = 0.f;
@ -135,19 +131,13 @@ bool cFurnaceEntity::Tick( float a_Dt )
cWindow* Window = GetWindow(); cWindow* Window = GetWindow();
if( Window ) if( Window )
{ {
const std::list< cPlayer* > & OpenedBy = Window->GetOpenedBy(); cPacket_InventoryProgressBar Progress;
for( std::list< cPlayer* >::const_iterator itr = OpenedBy.begin(); itr != OpenedBy.end(); ++itr ) Progress.m_ProgressBar = 0;
{ Progress.m_WindowID = (char)Window->GetWindowID();
cClientHandle* Client = (*itr)->GetClientHandle(); Progress.m_Value = (short)( m_TimeCooked * (180.f/m_CookTime) );
if( Progress.m_Value > 180 ) Progress.m_Value = 180;
cPacket_InventoryProgressBar Progress; if( Progress.m_Value < 0 ) Progress.m_Value = 0;
Progress.m_ProgressBar = 0; Window->Broadcast(Progress);
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 );
}
} }
} }
} }
@ -161,30 +151,26 @@ bool cFurnaceEntity::Tick( float a_Dt )
m_BurnTime = 0; m_BurnTime = 0;
if( StartCooking() && Window ) if( StartCooking() && Window )
{ {
const std::list< cPlayer* > & OpenedBy = Window->GetOpenedBy(); Window->BroadcastWholeWindow();
for( std::list< cPlayer* >::const_iterator itr = OpenedBy.begin(); itr != OpenedBy.end(); ++itr )
{
Window->SendWholeWindow( (*itr)->GetClientHandle() );
}
} }
} }
if( Window ) if( Window )
{ {
const std::list< cPlayer* > & OpenedBy = Window->GetOpenedBy(); cPacket_InventoryProgressBar Progress;
for( std::list< cPlayer* >::const_iterator itr = OpenedBy.begin(); itr != OpenedBy.end(); ++itr ) Progress.m_WindowID = (char)Window->GetWindowID();
Progress.m_ProgressBar = 1;
if ( m_BurnTime > 0.f )
{ {
cClientHandle* Client = (*itr)->GetClientHandle(); Progress.m_Value = (short)( m_TimeBurned * (150.f / m_BurnTime) );
if ( Progress.m_Value > 150 ) Progress.m_Value = 150;
cPacket_InventoryProgressBar Progress; if ( Progress.m_Value < 0 ) Progress.m_Value = 0;
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 );
} }
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 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
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "MemoryLeak.h"
#include "cWindowOwner.h" #include "cWindowOwner.h"
#include "FileDefine.h" #include "FileDefine.h"
@ -14,6 +14,11 @@ class cClientHandle;
class cPlayer; class cPlayer;
class cPacket; class cPacket;
class cPacket_EntityEquipment; class cPacket_EntityEquipment;
class cInventory //tolua_export class cInventory //tolua_export
: public cWindowOwner : public cWindowOwner
{ //tolua_export { //tolua_export
@ -71,3 +76,7 @@ protected:
cPlayer* m_Owner; cPlayer* m_Owner;
}; //tolua_export }; //tolua_export

View File

@ -1,7 +1,12 @@
#pragma once #pragma once
#include "cInventory.h" #include "cInventory.h"
class cSurvivalInventory //tolua_export class cSurvivalInventory //tolua_export
: public cInventory : public cInventory
{ //tolua_export { //tolua_export
@ -11,3 +16,7 @@ public:
virtual void Clicked( cPacket* a_ClickPacket ); virtual void Clicked( cPacket* a_ClickPacket );
}; //tolua_export }; //tolua_export

View File

@ -26,7 +26,9 @@ cWindow::cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible )
, m_NumSlots( 0 ) , m_NumSlots( 0 )
, m_Slots( 0 ) , m_Slots( 0 )
, m_DraggingItem( 0 ) , m_DraggingItem( 0 )
, m_IsDestroyed(false)
{ {
LOGD("Created a window at %p", this);
if( !m_bInventoryVisible ) m_DraggingItem = new cItem(); if( !m_bInventoryVisible ) m_DraggingItem = new cItem();
} }
@ -36,11 +38,13 @@ cWindow::cWindow( cWindowOwner* a_Owner, bool a_bInventoryVisible )
cWindow::~cWindow() cWindow::~cWindow()
{ {
LOGD("Deleting a window at %p", this);
if( !m_bInventoryVisible && m_DraggingItem ) if( !m_bInventoryVisible && m_DraggingItem )
{ {
delete m_DraggingItem; delete m_DraggingItem;
m_DraggingItem = 0; 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 ) void cWindow::Open( cPlayer & a_Player )
{ {
// If player is already in OpenedBy remove player first {
m_OpenedBy.remove( &a_Player ); cCSLock Lock(m_CS);
// Then add player // If player is already in OpenedBy remove player first
m_OpenedBy.push_back( &a_Player ); m_OpenedBy.remove( &a_Player );
// Then add player
m_OpenedBy.push_back( &a_Player );
}
cPacket_WindowOpen WindowOpen; cPacket_WindowOpen WindowOpen;
WindowOpen.m_WindowID = (char)m_WindowID; WindowOpen.m_WindowID = (char)m_WindowID;
@ -232,13 +239,23 @@ void cWindow::Close( cPlayer & a_Player )
cPacket_WindowClose WindowClose; cPacket_WindowClose WindowClose;
WindowClose.m_Close = (char)m_WindowID; WindowClose.m_Close = (char)m_WindowID;
cClientHandle* ClientHandle = a_Player.GetClientHandle(); cClientHandle * ClientHandle = a_Player.GetClientHandle();
if( ClientHandle ) ClientHandle->Send( WindowClose ); if ( ClientHandle != NULL)
m_OpenedBy.remove( &a_Player );
if( m_OpenedBy.size() == 0 )
{ {
Destroy(); ClientHandle->Send( WindowClose );
}
{
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() void cWindow::Destroy()
{ {
LOG("DESTROY WINDOW"); LOG("Destroying window %p (type %d)", this, m_WindowType);
if( m_Owner ) if (m_Owner != NULL)
{ {
m_Owner->CloseWindow(); 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[]
}

View File

@ -6,6 +6,14 @@ class cPlayer;
class cItem; class cItem;
class cWindowOwner; class cWindowOwner;
class cClientHandle; class cClientHandle;
class cPacket;
typedef std::list<cPlayer *> cPlayerList;
class cWindow class cWindow
{ {
public: public:
@ -49,25 +57,30 @@ public:
void SetOwner( cWindowOwner* a_Owner ) { m_Owner = a_Owner; } void SetOwner( cWindowOwner* a_Owner ) { m_Owner = a_Owner; }
void SendWholeWindow( cClientHandle* a_Client ); 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; } void SetWindowTitle( const std::string & a_WindowTitle ) { m_WindowTitle = a_WindowTitle; }
const std::list<cPlayer*> & GetOpenedBy() const { return m_OpenedBy; }
void OwnerDestroyed(); void OwnerDestroyed();
private: private:
void Destroy(); void Destroy();
int m_WindowID; int m_WindowID;
int m_WindowType; int m_WindowType;
std::string m_WindowTitle; AString m_WindowTitle;
cWindowOwner* m_Owner; cWindowOwner * m_Owner;
std::list<cPlayer*> m_OpenedBy; cCriticalSection m_CS;
bool m_bInventoryVisible; cPlayerList m_OpenedBy;
int m_NumSlots;
cItem* m_Slots; bool m_bInventoryVisible;
cItem* m_DraggingItem; int m_NumSlots;
cItem * m_Slots;
cItem * m_DraggingItem;
bool m_IsDestroyed;
}; };

View File

@ -3,11 +3,16 @@
class cWindow; class cWindow;
class cBlockEntity; class cBlockEntity;
class cWindowOwner class cWindowOwner
{ {
public: public:
cWindowOwner() : m_Window( 0 ) {} cWindowOwner() : m_Window( NULL ) {}
void CloseWindow() { m_Window = 0; } void CloseWindow() { m_Window = NULL; }
void OpenWindow( cWindow* a_Window ) { m_Window = a_Window; } void OpenWindow( cWindow* a_Window ) { m_Window = a_Window; }
cWindow* GetWindow() { return m_Window; } cWindow* GetWindow() { return m_Window; }
@ -17,4 +22,8 @@ public:
private: private:
cWindow* m_Window; cWindow* m_Window;
cBlockEntity *m_Entity; cBlockEntity *m_Entity;
}; };