1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354 |
- //-----------------------------------------------------------------------------
- // Copyright (c) 2012 GarageGames, LLC
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //-----------------------------------------------------------------------------
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
- // Copyright (C) 2015 Faust Logic, Inc.
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- #ifndef _CONSOLEOBJECT_H_
- #define _CONSOLEOBJECT_H_
- #ifndef _TVECTOR_H_
- #include "core/util/tVector.h"
- #endif
- #ifndef _STRINGTABLE_H_
- #include "core/stringTable.h"
- #endif
- #ifndef _STRINGFUNCTIONS_H_
- #include "core/strings/stringFunctions.h"
- #endif
- #ifndef _BITSET_H_
- #include "core/bitSet.h"
- #endif
- #ifndef _DYNAMIC_CONSOLETYPES_H_
- #include "console/dynamicTypes.h"
- #endif
- #ifndef _ENGINEOBJECT_H_
- #include "console/engineObject.h"
- #endif
- #ifndef _ENGINEFUNCTIONS_H_
- #include "console/engineFunctions.h"
- #endif
- #ifndef _SIMOBJECTREF_H_
- #include "console/simObjectRef.h"
- #endif
- #ifndef TINYXML_INCLUDED
- #include "tinyxml2.h"
- #endif
- /// @file
- /// Legacy console object system.
- /// @ingroup console_system Console System
- /// @{
- class Namespace;
- class ConsoleObject;
- enum NetClassTypes
- {
- NetClassTypeObject = 0,
- NetClassTypeDataBlock,
- NetClassTypeEvent,
- NetClassTypesCount,
- };
- enum NetClassGroups
- {
- NetClassGroupGame = 0,
- NetClassGroupCommunity,
- NetClassGroup3,
- NetClassGroup4,
- NetClassGroupsCount,
- };
- enum NetClassMasks
- {
- NetClassGroupGameMask = BIT(NetClassGroupGame),
- NetClassGroupCommunityMask = BIT(NetClassGroupCommunity),
- };
- enum NetDirection
- {
- NetEventDirAny,
- NetEventDirServerToClient,
- NetEventDirClientToServer,
- };
- class SimObject;
- class TypeValidator;
- class ConsoleClassObject;
- DECLARE_SCOPE( ConsoleAPI );
- //=============================================================================
- // AbstractClassRep.
- //=============================================================================
- /// Core functionality for class manipulation.
- ///
- /// @section AbstractClassRep_intro Introduction (or, Why AbstractClassRep?)
- ///
- /// Many of Torque's subsystems, especially network, console, and sim,
- /// require the ability to programatically instantiate classes. For instance,
- /// when objects are ghosted, the networking layer needs to be able to create
- /// an instance of the object on the client. When the console scripting
- /// language runtime encounters the "new" keyword, it has to be able to fill
- /// that request.
- ///
- /// Since standard C++ doesn't provide a function to create a new instance of
- /// an arbitrary class at runtime, one must be created. This is what
- /// AbstractClassRep and ConcreteClassRep are all about. They allow the registration
- /// and instantiation of arbitrary classes at runtime.
- ///
- /// In addition, ACR keeps track of the fields (registered via addField() and co.) of
- /// a class, allowing programmatic access of class fields.
- ///
- /// @see ConsoleObject
- ///
- /// @note In general, you will only access the functionality implemented in this class via
- /// ConsoleObject::create(). Most of the time, you will only ever need to use this part
- /// part of the engine indirectly - ie, you will use the networking system or the console,
- /// or ConsoleObject, and they will indirectly use this code. <b>The following discussion
- /// is really only relevant for advanced engine users.</b>
- ///
- /// @section AbstractClassRep_netstuff NetClasses and Class IDs
- ///
- /// Torque supports a notion of group, type, and direction for objects passed over
- /// the network. Class IDs are assigned sequentially per-group, per-type, so that, for instance,
- /// the IDs assigned to Datablocks are seperate from the IDs assigned to NetObjects or NetEvents.
- /// This can translate into significant bandwidth savings (especially since the size of the fields
- /// for transmitting these bits are determined at run-time based on the number of IDs given out.
- ///
- /// @section AbstractClassRep_details AbstractClassRep Internals
- ///
- /// Much like ConsoleConstructor, ACR does some preparatory work at runtime before execution
- /// is passed to main(). In actual fact, this preparatory work is done by the ConcreteClassRep
- /// template. Let's examine this more closely.
- ///
- /// If we examine ConsoleObject, we see that two macros must be used in the definition of a
- /// properly integrated objects. From the ConsoleObject example:
- ///
- /// @code
- /// // This is from inside the class definition...
- /// DECLARE_CONOBJECT(TorqueObject);
- ///
- /// // And this is from outside the class definition...
- /// IMPLEMENT_CONOBJECT(TorqueObject);
- /// @endcode
- ///
- /// What do these things actually do?
- ///
- /// Not all that much, in fact. They expand to code something like this:
- ///
- /// @code
- /// // This is from inside the class definition...
- /// static ConcreteClassRep<TorqueObject> dynClassRep;
- /// static AbstractClassRep* getParentStaticClassRep();
- /// static AbstractClassRep* getStaticClassRep();
- /// virtual AbstractClassRep* getClassRep() const;
- /// @endcode
- ///
- /// @code
- /// // And this is from outside the class definition...
- /// AbstractClassRep* TorqueObject::getClassRep() const { return &TorqueObject::dynClassRep; }
- /// AbstractClassRep* TorqueObject::getStaticClassRep() { return &dynClassRep; }
- /// AbstractClassRep* TorqueObject::getParentStaticClassRep() { return Parent::getStaticClassRep(); }
- /// ConcreteClassRep<TorqueObject> TorqueObject::dynClassRep("TorqueObject", 0, -1, 0);
- /// @endcode
- ///
- /// As you can see, getClassRep(), getStaticClassRep(), and getParentStaticClassRep() are just
- /// accessors to allow access to various ConcreteClassRep instances. This is where the Parent
- /// typedef comes into play as well - it lets getParentStaticClassRep() get the right
- /// class rep.
- ///
- /// In addition, dynClassRep is declared as a member of TorqueObject, and defined later
- /// on. Much like ConsoleConstructor, ConcreteClassReps add themselves to a global linked
- /// list in their constructor.
- ///
- /// Then, when AbstractClassRep::initialize() is called, from Con::init(), we iterate through
- /// the list and perform the following tasks:
- /// - Sets up a Namespace for each class.
- /// - Call the init() method on each ConcreteClassRep. This method:
- /// - Links namespaces between parent and child classes, using Con::classLinkNamespaces.
- /// - Calls initPersistFields() and consoleInit().
- /// - As a result of calling initPersistFields, the field list for the class is populated.
- /// - Assigns network IDs for classes based on their NetGroup membership. Determines
- /// bit allocations for network ID fields.
- ///
- /// @nosubgrouping
- class AbstractClassRep : public ConsoleBaseType
- {
- friend class ConsoleObject;
- public:
- typedef ConsoleBaseType Parent;
- /// Allows the writing of a custom TAML schema.
- typedef void(*WriteCustomTamlSchema)(const AbstractClassRep* pClassRep, tinyxml2::XMLElement* pParentElement);
- /// @name 'Tructors
- /// @{
- ///
- /// @param conIdPtr Pointer to the static S32 console ID.
- /// @param conTypeName Console type name.
- AbstractClassRep( S32* conIdPtr, const char* typeName )
- : Parent( sizeof( void* ), conIdPtr, typeName )
- {
- VECTOR_SET_ASSOCIATION( mFieldList );
- mCategory = StringTable->EmptyString();
- mClassGroupMask = 0;
- std::fill_n(mClassId, NetClassGroupsCount, -1);
- mClassName = StringTable->EmptyString();
- mClassSizeof = 0;
- mClassType = 0;
- mDescription = StringTable->EmptyString();
- #ifdef TORQUE_NET_STATS
- dMemset(mDirtyMaskFrequency, 0, sizeof(mDirtyMaskFrequency));
- dMemset(mDirtyMaskTotal, 0, sizeof(mDirtyMaskTotal));
- #endif
- mDynamicGroupExpand = false;
- mNamespace = NULL;
- mNetEventDir = 0;
- nextClass = NULL;
- parentClass = NULL;
- mIsRenderEnabled = true;
- mIsSelectionEnabled = true;
- }
- /// @}
- /// @name Representation Interface
- /// @{
- //TODO: move over to EngineTypeNetInfo
- S32 mClassGroupMask; ///< Mask indicating in which NetGroups this object belongs.
- S32 mClassType; ///< Stores the NetClass of this class.
- S32 mNetEventDir; ///< Stores the NetDirection of this class.
- S32 mClassId[ NetClassGroupsCount ]; ///< Stores the IDs assigned to this class for each group.
- S32 mClassSizeof; ///< Size of instances in bytes.
- //TODO: move over to EngineTypeNetInfo
- #ifdef TORQUE_NET_STATS
- struct NetStatInstance
- {
- U32 numEvents;
- U32 total;
- S32 min;
- S32 max;
- void reset()
- {
- numEvents = 0;
- total = 0;
- min = S32_MAX;
- max = S32_MIN;
- }
- void update(U32 amount)
- {
- numEvents++;
- total += amount;
- min = getMin((S32)amount, min);
- max = getMax((S32)amount, max);
- }
- NetStatInstance()
- {
- reset();
- }
- };
- NetStatInstance mNetStatPack;
- NetStatInstance mNetStatUnpack;
- NetStatInstance mNetStatWrite;
- NetStatInstance mNetStatRead;
- U32 mDirtyMaskFrequency[32];
- U32 mDirtyMaskTotal[32];
- void resetNetStats()
- {
- mNetStatPack.reset();
- mNetStatUnpack.reset();
- mNetStatWrite.reset();
- mNetStatRead.reset();
- for(S32 i=0; i<32; i++)
- {
- mDirtyMaskFrequency[i] = 0;
- mDirtyMaskTotal[i] = 0;
- }
- }
- void updateNetStatPack(U32 dirtyMask, U32 length)
- {
- mNetStatPack.update(length);
- for(S32 i=0; i<32; i++)
- if(BIT(i) & dirtyMask)
- {
- mDirtyMaskFrequency[i]++;
- mDirtyMaskTotal[i] += length;
- }
- }
- void updateNetStatUnpack(U32 length)
- {
- mNetStatUnpack.update(length);
- }
- void updateNetStatWriteData(U32 length)
- {
- mNetStatWrite.update(length);
- }
- void updateNetStatReadData(U32 length)
- {
- mNetStatRead.update(length);
- }
- #endif
- S32 getClassId (U32 netClassGroup) const { return mClassId[ netClassGroup ]; }
- static U32 getClassCRC (U32 netClassGroup) { return classCRC[ netClassGroup ]; }
- AbstractClassRep* getCommonParent( const AbstractClassRep *otherClass ) const;
- /// Return the name of this class.
- StringTableEntry getClassName() const { return mClassName; }
- /// Return the namespace that contains the methods of this class.
- Namespace* getNameSpace() const { return mNamespace; }
- /// Return the AbstractClassRep of the class that this class is derived from.
- AbstractClassRep* getParentClass() const { return parentClass; }
- virtual AbstractClassRep* getContainerChildClass(const bool recurse) = 0;
- virtual WriteCustomTamlSchema getCustomTamlSchema(void) = 0;
- /// Return the size of instances of this class in bytes.
- S32 getSizeof() const { return mClassSizeof; }
- /// Return the next class in the global class list link chain.
- AbstractClassRep* getNextClass() const { return nextClass; }
- /// Return the head of the global class list.
- static AbstractClassRep* getClassList() { return classLinkList; }
- /// Helper class to see if we are a given class, or a subclass thereof by
- /// comparing AbstractClassRep pointers.
- bool isSubclassOf( const AbstractClassRep* klass ) const
- {
- const AbstractClassRep *walk = this;
- // Walk up parents, checking for equivalence.
- while ( walk )
- {
- if ( walk == klass )
- return true;
- walk = walk->parentClass;
- };
- return false;
- }
- /// Helper class to see if we are a given class, or a subclass thereof by
- /// comparing the class name strings.
- bool isSubclassOf( const char *klass ) const
- {
- klass = StringTable->insert( klass );
- // Walk up parents, checking for equivalence.
- const AbstractClassRep *walk = this;
- while ( walk )
- {
- if ( walk->mClassName == klass )
- return true;
- walk = walk->parentClass;
- };
- return false;
- }
- /// @deprecated Use isSubclassOf.
- bool isClass( const AbstractClassRep* acr ) const
- {
- return isSubclassOf( acr );
- }
- virtual ConsoleObject* create () const = 0;
- AbstractClassRep* findFieldRoot(StringTableEntry fieldName);
- protected:
- virtual void init();
- const char * mClassName;
- AbstractClassRep * nextClass;
- AbstractClassRep * parentClass;
- Namespace * mNamespace;
- /// @}
- public:
- bool mIsRenderEnabled;
- bool mIsSelectionEnabled;
- bool isRenderEnabled() const { return mIsRenderEnabled; }
- bool isSelectionEnabled() const { return mIsSelectionEnabled; }
- /// @name Categories
- /// @{
- protected:
- const char* mCategory;
- const char* mDescription;
- public:
- /// Return the space separated category path for the class.
- const char* getCategory() const { return mCategory; }
- /// Return a short description string suitable for displaying in tooltips.
- const char* getDescription() const { return mDescription; }
- /// @}
- /// @name Fields
- /// @{
- public:
- /// This is a function pointer typedef to support get/set callbacks for fields
- typedef bool (*SetDataNotify)( void *obj, const char *array, const char *data );
- typedef const char *(*GetDataNotify)( void *obj, const char *data );
- /// This is a function pointer typedef to support optional writing for fields.
- typedef bool(*WriteDataNotify)(void* obj, StringTableEntry pFieldName);
- /// These are special field type values used to mark
- /// groups and arrays in the field list.
- /// @see Field::type
- /// @see addArray, endArray
- /// @see addGroup, endGroup
- /// @see addGroup, endGroup
- /// @see addDeprecatedField
- enum ACRFieldTypes : U32
- {
- /// The first custom field type... all fields
- /// types greater or equal to this one are not
- /// console data types.
- ARCFirstCustomField = 0xFFFFFFFB,
- /// Marks the start of a fixed size array of fields.
- /// @see addArray
- StartArrayFieldType = 0xFFFFFFFB,
- /// Marks the end of a fixed size array of fields.
- /// @see endArray
- EndArrayFieldType = 0xFFFFFFFC,
- /// Marks the beginning of a group of fields.
- /// @see addGroup
- StartGroupFieldType = 0xFFFFFFFD,
- /// Marks the beginning of a group of fields.
- /// @see endGroup
- EndGroupFieldType = 0xFFFFFFFE,
- /// Marks a field that is depreciated and no
- /// longer stores a value.
- /// @see addDeprecatedField
- DeprecatedFieldType = 0xFFFFFFFF
- };
- enum FieldFlags
- {
- FIELD_HideInInspectors = BIT( 0 ), ///< Do not show the field in inspectors.
- FIELD_ComponentInspectors = BIT(1), ///< Custom fields used by components. They are likely to be non-standard size/configuration, so
- ///< They are handled specially
- FIELD_CustomInspectors = BIT(2), ///< Display as a button in inspectors.
- };
- struct Field
- {
- Field()
- : pFieldname( NULL ),
- pGroupname( NULL ),
- pFieldDocs( NULL ),
- groupExpand( false ),
- type( 0 ),
- offset( 0 ),
- elementCount( 0 ),
- table( NULL ),
- validator( NULL ),
- setDataFn( NULL ),
- getDataFn( NULL ),
- writeDataFn(NULL),
- networkMask(0)
- {
- doNotSubstitute = keepClearSubsOnly = false;
- }
- StringTableEntry pFieldname; ///< Name of the field.
- const char* pGroupname; ///< Optionally filled field containing the group name.
- ///
- /// This is filled when type is StartField or EndField
- const char* pFieldDocs; ///< Documentation about this field; see consoleDoc.cc.
- bool groupExpand; ///< Flag to track expanded/not state of this group in the editor.
- U32 type; ///< A data type ID or one of the special custom fields. @see ACRFieldTypes
- U32 offset; ///< Memory offset from beginning of class for this field.
- S32 elementCount; ///< Number of elements, if this is an array.
- const EnumTable * table; ///< If this is an enum, this points to the table defining it.
- BitSet32 flag; ///< Stores various flags
- TypeValidator *validator; ///< Validator, if any.
- SetDataNotify setDataFn; ///< Set data notify Fn
- GetDataNotify getDataFn; ///< Get data notify Fn
- WriteDataNotify writeDataFn; ///< Function to determine whether data should be written or not.
- bool doNotSubstitute;
- bool keepClearSubsOnly;
- U32 networkMask;
- };
- typedef Vector<Field> FieldList;
- FieldList mFieldList;
- bool mDynamicGroupExpand;
- const Field* findField( StringTableEntry fieldName ) const;
- /// @}
- /// @name Console Type Interface
- /// @{
- virtual void* getNativeVariable() { return new ( AbstractClassRep* ); } // Any pointer-sized allocation will do.
- virtual void deleteNativeVariable( void* var ) { delete reinterpret_cast< AbstractClassRep** >( var ); }
- /// @}
- /// @name Abstract Class Database
- /// @{
- protected:
- static AbstractClassRep ** classTable[NetClassGroupsCount][NetClassTypesCount];
- static AbstractClassRep * classLinkList;
- static U32 classCRC[NetClassGroupsCount];
- static bool initialized;
- static ConsoleObject* create(const char* in_pClassName);
- static ConsoleObject* create(const U32 groupId, const U32 typeId, const U32 in_classId);
- public:
- static U32 NetClassCount [NetClassGroupsCount][NetClassTypesCount];
- static U32 NetClassBitSize[NetClassGroupsCount][NetClassTypesCount];
- static void registerClassRep(AbstractClassRep*);
- static AbstractClassRep* findClassRep(const char* in_pClassName);
- static AbstractClassRep* findClassRep( U32 groupId, U32 typeId, U32 classId );
- static void removeClassRep(AbstractClassRep*); // This should not be used lightly
- static void initialize(); // Called from Con::init once on startup
- static void shutdown();
- /// @}
- };
- extern AbstractClassRep::FieldList sg_tempFieldList;
- //=============================================================================
- // ConcreteClassRep.
- //=============================================================================
- /// Helper class for AbstractClassRep.
- ///
- /// @see AbtractClassRep
- /// @see ConsoleObject
- template< class T >
- class ConcreteAbstractClassRep : public AbstractClassRep
- {
- public:
- virtual AbstractClassRep* getContainerChildClass(const bool recurse)
- {
- // Fetch container children type.
- AbstractClassRep* pChildren = T::getContainerChildStaticClassRep();
- if (!recurse || pChildren != NULL)
- return pChildren;
- // Fetch parent type.
- AbstractClassRep* pParent = T::getParentStaticClassRep();
- if (pParent == NULL)
- return NULL;
- // Get parent container children.
- return pParent->getContainerChildClass(recurse);
- }
- virtual WriteCustomTamlSchema getCustomTamlSchema(void)
- {
- return T::getStaticWriteCustomTamlSchema();
- }
- static EnginePropertyTable _smPropertyTable;
- static EnginePropertyTable& smPropertyTable;
- ConcreteAbstractClassRep(const char* name,
- const char* conTypeName,
- S32* conTypeIdPtr,
- S32 netClassGroupMask,
- S32 netClassType,
- S32 netEventDir,
- AbstractClassRep* parent,
- const char* (*parentDesc)())
- : AbstractClassRep(conTypeIdPtr, conTypeName)
- {
- mClassName = StringTable->insert(name);
- mCategory = T::__category();
- mTypeInfo = _MAPTYPE< T >();
- if (mTypeInfo)
- const_cast< EngineTypeInfo* >(mTypeInfo)->mPropertyTable = &smPropertyTable;
- if (&T::__description != parentDesc)
- mDescription = T::__description();
- // Clean up mClassId
- for (U32 i = 0; i < NetClassGroupsCount; i++)
- mClassId[i] = -1;
- // Set properties for this ACR
- mClassType = netClassType;
- mClassGroupMask = netClassGroupMask;
- mNetEventDir = netEventDir;
- parentClass = parent;
- mClassSizeof = sizeof(T);
-
- // Finally, register ourselves.
- registerClassRep(this);
- };
-
- /// Wrap constructor.
- ConsoleObject* create() const { return NULL; }
- /// Perform class specific initialization tasks.
- ///
- /// Link namespaces, call initPersistFields() and consoleInit().
- void init()
- {
- // Get handle to our parent class, if any, and ourselves (we are our parent's child).
- AbstractClassRep *parent = T::getParentStaticClassRep();
- AbstractClassRep *child = T::getStaticClassRep();
-
- // If we got reps, then link those namespaces! (To get proper inheritance.)
- if (parent && child)
- Con::classLinkNamespaces(parent->getNameSpace(), child->getNameSpace());
- // Finally, do any class specific initialization...
- T::initPersistFields();
- T::consoleInit();
- EnginePropertyTable::Property* props = new EnginePropertyTable::Property[sg_tempFieldList.size()];
- for (int i = 0; i < sg_tempFieldList.size(); ++i)
- {
- EnginePropertyTable::Property prop;
- prop.mDocString = sg_tempFieldList[i].pFieldDocs;
- prop.mName = sg_tempFieldList[i].pFieldname;
- prop.mNumElements = sg_tempFieldList[i].elementCount;
- prop.mFlags = 0;
- if (sg_tempFieldList[i].type == StartGroupFieldType)
- prop.mFlags |= EnginePropertyGroupBegin;
- if (sg_tempFieldList[i].type == EndGroupFieldType)
- prop.mFlags |= EnginePropertyGroupEnd;
- prop.mType = sg_tempFieldList[i].type;
- props[i] = prop;
- }
- _smPropertyTable = EnginePropertyTable(sg_tempFieldList.size(), props);
- smPropertyTable = _smPropertyTable;
- const_cast<EngineTypeInfo*>(mTypeInfo)->mPropertyTable = &_smPropertyTable;
-
- // Let the base finish up.
- AbstractClassRep::init();
- }
-
- /// @name Console Type Interface
- /// @{
-
- virtual void setData(void* dptr, S32 argc, const char** argv, const EnumTable* tbl, BitSet32 flag)
- {
- if (argc == 1)
- {
- T** obj = (T**)dptr;
- *obj = dynamic_cast< T* >(T::__findObject(argv[0]));
- }
- else
- Con::errorf("Cannot set multiple args to a single ConsoleObject*.");
- }
-
- virtual const char* getData(void* dptr, const EnumTable* tbl, BitSet32 flag)
- {
- T** obj = (T**)dptr;
- return Con::getReturnBuffer(T::__getObjectId(*obj));
- }
-
- virtual const char* getTypeClassName() { return mClassName; }
- virtual const bool isDatablock() { return T::__smIsDatablock; };
- /// @}
- };
-
- template< class T >
- class ConcreteClassRep : public ConcreteAbstractClassRep<T>
- {
- public:
- ConcreteClassRep(const char* name,
- const char* conTypeName,
- S32* conTypeIdPtr,
- S32 netClassGroupMask,
- S32 netClassType,
- S32 netEventDir,
- AbstractClassRep* parent,
- const char* (*parentDesc)())
- : ConcreteAbstractClassRep<T>(name, conTypeName, conTypeIdPtr, netClassGroupMask, netClassType, netEventDir, parent, parentDesc)
- {
- }
-
- /// Wrap constructor.
- ConsoleObject* create() const { return new T; }
- };
- template< typename T > EnginePropertyTable ConcreteAbstractClassRep< T >::_smPropertyTable(0, NULL);
- template< typename T > EnginePropertyTable& ConcreteAbstractClassRep< T >::smPropertyTable = ConcreteAbstractClassRep< T >::_smPropertyTable;
- //------------------------------------------------------------------------------
- // Forward declaration of this function so it can be used in the class
- const char *defaultProtectedGetFn( void *obj, const char *data );
- bool defaultProtectedWriteFn(void* obj, StringTableEntry pFieldName);
- //=============================================================================
- // ConsoleObject.
- //=============================================================================
- /// Interface class to the console.
- ///
- /// @section ConsoleObject_basics The Basics
- ///
- /// Any object which you want to work with the console system should derive from this,
- /// and access functionality through the static interface.
- ///
- /// This class is always used with the DECLARE_CONOBJECT and IMPLEMENT_* macros.
- ///
- /// @code
- /// // A very basic example object. It will do nothing!
- /// class TorqueObject : public ConsoleObject {
- /// // Must provide a Parent typedef so the console system knows what we inherit from.
- /// typedef ConsoleObject Parent;
- ///
- /// // This does a lot of menial declaration for you.
- /// DECLARE_CONOBJECT(TorqueObject);
- ///
- /// // This is for us to register our fields in.
- /// static void initPersistFields();
- ///
- /// // A sample field.
- /// S8 mSample;
- /// }
- /// @endcode
- ///
- /// @code
- /// // And the accordant implementation...
- /// IMPLEMENT_CONOBJECT(TorqueObject);
- ///
- /// void TorqueObject::initPersistFields()
- /// {
- /// // If you want to inherit any fields from the parent (you do), do this:
- /// Parent::initPersistFields();
- ///
- /// // Pass the field, the type, the offset, and a usage string.
- /// addField("sample", TypeS8, Offset(mSample, TorqueObject), "A test field.");
- /// }
- /// @endcode
- ///
- /// That's all you need to do to get a class registered with the console system. At this point,
- /// you can instantiate it via script, tie methods to it using ConsoleMethod, register fields,
- /// and so forth. You can also register any global variables related to the class by creating
- /// a consoleInit() method.
- ///
- /// You will need to use different IMPLEMENT_ macros in different cases; for instance, if you
- /// are making a NetObject (for ghosting), a DataBlock, or a NetEvent.
- ///
- /// @see AbstractClassRep for gory implementation details.
- /// @nosubgrouping
- class ConsoleObject : public EngineObject
- {
- DECLARE_ABSTRACT_CLASS( ConsoleObject, EngineObject );
- protected:
- /// @deprecated This is disallowed.
- ConsoleObject(const ConsoleObject&);
- public:
- ConsoleObject() {}
- /// Get a reference to a field by name.
- const AbstractClassRep::Field *findField(StringTableEntry fieldName) const;
- /// Gets the ClassRep.
- virtual AbstractClassRep* getClassRep() const;
- #define DECLARE_ABSTRACT_CONOBJECT( className ) \
- DECLARE_ABSTRACT_CLASS( className, Parent ); \
- static S32 _smTypeId; \
- static ConcreteAbstractClassRep< className > dynClassRep; \
- static AbstractClassRep* getParentStaticClassRep(); \
- static AbstractClassRep* getStaticClassRep(); \
- static SimObjectRefConsoleBaseType< className > ptrRefType; \
- virtual AbstractClassRep* getClassRep() const
- /// Set the value of a field.
- bool setField(const char *fieldName, const char *value);
- public:
- /// @name Object Creation
- /// @{
- static ConsoleObject* create(const char* in_pClassName);
- static ConsoleObject* create(const U32 groupId, const U32 typeId, const U32 in_classId);
- /// @}
- public:
- /// Get the classname from a class tag.
- static const char* lookupClassName(const U32 in_classTag);
- /// @name Fields
- /// @{
- /// Mark the beginning of a group of fields.
- ///
- /// This is used in the consoleDoc system.
- /// @see console_autodoc
- static void addGroup(const char* in_pGroupname, const char* in_pGroupDocs = NULL);
- /// Mark the end of a group of fields.
- ///
- /// This is used in the consoleDoc system.
- /// @see console_autodoc
- static void endGroup(const char* in_pGroupname);
- /// Marks the start of a fixed size array of fields.
- /// @see console_autodoc
- static void addArray( const char *arrayName, S32 count );
- /// Marks the end of an array of fields.
- /// @see console_autodoc
- static void endArray( const char *arrayName );
- /// Register a complex field.
- ///
- /// @param in_pFieldname Name of the field.
- /// @param in_fieldType Type of the field. @see ConsoleDynamicTypes
- /// @param in_fieldOffset Offset to the field from the start of the class; calculated using the Offset() macro.
- /// @param in_elementCount Number of elements in this field. Arrays of elements are assumed to be contiguous in memory.
- /// @param in_pFieldDocs Usage string for this field. @see console_autodoc
- static void addField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- const U32 in_elementCount = 1,
- const char* in_pFieldDocs = NULL,
- U32 flags = 0 );
- static void addField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- AbstractClassRep::WriteDataNotify in_writeDataFn,
- const U32 in_elementCount = 1,
- const char* in_pFieldDocs = NULL,
- U32 flags = 0);
- /// Register a simple field.
- ///
- /// @param in_pFieldname Name of the field.
- /// @param in_fieldType Type of the field. @see ConsoleDynamicTypes
- /// @param in_fieldOffset Offset to the field from the start of the class; calculated using the Offset() macro.
- /// @param in_pFieldDocs Usage string for this field. @see console_autodoc
- static void addField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- const char* in_pFieldDocs,
- U32 flags = 0 );
- static void addField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- AbstractClassRep::WriteDataNotify in_writeDataFn,
- const char* in_pFieldDocs,
- U32 flags = 0);
- /// Register a validated field.
- ///
- /// A validated field is just like a normal field except that you can't
- /// have it be an array, and that you give it a pointer to a TypeValidator
- /// subclass, which is then used to validate any value placed in it. Invalid
- /// values are ignored and an error is printed to the console.
- ///
- /// @see addField
- /// @see typeValidators.h
- static void addFieldV(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- TypeValidator *v,
- const char * in_pFieldDocs = NULL);
- /// Register a complex protected field.
- ///
- /// @param in_pFieldname Name of the field.
- /// @param in_fieldType Type of the field. @see ConsoleDynamicTypes
- /// @param in_fieldOffset Offset to the field from the start of the class; calculated using the Offset() macro.
- /// @param in_setDataFn When this field gets set, it will call the callback provided. @see console_protected
- /// @param in_getDataFn When this field is accessed for it's data, it will return the value of this function
- /// @param in_elementCount Number of elements in this field. Arrays of elements are assumed to be contiguous in memory.
- /// @param in_pFieldDocs Usage string for this field. @see console_autodoc
- static void addProtectedField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- AbstractClassRep::SetDataNotify in_setDataFn,
- AbstractClassRep::GetDataNotify in_getDataFn = &defaultProtectedGetFn,
- AbstractClassRep::WriteDataNotify in_writeDataFn = &defaultProtectedWriteFn,
- const U32 in_elementCount = 1,
- const char* in_pFieldDocs = NULL,
- U32 flags = 0);
- static void addProtectedField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- AbstractClassRep::SetDataNotify in_setDataFn,
- AbstractClassRep::GetDataNotify in_getDataFn = &defaultProtectedGetFn,
- const U32 in_elementCount = 1,
- const char* in_pFieldDocs = NULL,
- U32 flags = 0);
- /// Register a simple protected field.
- ///
- /// @param in_pFieldname Name of the field.
- /// @param in_fieldType Type of the field. @see ConsoleDynamicTypes
- /// @param in_fieldOffset Offset to the field from the start of the class; calculated using the Offset() macro.
- /// @param in_setDataFn When this field gets set, it will call the callback provided. @see console_protected
- /// @param in_getDataFn When this field is accessed for it's data, it will return the value of this function
- /// @param in_pFieldDocs Usage string for this field. @see console_autodoc
- static void addProtectedField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- AbstractClassRep::SetDataNotify in_setDataFn,
- AbstractClassRep::GetDataNotify in_getDataFn = &defaultProtectedGetFn,
- AbstractClassRep::WriteDataNotify in_writeDataFn = &defaultProtectedWriteFn,
- const char* in_pFieldDocs = NULL,
- U32 flags = 0);
- static void addProtectedField(const char* in_pFieldname,
- const U32 in_fieldType,
- const dsize_t in_fieldOffset,
- AbstractClassRep::SetDataNotify in_setDataFn,
- AbstractClassRep::GetDataNotify in_getDataFn = &defaultProtectedGetFn,
- const char* in_pFieldDocs = NULL,
- U32 flags = 0);
- /// Add a deprecated field.
- ///
- /// A deprecated field will always be undefined, even if you assign a value to it. This
- /// is useful when you need to make sure that a field is not being used anymore.
- static void addDeprecatedField(const char *fieldName);
- /// Remove a field.
- ///
- /// Sometimes, you just have to remove a field!
- /// @returns True on success.
- static bool removeField(const char* in_pFieldname);
- /// @}
- /// @name Logging
- /// @{
- /// Overload this in subclasses to change the message formatting.
- /// @param fmt A printf style format string.
- /// @param args A va_list containing the args passed ot a log function.
- /// @note It is suggested that you use String::VToString.
- virtual String _getLogMessage(const char* fmt, va_list args) const;
- /// @}
- public:
- /// @name Logging
- /// These functions will try to print out a message along the lines
- /// of "ObjectClass - ObjectName(ObjectId) - formatted message"
- /// @{
- /// Logs with Con::printf.
- void logMessage(const char* fmt, ...) const;
- /// Logs with Con::warnf.
- void logWarning(const char* fmt, ...) const;
- /// Logs with Con::errorf.
- void logError(const char* fmt, ...) const;
- /// @}
- /// Register dynamic fields in a subclass of ConsoleObject.
- ///
- /// @see addField(), addFieldV(), addDeprecatedField(), addGroup(), endGroup()
- static void initPersistFields();
- /// Register global constant variables and do other one-time initialization tasks in
- /// a subclass of ConsoleObject.
- ///
- /// @deprecated You should use ConsoleMethod and ConsoleFunction, not this, to
- /// register methods or commands.
- /// @see console
- static void consoleInit();
- /// @name Field List
- /// @{
- /// Get a list of all the fields. This information cannot be modified.
- const AbstractClassRep::FieldList& getFieldList() const;
- /// Get a list of all the fields, set up so we can modify them.
- ///
- /// @note This is a bad trick to pull if you aren't very careful,
- /// since you can blast field data!
- AbstractClassRep::FieldList& getModifiableFieldList();
- /// Get a handle to a boolean telling us if we expanded the dynamic group.
- ///
- /// @see GuiInspector::Inspect()
- bool& getDynamicGroupExpand();
- /// @}
- /// @name ConsoleObject Implementation
- ///
- /// These functions are implemented in every subclass of
- /// ConsoleObject by an IMPLEMENT_CONOBJECT or IMPLEMENT_CO_* macro.
- /// @{
- /// Get the abstract class information for this class.
- static AbstractClassRep *getStaticClassRep() { return NULL; }
- /// Get the abstract class information for this class's superclass.
- static AbstractClassRep *getParentStaticClassRep() { return NULL; }
- /// Get our network-layer class id.
- ///
- /// @param netClassGroup The net class for which we want our ID.
- /// @see
- S32 getClassId(U32 netClassGroup) const;
- /// Get our compiler and platform independent class name.
- ///
- /// @note This name can be used to instantiate another instance using create()
- StringTableEntry getClassName() const;
- /// @}
- static const char* __category() { return ""; }
- static const char* __description() { return ""; }
- /// Subclasses of ConsoleObjects that are datablocks should redefine this static member variable
- /// and set it to true.
- static const bool __smIsDatablock = false;
- /// @name Object IDs and lookup.
- /// For a subclass hierarchy based on ConsoleObject to become functional for use as a console object type,
- /// the hierarchy must implement a naming scheme and indexing function for looking up objects by name.
- /// @{
- static ConsoleObject* __findObject( const char* ) { return NULL; }
- static const char* __getObjectId( ConsoleObject* ) { return ""; }
- protected:
- static bool disableFieldSubstitutions(const char* in_pFieldname);
- static bool onlyKeepClearSubstitutions(const char* in_pFieldname);
- };
- #define addNamedField(fieldName,type,className) addField(#fieldName, type, Offset(fieldName,className))
- #define addNamedFieldV(fieldName,type,className, validator) addFieldV(#fieldName, type, Offset(fieldName,className), validator)
- //------------------------------------------------------------------------------
- //-------------------------------------- Inlines
- //
- inline S32 ConsoleObject::getClassId(U32 netClassGroup) const
- {
- AssertFatal(getClassRep() != NULL,"Cannot get tag from non-declared dynamic class!");
- return getClassRep()->getClassId(netClassGroup);
- }
- inline StringTableEntry ConsoleObject::getClassName() const
- {
- AssertFatal(getClassRep() != NULL,
- "Cannot get tag from non-declared dynamic class");
- return getClassRep()->getClassName();
- }
- inline const AbstractClassRep::Field * ConsoleObject::findField(StringTableEntry name) const
- {
- AssertFatal(getClassRep() != NULL,
- avar("Cannot get field '%s' from non-declared dynamic class.", name));
- return getClassRep()->findField(name);
- }
- inline bool ConsoleObject::setField(const char *fieldName, const char *value)
- {
- //sanity check
- if ((! fieldName) || (! fieldName[0]) || (! value))
- return false;
- if (! getClassRep())
- return false;
- const AbstractClassRep::Field *myField = getClassRep()->findField(StringTable->insert(fieldName));
- if (! myField)
- return false;
- Con::setData(
- myField->type,
- (void *) (((const char *)(this)) + myField->offset),
- 0,
- 1,
- &value,
- myField->table,
- myField->flag);
- return true;
- }
- inline ConsoleObject* ConsoleObject::create(const char* in_pClassName)
- {
- return AbstractClassRep::create(in_pClassName);
- }
- inline ConsoleObject* ConsoleObject::create(const U32 groupId, const U32 typeId, const U32 in_classId)
- {
- return AbstractClassRep::create(groupId, typeId, in_classId);
- }
- inline const AbstractClassRep::FieldList& ConsoleObject::getFieldList() const
- {
- return getClassRep()->mFieldList;
- }
- inline AbstractClassRep::FieldList& ConsoleObject::getModifiableFieldList()
- {
- return getClassRep()->mFieldList;
- }
- inline bool& ConsoleObject::getDynamicGroupExpand()
- {
- return getClassRep()->mDynamicGroupExpand;
- }
- /// @name ConsoleObject Macros
- /// @{
- #define DECLARE_CONOBJECT( className ) \
- DECLARE_CLASS( className, Parent ); \
- static S32 _smTypeId; \
- static ConcreteClassRep< className > dynClassRep; \
- static AbstractClassRep* getParentStaticClassRep(); \
- static AbstractClassRep* getStaticClassRep(); \
- static SimObjectRefConsoleBaseType< className > ptrRefType; \
- static AbstractClassRep::WriteCustomTamlSchema getStaticWriteCustomTamlSchema(); \
- static AbstractClassRep* getContainerChildStaticClassRep(); \
- virtual AbstractClassRep* getClassRep() const
- #define DECLARE_CATEGORY( string ) \
- static const char* __category() { return string; }
- #define DECLARE_DESCRIPTION( string ) \
- static const char* __description() { return string; }
- #define IMPLEMENT_CONOBJECT( className ) \
- IMPLEMENT_CLASS( className, NULL ) \
- END_IMPLEMENT_CLASS; \
- S32 className::_smTypeId; \
- SimObjectRefConsoleBaseType< className > className::ptrRefType( "Type" #className "Ref" ); \
- AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
- AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
- AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
- AbstractClassRep* className::getContainerChildStaticClassRep() { return NULL; } \
- AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return NULL; } \
- ConcreteClassRep<className> className::dynClassRep( #className, "Type" #className, &_smTypeId, 0, -1, 0, className::getParentStaticClassRep(), &Parent::__description )
- #define IMPLEMENT_CONOBJECT_CHILDREN( className ) \
- IMPLEMENT_CLASS( className, NULL ) \
- END_IMPLEMENT_CLASS; \
- S32 className::_smTypeId; \
- SimObjectRefConsoleBaseType< className > className::ptrRefType( "Type" #className "Ref" ); \
- AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
- AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
- AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
- AbstractClassRep* className::getContainerChildStaticClassRep() { return Children::getStaticClassRep(); } \
- AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return NULL; } \
- ConcreteClassRep<className> className::dynClassRep( #className, "Type" #className, &_smTypeId, 0, -1, 0, className::getParentStaticClassRep(), &Parent::__description )
- #define IMPLEMENT_CONOBJECT_SCHEMA( className, schema ) \
- IMPLEMENT_CLASS( className, NULL ) \
- END_IMPLEMENT_CLASS; \
- S32 className::_smTypeId; \
- SimObjectRefConsoleBaseType< className > className::ptrRefType( "Type" #className "Ref" ); \
- AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
- AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
- AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
- AbstractClassRep* className::getContainerChildStaticClassRep() { return NULL; } \
- AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return schema; } \
- ConcreteClassRep<className> className::dynClassRep( #className, "Type" #className, &_smTypeId, 0, -1, 0, className::getParentStaticClassRep(), &Parent::__description )
- #define IMPLEMENT_CONOBJECT_CHILDREN_SCHEMA( className, schema ) \
- IMPLEMENT_CLASS( className, NULL ) \
- END_IMPLEMENT_CLASS; \
- S32 className::_smTypeId; \
- SimObjectRefConsoleBaseType< className > className::ptrRefType( "Type" #className "Ref" ); \
- AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
- AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
- AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
- AbstractClassRep* className::getContainerChildStaticClassRep() { return Children::getStaticClassRep(); } \
- AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return schema; } \
- ConcreteClassRep<className> className::dynClassRep( #className, "Type" #className, &_smTypeId, 0, -1, 0, className::getParentStaticClassRep(), &Parent::__description )
- #define IMPLEMENT_ABSTRACT_CONOBJECT( className ) \
- IMPLEMENT_NONINSTANTIABLE_CLASS( className, NULL ) \
- END_IMPLEMENT_CLASS; \
- S32 className::_smTypeId; \
- SimObjectRefConsoleBaseType< className > className::ptrRefType( "Type" #className "Ref" ); \
- AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
- AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
- AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
- ConcreteAbstractClassRep<className> className::dynClassRep( #className, "Type" #className, &_smTypeId, 0, -1, 0, className::getParentStaticClassRep(), &Parent::__description )
- #define IMPLEMENT_CO_NETOBJECT_V1( className ) \
- IMPLEMENT_CLASS( className, NULL ) \
- END_IMPLEMENT_CLASS; \
- S32 className::_smTypeId; \
- SimObjectRefConsoleBaseType< className > className::ptrRefType( "Type" #className "Ref" ); \
- AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
- AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
- AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
- AbstractClassRep* className::getContainerChildStaticClassRep() { return NULL; } \
- AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return NULL; } \
- ConcreteClassRep<className> className::dynClassRep( #className, "Type" #className, &_smTypeId, NetClassGroupGameMask, NetClassTypeObject, 0, className::getParentStaticClassRep(), &Parent::__description )
- #define IMPLEMENT_CO_DATABLOCK_V1( className ) \
- IMPLEMENT_CLASS( className, NULL ) \
- END_IMPLEMENT_CLASS; \
- S32 className::_smTypeId; \
- SimObjectRefConsoleBaseType< className > className::ptrRefType( "Type" #className "Ref" ); \
- AbstractClassRep* className::getClassRep() const { return &className::dynClassRep; } \
- AbstractClassRep* className::getStaticClassRep() { return &dynClassRep; } \
- AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
- AbstractClassRep* className::getContainerChildStaticClassRep() { return NULL; } \
- AbstractClassRep::WriteCustomTamlSchema className::getStaticWriteCustomTamlSchema() { return NULL; } \
- ConcreteClassRep<className> className::dynClassRep(#className, "Type" #className, &_smTypeId, NetClassGroupGameMask, NetClassTypeDataBlock, 0, className::getParentStaticClassRep(), &Parent::__description )
- // Support for adding properties to classes CONOBJECT style.
- #define PROPERTY_TABLE( className ) \
- namespace { namespace _ ## className { \
- extern EnginePropertyTable _propTable; \
- } } \
- template<> EnginePropertyTable& \
- ConcreteClassRep< className >::smPropertyTable = _ ## className::_propTable; \
- namespace { namespace _ ## className { \
- EnginePropertyTable::Property _props[] = {
- #define END_PROPERTY_TABLE \
- { NULL } \
- }; \
- EnginePropertyTable _propTable( sizeof( _props ) / sizeof( _props[ 0 ] ) - 1, _props ); \
- } }
- /// @}
- //------------------------------------------------------------------------------
- // Protected field default get/set functions
- //
- // The reason for these functions is that it will save one branch per console
- // data request and script functions will still execute at the same speed as
- // before the modifications to allow protected static fields. These will just
- // inline and the code should be roughly the same size, and just as fast as
- // before the modifications. -pw
- inline bool defaultProtectedSetFn( void *object, const char *index, const char *data )
- {
- return true;
- }
- inline bool defaultProtectedSetNotEmptyFn( void *object, const char *index, const char *data )
- {
- return data && data[0];
- }
- inline const char *defaultProtectedGetFn( void *obj, const char *data )
- {
- return data;
- }
- inline const char *emptyStringProtectedGetFn( void *obj, const char *data )
- {
- return "";
- }
- inline bool defaultProtectedWriteFn(void* obj, StringTableEntry pFieldName)
- {
- return true;
- }
- inline bool defaultProtectedNotSetFn(void* obj, const char *array, const char* data)
- {
- return false;
- }
- inline bool defaultProtectedNotWriteFn(void* obj, StringTableEntry pFieldName)
- {
- return false;
- }
- /// @}
- #endif //_CONSOLEOBJECT_H_
|