///////////////////////////////////////////////////////////////////////////////
/// @file deSynchObject.hpp
///
/// @brief 
///
/// @author trajar
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Jun 2002
/// @author trajar
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

#ifndef		_DESYNCHOBJECT_HPP
#define		_DESYNCHOBJECT_HPP

#ifndef		_DENET_HPP
 #include	"deNet.hpp"
#endif

#include	<WINDOWS.H>

// used to ensure local lock inside a function
#define		ENSURE_LOCK( a, b )	{ if( !(b)->IsLocked() ) { deSynchLocalObject myLocalSynchObject = deSynchLocalObject( (a), (b) ); } }

//-------------------------------------------------------------
// deSynchObject
//
// - used to ensure thread safe operations
//-------------------------------------------------------------
class DENET_API deSynchObject
{
public:
	deSynchObject(void);
	~deSynchObject(void);

	void	Lock(void*);
	void	Unlock(void);

	void *	GetOwner(void)		const { return m_Owner; }
	bool	IsLocked(void)		const { return m_bLocked || m_Owner; }

private:

	bool				m_bLocked;
	void *				m_Owner;
	CRITICAL_SECTION	m_csLock;
};

//-------------------------------------------------------------
// deSynchLocalObject
//
// - used to ensure thread-safe operations for local function
//-------------------------------------------------------------
class DENET_API deSynchLocalObject
{
public:
	// don't use this
	deSynchLocalObject( void );
	
	// use these
	deSynchLocalObject( void * pOwner, deSynchObject * pObj );
	~deSynchLocalObject( void );

	deSynchObject *		GetParent( void );

private:
	void *				m_Owner;
	deSynchObject *		m_Object;
};

#endif