2016-05-14 05:00:02 +00:00
//-----------------------------------------------------------------------------
// 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.
//-----------------------------------------------------------------------------
# include "platform/platform.h"
# include "console/simBase.h"
# include "console/consoleTypes.h"
2016-05-26 06:37:14 +00:00
# include "T3D/components/component.h"
2016-05-14 05:00:02 +00:00
# include "core/util/safeDelete.h"
# include "core/resourceManager.h"
# include "core/stream/fileStream.h"
# include "core/stream/bitStream.h"
# include "console/engineAPI.h"
# include "sim/netConnection.h"
# include "console/consoleInternal.h"
2018-01-28 20:57:02 +00:00
# include "T3D/assets/MaterialAsset.h"
2016-05-14 05:00:02 +00:00
# define DECLARE_NATIVE_COMPONENT( ComponentType ) \
Component * staticComponentTemplate = new ComponentType ; \
Sim : : gNativeComponentSet - > addObject ( staticComponentTemplate ) ;
//////////////////////////////////////////////////////////////////////////
// Constructor/Destructor
//////////////////////////////////////////////////////////////////////////
Component : : Component ( )
{
2017-10-15 09:42:30 +00:00
mFriendlyName = StringTable - > EmptyString ( ) ;
mFromResource = StringTable - > EmptyString ( ) ;
mComponentType = StringTable - > EmptyString ( ) ;
mComponentGroup = StringTable - > EmptyString ( ) ;
mNetworkType = StringTable - > EmptyString ( ) ;
mTemplateName = StringTable - > EmptyString ( ) ;
//mDependency = StringTable->EmptyString();
2016-05-14 05:00:02 +00:00
mNetworked = false ;
// [tom, 1/12/2007] We manage the memory for the description since it
// could be loaded from a file and thus massive. This is accomplished with
// protected fields, but since they still call Con::getData() the field
// needs to always be valid. This is pretty lame.
mDescription = new char [ 1 ] ;
( ( char * ) mDescription ) [ 0 ] = 0 ;
mOwner = NULL ;
mCanSaveFieldDictionary = false ;
2017-10-15 09:42:30 +00:00
mOriginatingAssetId = StringTable - > EmptyString ( ) ;
2018-01-28 20:57:02 +00:00
mIsServerObject = true ;
2018-02-04 22:21:07 +00:00
componentIdx = 0 ;
mHidden = false ;
mEnabled = true ;
mDirtyMaskBits = 0 ;
2016-05-14 05:00:02 +00:00
}
Component : : ~ Component ( )
{
for ( S32 i = 0 ; i < mFields . size ( ) ; + + i )
{
ComponentField & field = mFields [ i ] ;
SAFE_DELETE_ARRAY ( field . mFieldDescription ) ;
}
SAFE_DELETE_ARRAY ( mDescription ) ;
}
IMPLEMENT_CO_NETOBJECT_V1 ( Component ) ;
//////////////////////////////////////////////////////////////////////////
void Component : : initPersistFields ( )
{
addGroup ( " Component " ) ;
addField ( " componentType " , TypeCaseString , Offset ( mComponentType , Component ) , " The type of behavior. " , AbstractClassRep : : FieldFlags : : FIELD_HideInInspectors ) ;
addField ( " networkType " , TypeCaseString , Offset ( mNetworkType , Component ) , " The type of behavior. " , AbstractClassRep : : FieldFlags : : FIELD_HideInInspectors ) ;
addField ( " friendlyName " , TypeCaseString , Offset ( mFriendlyName , Component ) , " Human friendly name of this behavior " , AbstractClassRep : : FieldFlags : : FIELD_HideInInspectors ) ;
addProtectedField ( " description " , TypeCaseString , Offset ( mDescription , Component ) , & setDescription , & getDescription ,
" The description of this behavior which can be set to a \" string \" or a fileName \n " , AbstractClassRep : : FieldFlags : : FIELD_HideInInspectors ) ;
addField ( " networked " , TypeBool , Offset ( mNetworked , Component ) , " Is this behavior ghosted to clients? " , AbstractClassRep : : FieldFlags : : FIELD_HideInInspectors ) ;
addProtectedField ( " Owner " , TypeSimObjectPtr , Offset ( mOwner , Component ) , & setOwner , & defaultProtectedGetFn , " " , AbstractClassRep : : FieldFlags : : FIELD_HideInInspectors ) ;
//addField("hidden", TypeBool, Offset(mHidden, Component), "Flags if this behavior is shown in the editor or not", AbstractClassRep::FieldFlags::FIELD_HideInInspectors);
addProtectedField ( " enabled " , TypeBool , Offset ( mEnabled , Component ) , & _setEnabled , & defaultProtectedGetFn , " " ) ;
2017-10-15 09:42:30 +00:00
addField ( " originatingAsset " , TypeComponentAssetPtr , Offset ( mOriginatingAsset , Component ) ,
" Asset that spawned this component, used for tracking/housekeeping " , AbstractClassRep : : FieldFlags : : FIELD_HideInInspectors ) ;
2016-05-14 05:00:02 +00:00
endGroup ( " Component " ) ;
Parent : : initPersistFields ( ) ;
//clear out irrelevent fields
removeField ( " name " ) ;
//removeField("internalName");
removeField ( " parentGroup " ) ;
//removeField("class");
removeField ( " superClass " ) ;
removeField ( " hidden " ) ;
removeField ( " canSave " ) ;
removeField ( " canSaveDynamicFields " ) ;
removeField ( " persistentId " ) ;
}
bool Component : : _setEnabled ( void * object , const char * index , const char * data )
{
Component * c = static_cast < Component * > ( object ) ;
c - > mEnabled = dAtob ( data ) ;
c - > setMaskBits ( EnableMask ) ;
return true ;
}
//////////////////////////////////////////////////////////////////////////
bool Component : : setDescription ( void * object , const char * index , const char * data )
{
Component * bT = static_cast < Component * > ( object ) ;
SAFE_DELETE_ARRAY ( bT - > mDescription ) ;
bT - > mDescription = bT - > getDescriptionText ( data ) ;
// We return false since we don't want the console to mess with the data
return false ;
}
const char * Component : : getDescription ( void * obj , const char * data )
{
Component * object = static_cast < Component * > ( obj ) ;
return object - > mDescription ? object - > mDescription : " " ;
}
//////////////////////////////////////////////////////////////////////////
bool Component : : onAdd ( )
{
if ( ! Parent : : onAdd ( ) )
return false ;
setMaskBits ( UpdateMask ) ;
2017-10-15 09:42:30 +00:00
setMaskBits ( NamespaceMask ) ;
2016-05-14 05:00:02 +00:00
return true ;
}
void Component : : onRemove ( )
{
onDataSet . removeAll ( ) ;
if ( mOwner )
{
//notify our removal to the owner, so we have no loose ends
mOwner - > removeComponent ( this , false ) ;
}
Parent : : onRemove ( ) ;
}
void Component : : onComponentAdd ( )
{
if ( isServerObject ( ) )
{
if ( isMethod ( " onAdd " ) )
Con : : executef ( this , " onAdd " ) ;
}
mEnabled = true ;
}
void Component : : onComponentRemove ( )
{
mEnabled = false ;
if ( isServerObject ( ) )
{
if ( isMethod ( " onRemove " ) )
Con : : executef ( this , " onRemove " ) ;
}
if ( mOwner )
{
mOwner - > onComponentAdded . remove ( this , & Component : : componentAddedToOwner ) ;
mOwner - > onComponentRemoved . remove ( this , & Component : : componentRemovedFromOwner ) ;
}
mOwner = NULL ;
setDataField ( " owner " , NULL , " " ) ;
}
void Component : : setOwner ( Entity * owner )
{
//first, catch if we have an existing owner, and we're changing from it
if ( mOwner & & mOwner ! = owner )
{
mOwner - > onComponentAdded . remove ( this , & Component : : componentAddedToOwner ) ;
mOwner - > onComponentRemoved . remove ( this , & Component : : componentRemovedFromOwner ) ;
mOwner - > removeComponent ( this , false ) ;
}
mOwner = owner ;
if ( mOwner ! = NULL )
{
mOwner - > onComponentAdded . notify ( this , & Component : : componentAddedToOwner ) ;
mOwner - > onComponentRemoved . notify ( this , & Component : : componentRemovedFromOwner ) ;
}
if ( isServerObject ( ) )
2018-01-28 20:57:02 +00:00
{
2016-05-14 05:00:02 +00:00
setMaskBits ( OwnerMask ) ;
2018-01-28 20:57:02 +00:00
//if we have any outstanding maskbits, push them along to have the network update happen on the entity
if ( mDirtyMaskBits ! = 0 & & mOwner )
{
mOwner - > setMaskBits ( Entity : : ComponentsUpdateMask ) ;
}
}
2016-05-14 05:00:02 +00:00
}
void Component : : componentAddedToOwner ( Component * comp )
{
return ;
}
void Component : : componentRemovedFromOwner ( Component * comp )
{
return ;
}
2018-01-28 20:57:02 +00:00
void Component : : setMaskBits ( U32 orMask )
2016-05-14 05:00:02 +00:00
{
2018-01-28 20:57:02 +00:00
AssertFatal ( orMask ! = 0 , " Invalid net mask bits set. " ) ;
if ( mOwner )
mOwner - > setComponentNetMask ( this , orMask ) ;
2016-05-14 05:00:02 +00:00
}
U32 Component : : packUpdate ( NetConnection * con , U32 mask , BitStream * stream )
{
2018-01-28 20:57:02 +00:00
U32 retMask = 0 ;
2016-05-14 05:00:02 +00:00
2018-01-28 20:57:02 +00:00
/*if (mask & OwnerMask)
2016-05-14 05:00:02 +00:00
{
if ( mOwner ! = NULL )
{
S32 ghostIndex = con - > getGhostIndex ( mOwner ) ;
if ( ghostIndex = = - 1 )
{
stream - > writeFlag ( false ) ;
retMask | = OwnerMask ;
}
else
{
stream - > writeFlag ( true ) ;
stream - > writeFlag ( true ) ;
stream - > writeInt ( ghostIndex , NetConnection : : GhostIdBitSize ) ;
}
}
else
{
stream - > writeFlag ( true ) ;
stream - > writeFlag ( false ) ;
}
}
else
2018-01-28 20:57:02 +00:00
stream - > writeFlag ( false ) ; */
2016-05-14 05:00:02 +00:00
if ( stream - > writeFlag ( mask & EnableMask ) )
{
stream - > writeFlag ( mEnabled ) ;
}
2017-10-15 09:42:30 +00:00
/*if (stream->writeFlag(mask & NamespaceMask))
{
const char * name = getName ( ) ;
if ( stream - > writeFlag ( name & & name [ 0 ] ) )
stream - > writeString ( String ( name ) ) ;
if ( stream - > writeFlag ( mSuperClassName & & mSuperClassName [ 0 ] ) )
stream - > writeString ( String ( mSuperClassName ) ) ;
if ( stream - > writeFlag ( mClassName & & mClassName [ 0 ] ) )
stream - > writeString ( String ( mClassName ) ) ;
} */
2016-05-14 05:00:02 +00:00
return retMask ;
}
void Component : : unpackUpdate ( NetConnection * con , BitStream * stream )
{
2018-01-28 20:57:02 +00:00
/*if (stream->readFlag())
2016-05-14 05:00:02 +00:00
{
if ( stream - > readFlag ( ) )
{
//we have an owner object, so fetch it
S32 gIndex = stream - > readInt ( NetConnection : : GhostIdBitSize ) ;
Entity * e = dynamic_cast < Entity * > ( con - > resolveGhost ( gIndex ) ) ;
if ( e )
e - > addComponent ( this ) ;
}
else
{
//it's being nulled out
setOwner ( NULL ) ;
}
2018-01-28 20:57:02 +00:00
} */
2016-05-14 05:00:02 +00:00
if ( stream - > readFlag ( ) )
{
mEnabled = stream - > readFlag ( ) ;
}
2017-10-15 09:42:30 +00:00
/*if (stream->readFlag())
{
if ( stream - > readFlag ( ) )
{
char name [ 256 ] ;
stream - > readString ( name ) ;
assignName ( name ) ;
}
if ( stream - > readFlag ( ) )
{
char superClassname [ 256 ] ;
stream - > readString ( superClassname ) ;
mSuperClassName = superClassname ;
}
if ( stream - > readFlag ( ) )
{
char classname [ 256 ] ;
stream - > readString ( classname ) ;
mClassName = classname ;
}
linkNamespaces ( ) ;
} */
2016-05-14 05:00:02 +00:00
}
void Component : : packToStream ( Stream & stream , U32 tabStop , S32 behaviorID , U32 flags /* = 0 */ )
{
char buffer [ 1024 ] ;
writeFields ( stream , tabStop ) ;
// Write out the fields which the behavior template knows about
for ( int i = 0 ; i < getComponentFieldCount ( ) ; i + + )
{
ComponentField * field = getComponentField ( i ) ;
const char * objFieldValue = getDataField ( field - > mFieldName , NULL ) ;
// If the field holds the same value as the template's default value than it
// will get initialized by the template, and so it won't be included just
// to try to keep the object files looking as non-horrible as possible.
if ( dStrcmp ( field - > mDefaultValue , objFieldValue ) ! = 0 )
{
dSprintf ( buffer , sizeof ( buffer ) , " %s = \" %s \" ; \n " , field - > mFieldName , ( dStrlen ( objFieldValue ) > 0 ? objFieldValue : " 0 " ) ) ;
stream . writeTabs ( tabStop ) ;
stream . write ( dStrlen ( buffer ) , buffer ) ;
}
}
}
void Component : : processTick ( )
{
if ( isServerObject ( ) & & mEnabled )
{
if ( mOwner ! = NULL & & isMethod ( " Update " ) )
Con : : executef ( this , " Update " ) ;
}
}
void Component : : setDataField ( StringTableEntry slotName , const char * array , const char * value )
{
Parent : : setDataField ( slotName , array , value ) ;
onDataSet . trigger ( this , slotName , value ) ;
}
2017-10-15 09:42:30 +00:00
StringTableEntry Component : : getComponentName ( )
{
return getNamespace ( ) - > getName ( ) ;
}
2016-05-14 05:00:02 +00:00
//catch any behavior field updates
void Component : : onStaticModified ( const char * slotName , const char * newValue )
{
Parent : : onStaticModified ( slotName , newValue ) ;
//If we don't have an owner yet, then this is probably the initial setup, so we don't need the console callbacks yet.
if ( ! mOwner )
return ;
onDataSet . trigger ( this , slotName , newValue ) ;
checkComponentFieldModified ( slotName , newValue ) ;
}
void Component : : onDynamicModified ( const char * slotName , const char * newValue )
{
Parent : : onDynamicModified ( slotName , newValue ) ;
//If we don't have an owner yet, then this is probably the initial setup, so we don't need the console callbacks yet.
if ( ! mOwner )
return ;
checkComponentFieldModified ( slotName , newValue ) ;
}
void Component : : checkComponentFieldModified ( const char * slotName , const char * newValue )
{
StringTableEntry slotNameEntry = StringTable - > insert ( slotName ) ;
//find if it's a behavior field
for ( int i = 0 ; i < mFields . size ( ) ; i + + )
{
ComponentField * field = getComponentField ( i ) ;
if ( field - > mFieldName = = slotNameEntry )
{
//we have a match, do the script callback that we updated a field
if ( isMethod ( " onInspectorUpdate " ) )
Con : : executef ( this , " onInspectorUpdate " , slotName ) ;
return ;
}
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
void Component : : addComponentField ( const char * fieldName , const char * desc , const char * type , const char * defaultValue /* = NULL */ , const char * userData /* = NULL */ , /*const char* dependency /* = NULL */ /*,*/ bool hidden /* = false */ )
{
StringTableEntry stFieldName = StringTable - > insert ( fieldName ) ;
for ( S32 i = 0 ; i < mFields . size ( ) ; + + i )
{
if ( mFields [ i ] . mFieldName = = stFieldName )
return ;
}
ComponentField field ;
field . mFieldName = stFieldName ;
//find the field type
S32 fieldTypeMask = - 1 ;
StringTableEntry fieldType = StringTable - > insert ( type ) ;
2016-06-03 03:40:29 +00:00
if ( fieldType = = StringTable - > insert ( " int " ) )
2016-05-14 05:00:02 +00:00
fieldTypeMask = TypeS32 ;
2016-06-03 03:40:29 +00:00
else if ( fieldType = = StringTable - > insert ( " float " ) )
2016-05-14 05:00:02 +00:00
fieldTypeMask = TypeF32 ;
2016-06-03 03:40:29 +00:00
else if ( fieldType = = StringTable - > insert ( " vector " ) )
2016-05-14 05:00:02 +00:00
fieldTypeMask = TypePoint3F ;
2016-06-03 03:40:29 +00:00
else if ( fieldType = = StringTable - > insert ( " material " ) )
2018-01-28 20:57:02 +00:00
fieldTypeMask = TypeMaterialAssetPtr ;
2016-06-03 03:40:29 +00:00
else if ( fieldType = = StringTable - > insert ( " image " ) )
2016-05-14 05:00:02 +00:00
fieldTypeMask = TypeImageFilename ;
2016-06-03 03:40:29 +00:00
else if ( fieldType = = StringTable - > insert ( " shape " ) )
2016-05-14 05:00:02 +00:00
fieldTypeMask = TypeShapeFilename ;
2016-06-03 03:40:29 +00:00
else if ( fieldType = = StringTable - > insert ( " bool " ) )
2016-05-14 05:00:02 +00:00
fieldTypeMask = TypeBool ;
2016-06-03 03:40:29 +00:00
else if ( fieldType = = StringTable - > insert ( " object " ) )
fieldTypeMask = TypeSimObjectPtr ;
2017-10-15 09:42:30 +00:00
else if ( fieldType = = StringTable - > insert ( " string " ) )
fieldTypeMask = TypeString ;
else if ( fieldType = = StringTable - > insert ( " colorI " ) )
fieldTypeMask = TypeColorI ;
else if ( fieldType = = StringTable - > insert ( " colorF " ) )
fieldTypeMask = TypeColorF ;
else if ( fieldType = = StringTable - > insert ( " ease " ) )
fieldTypeMask = TypeEaseF ;
else if ( fieldType = = StringTable - > insert ( " gameObject " ) )
fieldTypeMask = TypeGameObjectAssetPtr ;
2016-05-14 05:00:02 +00:00
else
fieldTypeMask = TypeString ;
2018-01-28 20:57:02 +00:00
field . mFieldTypeName = fieldType ;
2016-05-14 05:00:02 +00:00
field . mFieldType = fieldTypeMask ;
field . mUserData = StringTable - > insert ( userData ? userData : " " ) ;
field . mDefaultValue = StringTable - > insert ( defaultValue ? defaultValue : " " ) ;
field . mFieldDescription = getDescriptionText ( desc ) ;
field . mGroup = mComponentGroup ;
field . mHidden = hidden ;
mFields . push_back ( field ) ;
//Before we set this, we need to do a test to see if this field was already set, like from the mission file or a taml file
const char * curFieldData = getDataField ( field . mFieldName , NULL ) ;
if ( dStrIsEmpty ( curFieldData ) )
setDataField ( field . mFieldName , NULL , field . mDefaultValue ) ;
}
ComponentField * Component : : getComponentField ( const char * fieldName )
{
StringTableEntry stFieldName = StringTable - > insert ( fieldName ) ;
for ( S32 i = 0 ; i < mFields . size ( ) ; + + i )
{
if ( mFields [ i ] . mFieldName = = stFieldName )
return & mFields [ i ] ;
}
return NULL ;
}
//////////////////////////////////////////////////////////////////////////
const char * Component : : getDescriptionText ( const char * desc )
{
if ( desc = = NULL )
return NULL ;
2018-02-04 22:21:07 +00:00
char * newDesc = " " ;
2016-05-14 05:00:02 +00:00
// [tom, 1/12/2007] If it isn't a file, just do it the easy way
if ( ! Platform : : isFile ( desc ) )
{
newDesc = new char [ dStrlen ( desc ) + 1 ] ;
dStrcpy ( newDesc , desc ) ;
return newDesc ;
}
FileStream str ;
str . open ( desc , Torque : : FS : : File : : Read ) ;
Stream * stream = & str ;
if ( stream = = NULL ) {
str . close ( ) ;
return NULL ;
}
U32 size = stream - > getStreamSize ( ) ;
if ( size > 0 )
{
newDesc = new char [ size + 1 ] ;
if ( stream - > read ( size , ( void * ) newDesc ) )
newDesc [ size ] = 0 ;
else
{
SAFE_DELETE_ARRAY ( newDesc ) ;
}
}
str . close ( ) ;
2018-02-04 22:21:07 +00:00
//delete stream;
2016-05-14 05:00:02 +00:00
return newDesc ;
}
//////////////////////////////////////////////////////////////////////////
void Component : : beginFieldGroup ( const char * groupName )
{
if ( dStrcmp ( mComponentGroup , " " ) )
{
Con : : errorf ( " Component: attempting to begin new field group with a group already begun! " ) ;
return ;
}
mComponentGroup = StringTable - > insert ( groupName ) ;
}
void Component : : endFieldGroup ( )
{
mComponentGroup = StringTable - > insert ( " " ) ;
}
void Component : : addDependency ( StringTableEntry name )
{
mDependencies . push_back_unique ( name ) ;
}
//////////////////////////////////////////////////////////////////////////
// Console Methods
//////////////////////////////////////////////////////////////////////////
ConsoleMethod ( Component , beginGroup , void , 3 , 3 , " (groupName) \n "
" Starts the grouping for following fields being added to be grouped into \n "
" @param groupName The name of this group \n "
" @param desc The Description of this field \n "
" @param type The DataType for this field (default, int, float, Point2F, bool, enum, Object, keybind, color) \n "
" @param defaultValue The Default value for this field \n "
" @param userData An extra data field that can be used for custom data on a per-field basis<br>Usage for default types<br> "
" -enum: a TAB separated list of possible values<br> "
" -object: the T2D object type that are valid choices for the field. The object types observe inheritance, so if you have a t2dSceneObject field you will be able to choose t2dStaticSrpites, t2dAnimatedSprites, etc. \n "
" @return Nothing \n " )
{
object - > beginFieldGroup ( argv [ 2 ] ) ;
}
ConsoleMethod ( Component , endGroup , void , 2 , 2 , " () \n "
" Ends the grouping for prior fields being added to be grouped into \n "
" @param groupName The name of this group \n "
" @param desc The Description of this field \n "
" @param type The DataType for this field (default, int, float, Point2F, bool, enum, Object, keybind, color) \n "
" @param defaultValue The Default value for this field \n "
" @param userData An extra data field that can be used for custom data on a per-field basis<br>Usage for default types<br> "
" -enum: a TAB separated list of possible values<br> "
" -object: the T2D object type that are valid choices for the field. The object types observe inheritance, so if you have a t2dSceneObject field you will be able to choose t2dStaticSrpites, t2dAnimatedSprites, etc. \n "
" @return Nothing \n " )
{
object - > endFieldGroup ( ) ;
}
DefineConsoleMethod ( Component , addComponentField , void , ( String fieldName , String fieldDesc , String fieldType , String defValue , String userData , bool hidden ) ,
( " " , " " , " " , " " , " " , false ) ,
" Get the number of static fields on the object. \n "
" @return The number of static fields defined on the object. " )
{
object - > addComponentField ( fieldName , fieldDesc , fieldType , defValue , userData , hidden ) ;
}
ConsoleMethod ( Component , getComponentFieldCount , S32 , 2 , 2 , " () - Get the number of ComponentField's on this object \n "
" @return Returns the number of BehaviorFields as a nonnegative integer \n " )
{
return object - > getComponentFieldCount ( ) ;
}
// [tom, 1/12/2007] Field accessors split into multiple methods to allow space
// for long descriptions and type data.
ConsoleMethod ( Component , getComponentField , const char * , 3 , 3 , " (int index) - Gets a Tab-Delimited list of information about a ComponentField specified by Index \n "
" @param index The index of the behavior \n "
" @return FieldName, FieldType and FieldDefaultValue, each separated by a TAB character. \n " )
{
ComponentField * field = object - > getComponentField ( dAtoi ( argv [ 2 ] ) ) ;
if ( field = = NULL )
return " " ;
char * buf = Con : : getReturnBuffer ( 1024 ) ;
dSprintf ( buf , 1024 , " %s \t %s \t %s \t %s " , field - > mFieldName , field - > mFieldType , field - > mDefaultValue , field - > mGroup ) ;
return buf ;
}
ConsoleMethod ( Component , setComponentield , const char * , 3 , 3 , " (int index) - Gets a Tab-Delimited list of information about a ComponentField specified by Index \n "
" @param index The index of the behavior \n "
" @return FieldName, FieldType and FieldDefaultValue, each separated by a TAB character. \n " )
{
ComponentField * field = object - > getComponentField ( dAtoi ( argv [ 2 ] ) ) ;
if ( field = = NULL )
return " " ;
char * buf = Con : : getReturnBuffer ( 1024 ) ;
dSprintf ( buf , 1024 , " %s \t %s \t %s " , field - > mFieldName , field - > mFieldType , field - > mDefaultValue ) ;
return buf ;
}
2017-10-15 09:42:30 +00:00
DefineConsoleMethod ( Component , getComponentFieldType , const char * , ( String fieldName ) , ,
" Get the number of static fields on the object. \n "
" @return The number of static fields defined on the object. " )
{
ComponentField * field = object - > getComponentField ( fieldName ) ;
if ( field = = NULL )
return " " ;
return field - > mFieldTypeName ; ;
}
2016-05-14 05:00:02 +00:00
ConsoleMethod ( Component , getBehaviorFieldUserData , const char * , 3 , 3 , " (int index) - Gets the UserData associated with a field by index in the field list \n "
" @param index The index of the behavior \n "
" @return Returns a string representing the user data of this field \n " )
{
ComponentField * field = object - > getComponentField ( dAtoi ( argv [ 2 ] ) ) ;
if ( field = = NULL )
return " " ;
return field - > mUserData ;
}
ConsoleMethod ( Component , getComponentFieldDescription , const char * , 3 , 3 , " (int index) - Gets a field description by index \n "
" @param index The index of the behavior \n "
" @return Returns a string representing the description of this field \n " )
{
ComponentField * field = object - > getComponentField ( dAtoi ( argv [ 2 ] ) ) ;
if ( field = = NULL )
return " " ;
return field - > mFieldDescription ? field - > mFieldDescription : " " ;
}
ConsoleMethod ( Component , addDependency , void , 3 , 3 , " (string behaviorName) - Gets a field description by index \n "
" @param index The index of the behavior \n "
" @return Returns a string representing the description of this field \n " )
{
object - > addDependency ( argv [ 2 ] ) ;
}
ConsoleMethod ( Component , setDirty , void , 2 , 2 , " () - Gets a field description by index \n "
" @param index The index of the behavior \n "
" @return Returns a string representing the description of this field \n " )
{
object - > setMaskBits ( Component : : OwnerMask ) ;
}