📄 icefielddescriptor.h
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Contains field descriptors.
* \file IceFieldDescriptor.h
* \author Pierre Terdiman
* \date April, 4, 2000
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Guard
#ifndef __ICEFIELDDESCRIPTOR_H__
#define __ICEFIELDDESCRIPTOR_H__
// Forward declarations
class Cell;
struct FieldDescriptor;
class FieldController;
class ParameterBlock;
//! Defines a generic field
#define _FIELD(type, name, fieldtype, count, flags, accessor, callback, user) { fieldtype, #name, OFFSET_OF(type, name), count, flags, accessor, callback, user }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//! Defines a single base field
#define DEFINE_FIELD(type, name, fieldtype, flags, accessor, callback) _FIELD(type, name, fieldtype, 1, flags, accessor, callback, 0)
//! Defines a static array of base fields
#define DEFINE_FIELDS(type, name, fieldtype, count, flags, accessor, callback) _FIELD(type, name, fieldtype, count, flags, accessor, callback, 0)
//! Defines a single custom field
#define DEFINE_USER_FIELD(type, name, fieldtype, flags, accessor, callback, user) _FIELD(type, name, fieldtype, 1, flags, accessor, callback, user)
//! Defines a static array of custom fields
#define DEFINE_USER_FIELDS(type, name, fieldtype, count, flags, accessor, callback, user) _FIELD(type, name, fieldtype, count, flags, accessor, callback, user)
//! Defines a dynamic array of base fields
#define DEFINE_ARRAY(type, name, fieldtype, flags, accessor, callback) _FIELD(type, name, fieldtype, 0, flags, accessor, callback, 0)
//! Defines a dynamic array of custom fields
#define DEFINE_USER_ARRAY(type, name, fieldtype, flags, accessor, callback, user) _FIELD(type, name, fieldtype, 0, flags, accessor, callback, user)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//! Starts field declarations
#define BEGIN_FIELDS(current_class) FieldDescriptor current_class::mClassDescriptor[] = { \
{ FIELD_FORCE_DWORD, #current_class, 0, 0, 0, null, null, 0 },
//! Ends field declarations
#define END_FIELDS(current_class) }; udword current_class::GetDescriptorSize() const { return ARRAYSIZE(mClassDescriptor); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//! Declares a static class descriptor for the class. (a.k.a. meta-data)
//! You can use this on all classes, not only Cell-based ones. This macro must be used in the header files,
//! then fields must be declared in the cpp file using BEGIN_FIELDS / DEFINE_FIELD / END_FIELDS macros.
#define DECLARE_FIELDS \
\
static FieldDescriptor mClassDescriptor[]; \
\
/* Gets the number of defined fields. There's always at least one for the class itself */ \
/* This is ONLY for current class, not base classes. So NO VIRTUAL there. */ \
/*virtual*/ udword GetDescriptorSize() const; \
/* Gets field descriptors */ \
const FieldDescriptor* GetDescriptor() const { return mClassDescriptor; } \
/* Finds a field given its name */ \
const FieldDescriptor* FindDescriptor(const char* name) const \
{ \
if(!name) return null; \
udword Size = GetDescriptorSize(); \
for(udword i=0;i<Size;i++) \
{ \
const FieldDescriptor* FD = &mClassDescriptor[i]; \
if(strcmp(FD->Name, name)==0) return FD; \
} \
return null; \
} \
/* Setups from a parameter block */ \
bool SetFrom(const ParameterBlock& pb) \
{ \
udword Size = GetDescriptorSize(); \
for(udword i=0;i<Size;i++) \
{ \
if(mClassDescriptor[i].SetFrom(this, pb)) return true; \
} \
return false; \
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Field modification callback. Called by the system each time a declared field must be modified.
* \param owner [in] object to modify
* \param field [in] descriptor of modified field
* \param data [in] address of the new value
* \return true to override the system modification - which means you handled it yourself
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef bool (*ModificationNotif) (Cell* owner, const FieldDescriptor* field, const void* data);
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* Field control callback. Called by the system each time a declared field must be updated by a controller.
* \param owner [in] object to modify
* \param ctrl [in] field controller
* \param time [in] current time-related info
*/
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef void (*SetAccessor) (Cell* owner, FieldController* ctrl, const TimeInfo& time);
//! A field descriptor
struct ICECORE_API FieldDescriptor
{
// Compulsory values
FieldType Type; //!< Field type (bool, byte, quaternion, etc)
const char* Name; //!< Field name (appears exactly as in the source file)
udword Offset; //!< Offset from the start of the class (ie from "this", field is located at "this"+Offset)
uword Count; //!< Number of items of type Type (0 for dynamic sizes)
uword Flags; //!< Field parameters
ModificationNotif Callback; //!< Modification callback
SetAccessor Accessor; //!< Set accessor
// User-defined values
udword UserParam; //!< A user-defined parameter / ID to customize some fields.
// Generic methods
udword FieldSize() const;
inline_ void* Address(void* class_ptr) const { return (void*)(udword(class_ptr) + Offset); }
inline_ void DefaultCopy(void* ptr, const void* data) const { CopyMemory(Address(ptr), data, FieldSize()); }
bool SetFrom(void* ptr, const ParameterBlock& pb) const;
// Cell methods
void Replace(Cell* cell, const void* data) const;
inline_ void Copy(Cell* dest, Cell* src) const { Replace(dest, Address(src)); }
uword GetCount() const;
};
class ICECORE_API FieldDescriptors : private Container
{
public:
// Constructor / Destructor
FieldDescriptors() {}
~FieldDescriptors() {}
inline_ udword GetNbDescriptors() const { return GetNbEntries(); }
inline_ FieldDescriptor** GetDescriptors() const { return (FieldDescriptor**)GetEntries(); }
inline_ FieldDescriptor* GetDescriptor(udword i) const { return (FieldDescriptor*)GetEntry(i); }
void AddDescriptor(const FieldDescriptor* descriptor) { AddUnique(udword(descriptor)); }
PREVENT_COPY(FieldDescriptors)
};
#endif // __ICEFIELDDESCRIPTOR_H__
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -