Files
FC1/Editor/Objects/EntityScript.cpp
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

939 lines
23 KiB
C++

////////////////////////////////////////////////////////////////////////////
//
// Crytek Engine Source File.
// Copyright (C), Crytek Studios, 2001.
// -------------------------------------------------------------------------
// File name: EntityScript.cpp
// Version: v1.00
// Created: 10/12/2001 by Timur.
// Compilers: Visual C++ 6.0
// Description: CEntityScript class implementation.
// -------------------------------------------------------------------------
// History:
//
////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "EntityScript.h"
#include "Entity.h"
#include <IScriptSystem.h>
#include <IEntitySystem.h>
#include <IGame.h>
struct CScriptMethodsDump : public IScriptObjectDumpSink
{
std::vector<CString> methods;
std::vector<CString> events;
virtual void OnElementFound(int nIdx,ScriptVarType type){}
virtual void OnElementFound(const char *sName,ScriptVarType type)
{
if (type == svtFunction)
{
if (strncmp(sName,EVENT_PREFIX,6) == 0)
events.push_back( sName+6 );
else
methods.push_back( sName );
}/* else if (type == svtObject && stricmp(sName,PROPERTIES_TABLE)==0)
{
// Properties found.
}
*/
}
};
enum EScriptParamFlags
{
SCRIPTPARAM_POSITIVE = 0x01,
};
//////////////////////////////////////////////////////////////////////////
static struct {
const char *prefix;
IVariable::EType type;
IVariable::EDataType dataType;
int flags;
} s_paramTypes[] =
{
{ "n", IVariable::INT, IVariable::DT_SIMPLE, SCRIPTPARAM_POSITIVE },
{ "i", IVariable::INT, IVariable::DT_SIMPLE,0 },
{ "b", IVariable::BOOL, IVariable::DT_SIMPLE,0 },
{ "f", IVariable::FLOAT, IVariable::DT_SIMPLE,0 },
{ "s", IVariable::STRING, IVariable::DT_SIMPLE,0 },
{ "shader", IVariable::STRING, IVariable::DT_SHADER,0 },
{ "clr", IVariable::VECTOR, IVariable::DT_COLOR,0 },
{ "color", IVariable::VECTOR, IVariable::DT_COLOR,0 },
{ "vector", IVariable::VECTOR, IVariable::DT_SIMPLE,0 },
{ "snd", IVariable::STRING, IVariable::DT_SOUND,0 },
{ "sound", IVariable::STRING, IVariable::DT_SOUND,0 },
{ "tex", IVariable::STRING, IVariable::DT_TEXTURE,0 },
{ "texture", IVariable::STRING, IVariable::DT_TEXTURE,0 },
{ "obj", IVariable::STRING, IVariable::DT_OBJECT,0 },
{ "object", IVariable::STRING, IVariable::DT_OBJECT,0 },
{ "file", IVariable::STRING, IVariable::DT_FILE,0 },
{ "aibehavior", IVariable::STRING,IVariable::DT_AI_BEHAVIOR,0 },
{ "aicharacter",IVariable::STRING,IVariable::DT_AI_CHARACTER,0 },
{ "text", IVariable::STRING, IVariable::DT_LOCAL_STRING,0 },
{ "equip", IVariable::STRING, IVariable::DT_EQUIP,0 },
{ "sndpreset",IVariable::STRING, IVariable::DT_SOUNDPRESET,0 },
{ "eaxpreset",IVariable::STRING, IVariable::DT_EAXPRESET,0 },
{ "aianchor",IVariable::STRING,IVariable::DT_AI_ANCHOR,0 },
};
//////////////////////////////////////////////////////////////////////////
struct CScriptPropertiesDump : public IScriptObjectDumpSink
{
private:
struct Variable {
CString name;
ScriptVarType type;
};
std::vector<Variable> m_elements;
CVarBlock *m_varBlock;
IVariable *m_parentVar;
public:
explicit CScriptPropertiesDump( CVarBlock *pVarBlock,IVariable *pParentVar=NULL )
{
m_varBlock = pVarBlock;
m_parentVar = pParentVar;
}
//////////////////////////////////////////////////////////////////////////
inline bool IsPropertyTypeMatch( const char *type,const char *name,int nameLen )
{
int typeLen = strlen(type);
if (typeLen < nameLen)
{
// After type name Must follow Upper case or _.
if (name[typeLen] != tolower(name[typeLen]) || name[typeLen] == '_' )
{
if (strncmp(name,type,strlen(type)) == 0)
{
return true;
}
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
IVariable* CreateVarByType( IVariable::EType type )
{
switch(type)
{
case IVariable::FLOAT: return new CVariable<float>;
case IVariable::INT: return new CVariable<int>;
case IVariable::STRING: return new CVariable<CString>;
case IVariable::BOOL: return new CVariable<bool>;
case IVariable::VECTOR: return new CVariable<Vec3>;
case IVariable::QUAT: return new CVariable<Quat>;
default:
assert(0);
}
return NULL;
}
//////////////////////////////////////////////////////////////////////////
IVariable* CreateVar( const char *name,IVariable::EType defaultType,const char* &displayName )
{
displayName = name;
// Resolve type from variable name.
int nameLen = strlen(name);
// if starts from capital no type encoded.
if (name[0] == tolower(name[0]))
{
// Try to detect type.
for (int i = 0; i < sizeof(s_paramTypes)/sizeof(s_paramTypes[0]); i++)
{
if (IsPropertyTypeMatch(s_paramTypes[i].prefix,name,nameLen))
{
//if (s_paramTypes[i].type != var->GetType())
//continue;
displayName = name + strlen(s_paramTypes[i].prefix);
if (displayName[0] == '_')
displayName++;
IVariable *var = CreateVarByType(s_paramTypes[i].type);
if (!var)
continue;
var->SetName(name);
var->SetHumanName(displayName);
var->SetDataType(s_paramTypes[i].dataType);
if (s_paramTypes[i].flags & SCRIPTPARAM_POSITIVE)
{
float lmin=0,lmax=10000;
var->GetLimits( lmin,lmax );
// set min Limit to 0 to make it positive only value.
var->SetLimits( 0,lmax );
}
return var;
}
}
}
if (defaultType != IVariable::UNKNOWN)
{
IVariable *var = CreateVarByType(defaultType);
var->SetName(name);
return var;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
void OnElementFound(int nIdx,ScriptVarType type)
{
/*ignore non string indexed values*/
};
//////////////////////////////////////////////////////////////////////////
virtual void OnElementFound(const char *sName,ScriptVarType type)
{
if (sName && sName[0] != 0)
{
Variable var;
var.name = sName;
var.type = type;
m_elements.push_back(var);
}
}
//////////////////////////////////////////////////////////////////////////
void Dump( IScriptObject *pObject )
{
m_elements.reserve(20);
pObject->Dump( this );
std::map<CString,IVariablePtr> nodes;
std::map<CString,IVariablePtr> listNodes;
for (int i = 0; i < m_elements.size(); i++)
{
const char *sName = m_elements[i].name;
ScriptVarType type = m_elements[i].type;
const char *sDisplayName = sName;
if (type == svtNumber)
{
float fVal;
pObject->GetValue( sName,fVal );
IVariable *var = CreateVar(sName,IVariable::FLOAT,sDisplayName);
if (var)
{
var->Set(fVal);
nodes[sDisplayName] = var;
}
} else if (type == svtString)
{
const char *sVal;
pObject->GetValue( sName,sVal );
IVariable *var = CreateVar(sName,IVariable::STRING,sDisplayName);
if (var)
{
var->Set(sVal);
nodes[sDisplayName] = var;
}
} else if (type == svtFunction)
{
// Ignore functions.
} else if (type == svtObject)
{
// Some Table.
_SmartScriptObject pTable(GetIEditor()->GetSystem()->GetIScriptSystem(),true);
if (pObject->GetValue( sName,pTable ))
{
IVariable *var = CreateVar(sName,IVariable::UNKNOWN,sDisplayName);
if (var && var->GetType() == IVariable::VECTOR)
{
nodes[sDisplayName] = var;
float x,y,z;
if (pTable->GetValue("x",x) && pTable->GetValue("y",y) && pTable->GetValue("z",z))
{
var->Set( Vec3(x,y,z) );
}
else
{
pTable->GetAt(1,x);
pTable->GetAt(2,y);
pTable->GetAt(3,z);
var->Set( Vec3(x,y,z) );
}
}
else
{
var = new CVariableArray;
var->SetName(sName);
listNodes[sName] = var;
CScriptPropertiesDump dump(m_varBlock,var);
dump.Dump( *pTable );
}
}
}
}
for (std::map<CString,IVariablePtr>::iterator nit = nodes.begin(); nit != nodes.end(); nit++)
{
if (m_parentVar)
m_parentVar->AddChildVar(nit->second);
else
m_varBlock->AddVariable(nit->second);
}
for (std::map<CString,IVariablePtr>::iterator nit1 = listNodes.begin(); nit1 != listNodes.end(); nit1++)
{
if (m_parentVar)
m_parentVar->AddChildVar(nit1->second);
else
m_varBlock->AddVariable(nit1->second);
}
}
};
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
CEntityScript::CEntityScript( const EntityClassId ClassId,const char *sName,const char *sFile )
{
m_ClassId = ClassId;
m_valid = false;
m_haveEventsTable = false;
m_standart = false;
m_visibilityMask = 0;
m_usable = false;
m_name = sName;
m_file = sFile;
m_relFile = sFile;
}
//////////////////////////////////////////////////////////////////////////
CEntityScript::~CEntityScript()
{
}
//////////////////////////////////////////////////////////////////////////
int CEntityScript::GetEventCount()
{
//return sizeof(sEntityEvents)/sizeof(sEntityEvents[0]);
return m_events.size();
}
//////////////////////////////////////////////////////////////////////////
CString CEntityScript::GetEvent( int i )
{
//return sEntityEvents[i].name;
return m_events[i];
}
//////////////////////////////////////////////////////////////////////////
bool CEntityScript::Load()
{
m_valid = false;
IGame *pGame = GetIEditor()->GetGame();
EntityClass *entCls = pGame->GetClassRegistry()->GetByClassId( m_ClassId );
if (!entCls)
{
m_valid = false;
//Warning( "Load of entity script %s failed.",(const char*)m_name );
CErrorRecord err;
err.error.Format( "Entity Script %s Failed to Load",(const char*)m_name );
err.file = m_relFile;
err.severity = CErrorRecord::ESEVERITY_WARNING;
err.flags = CErrorRecord::FLAG_SCRIPT;
GetIEditor()->GetErrorReport()->ReportError(err);
return false;
}
m_standart = entCls->bReserved;
m_relFile = entCls->strScriptFile.c_str();
m_file = entCls->strFullScriptFile.c_str();
m_ClassId = entCls->ClassId;
if (m_file.IsEmpty())
{
m_valid = true;
return true;
}
return ParseScript();
}
//////////////////////////////////////////////////////////////////////////
bool CEntityScript::ParseScript()
{
// Parse .lua file.
IScriptSystem *script = GetIEditor()->GetSystem()->GetIScriptSystem();
_SmartScriptObject pEntity(script,true);
if (!script->GetGlobalValue( m_name,*pEntity ))
return false;
m_valid = true;
CScriptMethodsDump dump;
pEntity->Dump( &dump );
m_methods = dump.methods;
m_events = dump.events;
//! Sort methods and events.
std::sort( m_methods.begin(),m_methods.end() );
std::sort( m_events.begin(),m_events.end() );
{
// Normal properties.
m_properties = 0;
_SmartScriptObject pProps(script,true);
if (pEntity->GetValue( PROPERTIES_TABLE,*pProps ))
{
// Properties found in entity.
m_properties = new CVarBlock;
CScriptPropertiesDump dump(m_properties);
dump.Dump( *pProps );
}
}
{
// Second set of properties.
m_properties2 = 0;
_SmartScriptObject pProps(script,true);
if (pEntity->GetValue( PROPERTIES2_TABLE,*pProps ))
{
// Properties found in entity.
m_properties2 = new CVarBlock;
CScriptPropertiesDump dump(m_properties2);
dump.Dump( *pProps );
}
}
// Destroy variable block if empty.
if (m_properties != 0 && m_properties->GetVarsCount() < 1)
m_properties = 0;
// Destroy variable block if empty.
if (m_properties2 != 0 && m_properties2->GetVarsCount() < 1)
m_properties2 = 0;
// Load visual object.
_SmartScriptObject pEditorTable(script,true);
if (pEntity->GetValue( "Editor",*pEditorTable ))
{
const char *modelName;
if (pEditorTable->GetValue( "Model",modelName ))
{
m_visualObject = modelName;
}
}
return true;
}
//////////////////////////////////////////////////////////////////////////
void CEntityScript::Reload()
{
// First try compiling script and see if it have any errors.
bool bLoadScript = CFileUtil::CompileLuaFile( GetFile() );
if (bLoadScript)
{
EntityClass *entCls = GetIEditor()->GetGame()->GetClassRegistry()->GetByClassId( m_ClassId );
if (entCls)
{
entCls->bLoaded = false;
}
else
bLoadScript = false;
}
if (bLoadScript)
{
// Script compiled succesfully.
Load();/*
if (GetIEditor()->GetSystem()->GetIScriptSystem()->ReloadScript( GetFile(),false ))
{
ParseScript();
}
*/
}
}
//////////////////////////////////////////////////////////////////////////
void CEntityScript::GotoMethod( const CString &method )
{
CString line;
line.Format( "%s:%s",(const char*)GetName(),(const char*)method );
// Search this line in script file.
int lineNum = FindLineNum( line );
if (lineNum >= 0)
{
// Open UltraEdit32 with this line.
CFileUtil::EditTextFile( GetFile(),lineNum );
}
}
void CEntityScript::AddMethod( const CString &method )
{
// Add a new method to the file. and start Editing it.
FILE *f = fopen( GetFile(),"at" );
if (f)
{
fprintf( f,"\n" );
fprintf( f,"-------------------------------------------------------\n" );
fprintf( f,"function %s:%s()\n",(const char*)m_name,(const char*)method );
fprintf( f,"end\n" );
fclose(f);
}
}
//////////////////////////////////////////////////////////////////////////
int CEntityScript::FindLineNum( const CString &line )
{
FILE *f = fopen( GetFile(),"rb" );
if (!f)
return -1;
int lineFound = -1;
int lineNum = 1;
fseek( f,0,SEEK_END );
int size = ftell(f);
fseek( f,0,SEEK_SET );
char *text = new char[size+16];
fread( text,size,1,f );
text[size] = 0;
char *token = strtok( text,"\n" );
while (token)
{
if (strstr( token,line ) != 0)
{
lineFound = lineNum;
break;
}
token = strtok( NULL,"\n" );
lineNum++;
}
fclose(f);
delete []text;
return lineFound;
}
//////////////////////////////////////////////////////////////////////////
void CEntityScript::SetProperties( IEntity *ientity,CVarBlock *vars,bool bCallUpdate )
{
if (!IsValid())
return;
assert( ientity != 0 );
assert( vars != 0 );
IScriptObject *scriptObject = ientity->GetScriptObject();
if (!scriptObject)
return;
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
_SmartScriptObject pProperties( scriptSystem,true);
if (!scriptObject->GetValue( PROPERTIES_TABLE,*pProperties ))
{
return;
}
for (int i = 0; i < vars->GetVarsCount(); i++)
{
VarToScriptObject( vars->GetVariable(i),pProperties );
}
if (bCallUpdate)
{
HSCRIPTFUNCTION pf;
if (scriptObject->GetValue( "OnPropertyChange",pf ))
{
scriptSystem->BeginCall(pf);
scriptSystem->PushFuncParam(scriptObject);
scriptSystem->EndCall();
//Alberto
scriptSystem->ReleaseFunc(pf);
}
}
}
//////////////////////////////////////////////////////////////////////////
void CEntityScript::SetProperties2( IEntity *ientity,CVarBlock *vars,bool bCallUpdate )
{
if (!IsValid())
return;
assert( ientity != 0 );
assert( vars != 0 );
IScriptObject *scriptObject = ientity->GetScriptObject();
if (!scriptObject)
return;
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
_SmartScriptObject pProperties( scriptSystem,true);
if (!scriptObject->GetValue( PROPERTIES2_TABLE,*pProperties ))
{
return;
}
for (int i = 0; i < vars->GetVarsCount(); i++)
{
VarToScriptObject( vars->GetVariable(i),pProperties );
}
if (bCallUpdate)
{
HSCRIPTFUNCTION pf;
if (scriptObject->GetValue( "OnPropertyChange",pf ))
{
scriptSystem->BeginCall(pf);
scriptSystem->PushFuncParam(scriptObject);
scriptSystem->EndCall();
//Alberto
scriptSystem->ReleaseFunc(pf);
}
}
}
//////////////////////////////////////////////////////////////////////////
void CEntityScript::VarToScriptObject( IVariable *var,IScriptObject *obj )
{
assert(var);
if (var->GetType() == IVariable::ARRAY)
{
int type = obj->GetValueType( var->GetName() );
if (type != svtObject)
return;
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
_SmartScriptObject pTableObj( scriptSystem,true );
if (obj->GetValue( var->GetName(),*pTableObj ))
{
for (int i = 0; i < var->NumChildVars(); i++)
{
IVariable *child = var->GetChildVar(i);
VarToScriptObject( child,pTableObj );
}
}
return;
}
const char *name = var->GetName();
int type = obj->GetValueType( name );
if (type == svtString)
{
CString value;
var->Get(value);
obj->SetValue( name,value );
}
else if (type == svtNumber)
{
float val = 0;
var->Get(val);
obj->SetValue( name,val );
}
else if (type == svtObject)
{
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
// Probably Color/Vector.
_SmartScriptObject pTable( scriptSystem,true );
if (obj->GetValue( name,pTable ))
{
if (var->GetType() == IVariable::VECTOR)
{
Vec3 vec;
var->Get(vec);
float temp;
if (pTable->GetValue( "x",temp ))
{
// Named vector.
pTable->SetValue( "x",vec.x );
pTable->SetValue( "y",vec.y );
pTable->SetValue( "z",vec.z );
}
else
{
// Indexed vector.
pTable->SetAt(1,vec.x);
pTable->SetAt(2,vec.y);
pTable->SetAt(3,vec.z);
}
}
}
}
}
//////////////////////////////////////////////////////////////////////////
void CEntityScript::RunMethod( IEntity *ientity,const CString &method )
{
if (!IsValid())
return;
assert( ientity != 0 );
IScriptObject *scriptObject = ientity->GetScriptObject();
if (!scriptObject)
return;
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
scriptSystem->BeginCall( GetName(),method );
scriptSystem->PushFuncParam( scriptObject );
scriptSystem->EndCall();
}
//////////////////////////////////////////////////////////////////////////
void CEntityScript::SendEvent( IEntity *entity,const CString &method )
{
RunMethod( entity,CString(EVENT_PREFIX)+method );
}
//////////////////////////////////////////////////////////////////////////
void CEntityScript::SetEventsTable( CEntity *entity )
{
if (!IsValid())
return;
assert( entity != 0 );
IEntity *ientity = entity->GetIEntity();
if (!ientity)
return;
IScriptObject *scriptObject = ientity->GetScriptObject();
if (!scriptObject)
return;
// If events target table is null, set event table to null either.
if (entity->GetEventTargetCount() == 0)
{
if (m_haveEventsTable)
{
scriptObject->SetToNull( "Events" );
}
m_haveEventsTable = false;
return;
}
IScriptSystem *scriptSystem = GetIEditor()->GetSystem()->GetIScriptSystem();
_SmartScriptObject pEvents( scriptSystem,false );
scriptObject->SetValue( "Events",*pEvents );
m_haveEventsTable = true;
std::set<CString> sourceEvents;
for (int i = 0; i < entity->GetEventTargetCount(); i++)
{
CEntityEventTarget &et = entity->GetEventTarget(i);
sourceEvents.insert( et.sourceEvent );
}
for (std::set<CString>::iterator it = sourceEvents.begin(); it != sourceEvents.end(); it++)
{
_SmartScriptObject pTrgEvents( scriptSystem,false );
CString sourceEvent = *it;
//int srcEventId = EventNameToId( sourceEvent );
//pEvents->SetAt( srcEventId,*pTrgEvents );
pEvents->SetValue( sourceEvent,*pTrgEvents );
// Put target events to table.
int trgEventIndex = 1;
for (int i = 0; i < entity->GetEventTargetCount(); i++)
{
CEntityEventTarget &et = entity->GetEventTarget(i);
if (stricmp(et.sourceEvent,sourceEvent) == 0)
{
int entityId = 0;
if (et.target)
{
if (et.target->IsKindOf( RUNTIME_CLASS(CEntity) ))
entityId = ((CEntity*)et.target)->GetEntityId();
}
_SmartScriptObject pTrgEvent( scriptSystem,false );
pTrgEvents->SetAt( trgEventIndex,*pTrgEvent );
trgEventIndex++;
pTrgEvent->SetAt( 1,entityId );
pTrgEvent->SetAt( 2,et.event );
}
}
}
}
//////////////////////////////////////////////////////////////////////////
// CEntityScriptRegistry implementation.
//////////////////////////////////////////////////////////////////////////
CEntityScriptRegistry* CEntityScriptRegistry::m_instance = 0;
CEntityScriptRegistry::CEntityScriptRegistry()
{
m_instance = this;
}
CEntityScriptRegistry::~CEntityScriptRegistry()
{
m_instance = 0;
m_scripts.Clear();
}
CEntityScript* CEntityScriptRegistry::Find( const CString &name )
{
CEntityScriptPtr script = 0;
if (m_scripts.Find( name,script ))
{
return script;
}
return 0;
}
void CEntityScriptRegistry::Insert( CEntityScript *script )
{
// Check if inserting already exist script, if so ignore.
CEntityScriptPtr temp;
if (m_scripts.Find( script->GetName(),temp ))
{
Error( "Inserting duplicate Entity Script %s",(const char*)script->GetName() );
return;
}
m_scripts[script->GetName()] = script;
}
void CEntityScriptRegistry::GetScripts( std::vector<CEntityScript*> &scripts )
{
std::vector<CEntityScriptPtr> s;
m_scripts.GetAsVector( s );
scripts.resize( s.size() );
for (int i = 0; i < s.size(); i++)
{
scripts[i] = s[i];
}
}
void CEntityScriptRegistry::LoadScripts()
{
IGame *game = GetIEditor()->GetGame();
if (!game)
return;
m_scripts.Clear();
EntityClass *entCls;
// Enumerate entity classes inside Game.
game->GetClassRegistry()->MoveFirst();
do {
entCls = game->GetClassRegistry()->Next();
if (entCls)
{
CEntityScript *script = new CEntityScript( entCls->ClassId,entCls->strClassName.c_str(),entCls->strScriptFile.c_str() );
if (!entCls->strScriptFile.empty())
script->SetUsable( true );
Insert( script );
}
} while (entCls);
/*
int lastClassId = FIRST_ENTITY_CLASS_ID;
//////////////////////////////////////////////////////////////////////////
// Load class registry.
// Enumerate all XML files in Editor\ subfolder to look for EntityRegistry.
//////////////////////////////////////////////////////////////////////////
CString masterCD = GetIEditor()->GetMasterCDFolder();
std::vector<CFileUtil::FileDesc> files;
CString dir = Path::AddBackslash(masterCD) + "Editor\\";
CFileUtil::ScanDirectory( dir,"*.xml",files,false );
XmlParser parser;
FILE *file;
file = fopen( "Scripts\\classreg1.lua","wt" );
for (int k = 0; k < files.size(); k++)
{
// Construct the full filepath of the current file
XmlNodeRef registry = parser.parse( dir + files[k].filename );
if (registry != 0 && registry->isTag("EntityRegistry"))
{
for (int i = 0; i < registry->getChildCount(); i++)
{
XmlNodeRef child = registry->getChild(i);
if (child->isTag("EntityDesc"))
{
const char *fname = child->getAttr( "File" );
const char *tableName = child->getAttr( "Name" );
// Save new format.
fprintf( file,"\t{ \"\",\t\"%s\",\t%.3d,\t\"%s\" },\n",tableName,i+100,fname );
CString file,name;
int clsId;
if (child->getAttr( "File",file ) &&
child->getAttr( "Name",name ))
{
clsId = lastClassId++;
CEntityScript* script = Find(name);
if (script)
{
script->Invalidate();
}
else
{
script = new CEntityScript( clsId,name,file );
// Only scripts from entity registry can be used.
script->SetUsable( true );
Insert( script );
}
}
}
}
}
}
fclose( file );
*/
}
//////////////////////////////////////////////////////////////////////////
CEntityScriptRegistry* CEntityScriptRegistry::Instance()
{
if (!m_instance)
{
m_instance = new CEntityScriptRegistry;
}
return m_instance;
}
//////////////////////////////////////////////////////////////////////////
void CEntityScriptRegistry::Release()
{
if (m_instance)
{
delete m_instance;
}
m_instance = 0;
}