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();
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 )
cPacket_InventoryProgressBar Progress;
Progress.m_WindowID = (char)Window->GetWindowID();
Progress.m_ProgressBar = 1;
if ( m_BurnTime > 0.f )
{
cClientHandle* Client = (*itr)->GetClientHandle();
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 );
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
}

View File

@ -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

View File

@ -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

View File

@ -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 );
m_OpenedBy.remove( &a_Player );
if( m_OpenedBy.size() == 0 )
cClientHandle * ClientHandle = a_Player.GetClientHandle();
if ( ClientHandle != NULL)
{
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()
{
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[]
}

View File

@ -6,6 +6,14 @@ class cPlayer;
class cItem;
class cWindowOwner;
class cClientHandle;
class cPacket;
typedef std::list<cPlayer *> 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<cPlayer*> & 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<cPlayer*> 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;
};

View File

@ -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;
};
};