Torque3D/Engine/source/console/runtimeClassRep.h
marauder2k7 2b295fb7f0 rest of virtuals removed
virtuals removed and replaced with override where necessary on the rest of the code base, clang-tidy to the rescue.
2024-03-18 18:40:22 +00:00

196 lines
7.4 KiB
C++

//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
#ifndef _RUNTIME_CLASSREP_H_
#define _RUNTIME_CLASSREP_H_
#include "console/consoleObject.h"
#include "console/consoleInternal.h"
/// This class is to allow new types to be added, at run-time, to Torque.
/// This is primarily for dynamic libraries, plugins etc.
///
/// The idea is the same, one instance per type which is getting registered
/// however it doesn't get added to the dictionary until it is told to
/// add itself. It can be removed, as well, though no safe-execution
/// assurances are made by this class. If an object type is removed
/// behavior of existing console objects of that type is undefined.
/// (aka bad stuff will probably happen but I don't know exactly what)
template <class T>
class RuntimeClassRep : public AbstractClassRep
{
protected:
static bool smConRegistered; ///< This variable will be set to true if this class-rep is currently registered
public:
RuntimeClassRep( const char *name, const char* conTypeName, S32* conTypeIdPtr, S32 netClassGroupMask, S32 netClassType, S32 netEventDir, AbstractClassRep *parent )
: AbstractClassRep( conTypeIdPtr, conTypeName )
{
// name is a static compiler string so no need to worry about copying or deleting
mClassName = name;
mTypeInfo = _MAPTYPE< T >();
// 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;
};
AbstractClassRep* getContainerChildClass(const bool recurse) override
{
// 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);
}
WriteCustomTamlSchema getCustomTamlSchema(void) override
{
return T::getStaticWriteCustomTamlSchema();
}
/// Perform class specific initialization tasks.
///
/// Link namespaces, call initPersistFields() and consoleInit().
void init() const
{
// 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();
}
/// Wrap constructor.
ConsoleObject *create() const override { return new T; }
//-----------------------------------------------------------------------------
/// Register this class with the Torque console
void consoleRegister()
{
AssertFatal( !smConRegistered, "Calling consoleRegister, but this type is already linked into the class list" );
if( !smConRegistered )
registerClassRep( this );
// Now initialize the namespace
mNamespace = Con::lookupNamespace( StringTable->insert( getClassName() ) );
mNamespace->mClassRep = this;
// Perform field initialization
sg_tempFieldList.setSize(0);
init();
// So if we have things in it, copy it over...
if ( sg_tempFieldList.size() != 0 )
mFieldList = sg_tempFieldList;
// And of course delete it every round.
sg_tempFieldList.clear();
smConRegistered = true;
}
/// Unregister this class with the Torque console
void consoleUnRegister()
{
AssertFatal( smConRegistered, "Calling consoleUnRegister, but this type is not linked into the class list" );
if( !smConRegistered )
return;
removeClassRep( this );
smConRegistered = false;
}
/// Returns true if this class type is registered with the console system
static const bool isRegistered() { return smConRegistered; }
/// @name Console Type Interface
/// @{
void setData( void* dptr, S32 argc, const char** argv, const EnumTable* tbl, BitSet32 flag ) override
{
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*.");
}
const char* getData( void* dptr, const EnumTable* tbl, BitSet32 flag ) override
{
T** obj = ( T** ) dptr;
return Con::getReturnBuffer( T::__getObjectId( *obj ) );
}
const char* getTypeClassName() override { return mClassName; }
const bool isDatablock() override { return T::__smIsDatablock; };
/// @}
};
template<class T> bool RuntimeClassRep<T>::smConRegistered = false;
//-----------------------------------------------------------------------------
#define DECLARE_RUNTIME_CONOBJECT(className) \
DECLARE_CLASS( className, Parent ); \
static S32 _sTypeId; \
static RuntimeClassRep<className> dynRTClassRep; \
static AbstractClassRep* getParentStaticClassRep(); \
static AbstractClassRep* getStaticClassRep(); \
virtual AbstractClassRep* getClassRep() const
#define IMPLEMENT_RUNTIME_CONOBJECT(className) \
IMPLEMENT_CLASS( className, NULL ) \
END_IMPLEMENT_CLASS; \
S32 className::_sTypeId; \
AbstractClassRep* className::getClassRep() const { return &className::dynRTClassRep; } \
AbstractClassRep* className::getStaticClassRep() { return &dynRTClassRep; } \
AbstractClassRep* className::getParentStaticClassRep() { return Parent::getStaticClassRep(); } \
RuntimeClassRep<className> className::dynRTClassRep(#className, "Type" #className, &_sTypeId, 0, -1, 0, className::getParentStaticClassRep())
#endif