thug/Code/Gel/object.h

378 lines
13 KiB
C
Raw Permalink Normal View History

2016-02-13 21:39:12 +00:00
/*****************************************************************************
** **
** Neversoft Entertainment **
** **
** Copyright (C) 1999 - All Rights Reserved **
** **
******************************************************************************
** **
** Project: GEL (Game Engine Library) **
** **
** Module: Object (OBJ) **
** **
** File name: gel/object.h **
** **
** Created: 05/27/99 - mjb **
** **
** Notes:
**
** (Mick) This is the base type for all objects in the game. It contains basic
** mechanisms for maintaining a list of object associated with Object Servers
** and procedures for deleting them
** There are also hooks into the CScript class, in that an object has a
** reference to a script, and a virtual function CallMember, which allows
** the script to call a member function by name (actually by checksum of the name)
**
**
*****************************************************************************/
#ifndef __GEL_OBJECT_H
#define __GEL_OBJECT_H
#define __SCRIPT_EVENT_TABLE__ // define this is you want event tables attached to scripts, rather than objects
/*****************************************************************************
** Includes **
*****************************************************************************/
#include <core/list.h>
#include <core/macros.h>
#include <core/math.h>
#include <sys/timer.h>
#include <gel/ObjPtr.h>
#include <gel/RefCounted.h>
namespace Script
{
class CStruct;
class CScript;
}
struct SBBox{
Mth::Vector m_max;
Mth::Vector m_min;
Mth::Vector centerOfGravity;
float m_radius; // will give the max distance squared where there may still be a collision.
};
/*****************************************************************************
** Defines **
*****************************************************************************/
#define OBJECT_FLAG_INVISIBLE 1
namespace Front
{
class CScreenElementManager;
}
namespace Script
{
class CArray;
}
enum EReplaceEventHandlers
{
DONT_REPLACE_HANDLERS = 0,
REPLACE_HANDLER
};
namespace Obj
{
/*****************************************************************************
** Type Defines **
*****************************************************************************/
class CEvent;
class CEventHandlerTable;
class CBaseManager;
class CGeneralManager;
class CObject;
typedef CSmtPtr<CObject> CObjectPtr;
/*
CObject is described in more detail in: Q:\sk4\Docs\programming\Object Scripting System.htm
The base class for all scriptable objects. Every CObject has a global ID that
is unique among all CObjects. It also has a type specifier.
A script that is running can reference a CObject. The script can access special
commands for that CObject through CallMemberFunction(). Tags, which are like
scriptable member variables, can be attached from CObjects from script, too.
Event handling is supported through the PassTargetedEvent() function.
*/
class CObject : public CRefCounted
{
friend class CBaseManager;
friend class CGeneralManager;
friend class Front::CScreenElementManager;
public :
CObject();
virtual ~CObject ( void );
void DestroyIfUnlocked (); // Destroy immediately
void AddReference ( void );
void RemoveReference ( void );
bool IsReferenced() {return (m_ref_count > 0);}
bool IsDead ( void ) const; // Access functions for the above
bool IsLocked ( void ) const;
uint32 GetID() const {return m_id;}
sint GetType() const {return m_type;}
void SetID(uint32 id);
void SetType(sint type);
void ClearStampBit(uint32 stamp_mask) { m_stamp &= ~stamp_mask; }
bool CheckStampBit(uint32 stamp_mask) const { return m_stamp & stamp_mask; }
void SetStampBit(uint32 stamp_mask) { m_stamp |= stamp_mask; }
uint32 GetFlags() const {return m_object_flags;}
void SetFlags(uint32 flags) {m_object_flags = flags;}
void SetLockOn() {m_object_flags |= vLOCKED;}
void SetLockOff() {m_object_flags &= ~vLOCKED;}
#ifdef __NOPT_ASSERT__
void SetLockAssertOn() {m_object_flags |= vLOCKEDASSERT;}
void SetLockAssertOff() {m_object_flags &= ~vLOCKEDASSERT;}
bool GetLockAssert() {return m_object_flags & vLOCKEDASSERT;}
#endif
Script::CScript * GetScript() const {return mp_script;}
void SetScript(Script::CScript* p_script) {mp_script = p_script;}
void SetEventHandlers(Script::CArray *pArray, EReplaceEventHandlers replace = DONT_REPLACE_HANDLERS);
void RemoveEventHandler(uint32 type);
void RemoveEventHandlerGroup(uint32 group);
// See details on tags in object document
void SetIntegerTag(uint32 name, int value);
void SetChecksumTag(uint32 name, uint32 value);
void RemoveFlagTag(uint32 name);
bool GetIntegerTag(uint32 name, int *pResult) const ;
bool GetChecksumTag(uint32 name, uint32 *pResult) const;
bool ContainsFlagTag(uint32 name) const;
void SetTagsFromScript(Script::CStruct *pStruct);
void RemoveTagsFromScript(Script::CArray *pNameArray);
void CopyTagsToScriptStruct(Script::CStruct *pStruct);
void SetVectorTag(uint32 name, Mth::Vector v);
bool GetVectorTag(uint32 name, Mth::Vector *pResult) const;
void SetOnExceptionScriptChecksum(uint32 OnExceptionScriptChecksum);
uint32 GetOnExceptionScriptChecksum() const;
// subclasses that extend next three functions should still call CObject versions
virtual void SetProperties(Script::CStruct *pProps);
virtual bool CallMemberFunction (uint32 Checksum, Script::CStruct *pParams, Script::CScript *pScript); // Call a member function based on the checksum of the function name
virtual void GetDebugInfo(Script::CStruct *p_info);
// Called by CTracker singleton to pass events to this CObject
virtual bool PassTargetedEvent(CEvent *pEvent, bool broadcast = false); // return true if object still valid
virtual void HideForReplayPlayback() {}
virtual void RestoreAfterReplayPlayback() {}
enum
{
vDEAD = ( 1 << 0 ),
// if locked, can't be deleted
vLOCKED = ( 1 << 1 ),
vINVISIBLE = ( 1 << 2 ),
// this flag has been moved to the ExceptionComponent:
// vDISABLE_EXCEPTIONS = ( 1 << 3 ),
#ifdef __NOPT_ASSERT__
vLOCKEDASSERT = ( 1 << 4 ),
#endif
vCOMPOSITE = ( 1 << 5 ),
// RJM: flags from 8 on are reserved for children of CObject
};
protected:
CObject ( CBaseManager* );
void allocate_tags_if_needed();
public:
void AllocateScriptIfNeeded();
void debug_validate_smart_pointers(CSmtPtr<CObject> *pPtrToCheckForInclusion = NULL);
void MarkAsDead( void ); // Safe kill called from within the object's logic
CBaseManager * GetManager() const {return mp_manager;} // just for exception component stuff
protected:
uint32 m_object_flags;
CBaseManager * mp_manager;
// object script stuff:
Script::CScript* mp_script;
// object ID, globally unique among CObjects
uint32 m_id;
sint m_type; // Object type game dependent
uint32 m_stamp;
#ifndef __SCRIPT_EVENT_TABLE__
CEventHandlerTable * mp_event_handler_table;
// Script to run when there is an exception
// (needed here, since we are getting rid of CExceptionComponent, to replace it with one
// single event system
uint32 mOnExceptionScriptChecksum;
#endif
// Tags are basically variables that can be attached and queried by the scripting
// system at runtime. Very convenient for providing state info.
Script::CStruct * mp_tags;
public:
// (Moved here from CMovingObject)
// A set of flags that can be set using the SendFlag script command. Used for sending messages to objects.
uint32 mScriptFlags;
uint32 GetFlags( Script::CStruct *pParams, Script::CScript *pScript ) const;
// K: Used by CScript::TransmitInfoToDebugger to determine whether the CScript is the
// main script of it's parent object.
bool MainScriptIs(const Script::CScript *p_script) const {return mp_script==p_script;}
// standard objects can not be paused; thus, spawned (non-main) scripts running on them should never be paused
virtual bool ShouldUpdatePauseWithObjectScripts ( ) { return true; }
// K: Also used by CScript::TransmitInfoToDebugger
Script::CStruct *GetTags() const {return mp_tags;}
public:
// GJ: Made this public so that components can set their
// parent objects' scripts
void SwitchScript( uint32 scriptChecksum, Script::CStruct *pParams );
Script::CScript* SpawnScriptPlease( uint32 scriptChecksum, Script::CStruct *pParams, int Id = 0, bool pause_with_object = false );
void SpawnAndRunScript( uint32 ScriptChecksum, int node = -1, bool net_script = false, bool permanent = false, Script::CStruct *p_params = NULL );
void SpawnAndRunScript( const char *pScriptName, int node = -1, bool net_script = false, bool permanent = false, Script::CStruct *p_params = NULL );
void CallScript( uint32 ScriptChecksum, Script::CStruct *pParams );
void SelfEvent(uint32 event, Script::CStruct *pData = NULL);
void BroadcastEvent(uint32 event, Script::CStruct *pData = NULL, float radius = 0.0f);
protected:
Lst::Node< CObject > m_node;
private:
int m_ref_count;
};
/*****************************************************************************
** Private Declarations **
*****************************************************************************/
/*****************************************************************************
** Private Prototypes **
*****************************************************************************/
/*****************************************************************************
** Public Declarations **
*****************************************************************************/
/*****************************************************************************
** Public Prototypes **
*****************************************************************************/
void DestroyIfUnlocked ( CObject* obj, void* data = NULL );
void SetLockOff ( CObject* obj, void* data = NULL );
CObject * ResolveToObject(uint32 id);
/*****************************************************************************
** Inline Functions **
*****************************************************************************/
inline void CObject::AddReference ( void )
{
m_ref_count++;
}
/*****************************************************************************
** Inline Functions **
*****************************************************************************/
/******************************************************************/
/* */
/* */
/******************************************************************/
inline void CObject::RemoveReference ( void )
{
//Dbg_Assert(m_ref_count > 0);
if (m_ref_count > 0)
{
m_ref_count--;
}
// XXX
else
{
#ifdef __NOPT_ASSERT__
printf("Aaaah!! Removing more references than there are\n");
#endif
Dbg_Assert(( m_object_flags & ( 1 << 16 )) == 0 );
// if (m_object_flags & (1<<16)) //Front::CScreenElement::vIS_SCREEN_ELEMENT
// Dbg_Assert(0);
}
}
/******************************************************************/
/* */
/* */
/******************************************************************/
inline bool CObject::IsLocked ( void ) const
{
return ( m_object_flags & ( vLOCKED ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
inline bool CObject::IsDead ( void ) const
{
return ( m_object_flags & ( vDEAD ) );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
} // namespace Obj
#endif // __GEL_OBJECT_H