📄 simbase.cc
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "console/simBase.h"
#include "core/stringTable.h"
#include "console/console.h"
#include "core/fileStream.h"
#include "sim/actionMap.h"
#include "core/resManager.h"
#include "core/fileObject.h"
#include "console/consoleInternal.h"
#include "console/typeValidators.h"
#ifdef TGE_RPG
#include "gui/containers/guiCellArrayCtrl.h"
#include "gui/controls/guiCellButtonCtrl.h"
#endif
namespace Sim
{
// Don't forget to InstantiateNamed* in simManager.cc - DMM
ImplementNamedSet(ActiveActionMapSet)
ImplementNamedSet(GhostAlwaysSet)
ImplementNamedSet(LightSet)
ImplementNamedSet(WayPointSet)
ImplementNamedSet(fxReplicatorSet)
ImplementNamedSet(fxFoliageSet)
ImplementNamedGroup(ActionMapGroup)
ImplementNamedGroup(ClientGroup)
ImplementNamedGroup(GuiGroup)
ImplementNamedGroup(GuiDataGroup)
ImplementNamedGroup(TCPGroup)
//groups created on the client
ImplementNamedGroup(ClientConnectionGroup)
ImplementNamedGroup(ChunkFileGroup)
}
//---------------------------------------------------------------------------
void SimObjectList::pushBack(SimObject* obj)
{
if (find(begin(),end(),obj) == end())
push_back(obj);
}
void SimObjectList::pushBackForce(SimObject* obj)
{
iterator itr = find(begin(),end(),obj);
if (itr == end())
{
push_back(obj);
}
else
{
// Move to the back...
//
SimObject* pBack = *itr;
removeStable(pBack);
push_back(pBack);
}
}
void SimObjectList::pushFront(SimObject* obj)
{
if (find(begin(),end(),obj) == end())
push_front(obj);
}
void SimObjectList::remove(SimObject* obj)
{
iterator ptr = find(begin(),end(),obj);
if (ptr != end())
erase(ptr);
}
void SimObjectList::removeStable(SimObject* obj)
{
iterator ptr = find(begin(),end(),obj);
if (ptr != end())
erase(ptr);
}
S32 QSORT_CALLBACK SimObjectList::compareId(const void* a,const void* b)
{
return (*reinterpret_cast<const SimObject* const*>(a))->getId() -
(*reinterpret_cast<const SimObject* const*>(b))->getId();
}
void SimObjectList::sortId()
{
dQsort(address(),size(),sizeof(value_type),compareId);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
SimFieldDictionary::Entry *SimFieldDictionary::mFreeList = NULL;
static Chunker<SimFieldDictionary::Entry> fieldChunker;
SimFieldDictionary::Entry *SimFieldDictionary::allocEntry()
{
if(mFreeList)
{
Entry *ret = mFreeList;
mFreeList = ret->next;
return ret;
}
else
return fieldChunker.alloc();
}
void SimFieldDictionary::freeEntry(SimFieldDictionary::Entry *ent)
{
ent->next = mFreeList;
mFreeList = ent;
}
SimFieldDictionary::SimFieldDictionary()
{
for(U32 i = 0; i < HashTableSize; i++)
mHashTable[i] = 0;
mVersion = 0;
}
SimFieldDictionary::~SimFieldDictionary()
{
for(U32 i = 0; i < HashTableSize; i++)
{
for(Entry *walk = mHashTable[i]; walk;)
{
Entry *temp = walk;
walk = temp->next;
dFree(temp->value);
freeEntry(temp);
}
}
}
void SimFieldDictionary::setFieldValue(StringTableEntry slotName, const char *value)
{
U32 bucket = HashPointer(slotName) % HashTableSize;
Entry **walk = &mHashTable[bucket];
while(*walk && (*walk)->slotName != slotName)
walk = &((*walk)->next);
Entry *field = *walk;
if(!*value)
{
if(field)
{
mVersion++;
dFree(field->value);
*walk = field->next;
freeEntry(field);
}
}
else
{
if(field)
{
dFree(field->value);
field->value = dStrdup(value);
}
else
{
mVersion++;
field = allocEntry();
field->value = dStrdup(value);
field->slotName = slotName;
field->next = NULL;
*walk = field;
}
}
}
const char *SimFieldDictionary::getFieldValue(StringTableEntry slotName)
{
U32 bucket = HashPointer(slotName) % HashTableSize;
for(Entry *walk = mHashTable[bucket];walk;walk = walk->next)
if(walk->slotName == slotName)
return walk->value;
return NULL;
}
//---------------------------------------------------------------------------
SimObject::SimObject()
{
objectName = NULL;
nextNameObject = (SimObject*)-1;
nextManagerNameObject = (SimObject*)-1;
nextIdObject = NULL;
mId = 0;
mGroup = 0;
mNameSpace = NULL;
mNotifyList = NULL;
mFlags.set(ModDynamicFields);
mTypeMask = 0;
mFieldDictionary = NULL;
}
static void writeTabs(Stream &stream, U32 count)
{
char tab[] = " ";
while(count--)
stream.write(3, (void*)tab);
}
void SimFieldDictionary::assignFrom(SimFieldDictionary *dict)
{
mVersion++;
for(U32 i = 0; i < HashTableSize; i++)
for(Entry *walk = dict->mHashTable[i];walk; walk = walk->next)
setFieldValue(walk->slotName, walk->value);
}
/// TGE_Theme
//void SimFieldDictionary::writeFields(SimObject *obj, Stream &stream, U32 tabStop)
//{
// const AbstractClassRep::FieldList &list = obj->getFieldList();
// char expandedBuffer[1024];
void SimFieldDictionary::writeFields(SimObject *obj, Stream &stream, U32 tabStop, U32 flags)
{
const AbstractClassRep::FieldList &list = obj->getFieldList();
char expandedBuffer[1024];
// eag needed when writing out profiles from Theme Editor
bool objExists = flags & SimObject::ObjectExists;
char objName[100];
dSprintf(objName, sizeof(objName), "%s%s", objExists ? obj->getName() : "",objExists ? ".":"");
/// end TGE_Theme
const char* sTitle = "//Dynamic Fields...\r\n";
writeTabs(stream, tabStop);
stream.write(dStrlen(sTitle),sTitle);
for(U32 i = 0; i < HashTableSize; i++)
{
for(Entry *walk = mHashTable[i];walk; walk = walk->next)
{
// make sure we haven't written this out yet:
U32 i;
for(i = 0; i < list.size(); i++)
if(list[i].pFieldname == walk->slotName)
break;
if(i != list.size())
continue;
writeTabs(stream, tabStop);
/// TGE_Theme
//dSprintf(expandedBuffer, sizeof(expandedBuffer), "%s = \"", walk->slotName);
dSprintf(expandedBuffer, sizeof(expandedBuffer), "%s%s = \"", objName, walk->slotName);
expandEscape(expandedBuffer + dStrlen(expandedBuffer), walk->value);
dStrcat(expandedBuffer, "\";\r\n");
stream.write(dStrlen(expandedBuffer),expandedBuffer);
}
}
}
static S32 QSORT_CALLBACK compareEntries(const void* a,const void* b)
{
SimFieldDictionary::Entry *fa = *((SimFieldDictionary::Entry **)a);
SimFieldDictionary::Entry *fb = *((SimFieldDictionary::Entry **)b);
return dStricmp(fa->slotName, fb->slotName);
}
void SimFieldDictionary::printFields(SimObject *obj)
{
const AbstractClassRep::FieldList &list = obj->getFieldList();
char expandedBuffer[1024];
Vector<Entry *> flist(__FILE__, __LINE__);
for(U32 i = 0; i < HashTableSize; i++)
{
for(Entry *walk = mHashTable[i];walk; walk = walk->next)
{
// make sure we haven't written this out yet:
U32 i;
for(i = 0; i < list.size(); i++)
if(list[i].pFieldname == walk->slotName)
break;
if(i != list.size())
continue;
flist.push_back(walk);
}
}
dQsort(flist.address(),flist.size(),sizeof(Entry *),compareEntries);
for(Vector<Entry *>::iterator itr = flist.begin(); itr != flist.end(); itr++)
{
dSprintf(expandedBuffer, sizeof(expandedBuffer), " %s = \"", (*itr)->slotName);
expandEscape(expandedBuffer + dStrlen(expandedBuffer), (*itr)->value);
Con::printf("%s\"", expandedBuffer);
}
}
//------------------------------------------------------------------------------
SimFieldDictionaryIterator::SimFieldDictionaryIterator(SimFieldDictionary * dictionary)
{
mDictionary = dictionary;
mHashIndex = -1;
mEntry = 0;
operator++();
}
SimFieldDictionary::Entry* SimFieldDictionaryIterator::operator++()
{
if(!mDictionary)
return(mEntry);
if(mEntry)
mEntry = mEntry->next;
while(!mEntry && (mHashIndex < (SimFieldDictionary::HashTableSize-1)))
mEntry = mDictionary->mHashTable[++mHashIndex];
return(mEntry);
}
SimFieldDictionary::Entry* SimFieldDictionaryIterator::operator*()
{
return(mEntry);
}
void SimObject::assignFieldsFrom(SimObject *parent)
{
// only allow field assigns from objects of the same class:
if(getClassRep() == parent->getClassRep())
{
const AbstractClassRep::FieldList &list = getFieldList();
// copy out all the fields:
for(U32 i = 0; i < list.size(); i++)
{
const AbstractClassRep::Field* f = &list[i];
if(f->elementCount == 1)
{
const char *fieldVal = Con::getData(f->type, (void *) (((const char *)parent) + f->offset), 0, f->table, f->flag);
if(fieldVal)
Con::setData(f->type, (void *) (((const char *)this) + f->offset), 0, 1, &fieldVal, f->table);
}
else
{
for(U32 j = 0; j < f->elementCount; j++)
{
const char *fieldVal = Con::getData(f->type, (void *) (((const char *)parent) + f->offset), j, f->table, f->flag);
if(fieldVal)
Con::setData(f->type, (void *) (((const char *)this) + f->offset), j, 1, &fieldVal, f->table);
}
}
}
}
if(parent->mFieldDictionary)
{
mFieldDictionary = new SimFieldDictionary;
mFieldDictionary->assignFrom(parent->mFieldDictionary);
}
}
/// TGE_Theme
//void SimObject::writeFields(Stream &stream, U32 tabStop)
//{
// const AbstractClassRep::FieldList &list = getFieldList();
// char expandedBuffer[1024];
// const char *docRoot = Con::getVariable("$DocRoot");
// const char *modRoot = Con::getVariable("$ModRoot");
// S32 docRootLen = dStrlen(docRoot);
// S32 modRootLen = dStrlen(modRoot);
void SimObject::writeFields(Stream &stream, U32 tabStop, U32 flags)
{
//#ifdef TGE_RPG
const AbstractClassRep::FieldList &list = getFieldList();
char expandedBuffer[1024];
CSTR docRoot = Con::getVariable("$DocRoot");
CSTR modRoot = Con::getVariable("$ModRoot");
S32 docRootLen = dStrlen(docRoot);
S32 modRootLen = dStrlen(modRoot);
bool objExists = flags & ObjectExists;
char objName[100];
U32 i;
CSTR sQuote;
CSTR val;
ConsoleBaseType *cbt;
dSprintf(objName, sizeof(objName), "%s%s", objExists ? getName() : "", objExists ? ".":"");
///end TGE_Theme
for(i = 0; i < list.size(); i++)
{
const AbstractClassRep::Field* f = &list[i];
if(f->type == AbstractClassRep::DepricatedFieldType ||
f->type == AbstractClassRep::StartGroupFieldType ||
f->type == AbstractClassRep::EndGroupFieldType) continue;
for(U32 j = 0; S32(j) < f->elementCount; j++)
{
if(f->pFieldname[0] == '_')
continue;
val = Con::getData(f->type, (void *) (((CSTR)this) + f->offset), j, f->table, f->flag);
if(!val || !*val)
continue;
cbt = ConsoleBaseType::getType(f->type);
if(cbt->getTypeID() == TypeBool)
{
val = (val[0] == '0')?"false" : "true";
sQuote = "";
}
else if(cbt->getTypeID() == TypeS32)
sQuote = "";
else
sQuote = "\"";
/*
sQuote
*/
/// TGE_Theme
if(f->elementCount == 1)
dSprintf(expandedBuffer, sizeof(expandedBuffer), "%s%s = %s", objName, f->pFieldname, sQuote);
else
dSprintf(expandedBuffer, sizeof(expandedBuffer), "%s%s[%d] = %s", objName, f->pFieldname, j,sQuote);
///end TGE_Theme
// detect and collapse relative path information
if (f->type == TypeFilename)
{
if (docRootLen && (dStrnicmp(docRoot, val, docRootLen) == 0))
{
val += (docRootLen-1);
dStrcat(expandedBuffer, ".");
}
else
if (modRootLen && (dStrnicmp(modRoot, val, modRootLen) == 0))
{
val += (modRootLen-1);
dStrcat(expandedBuffer, "~");
}
}
expandEscape(expandedBuffer + dStrlen(expandedBuffer), val);
if(sQuote[0])
dStrcat(expandedBuffer, sQuote);
dStrcat(expandedBuffer, ";\r\n");
writeTabs(stream, tabStop);
stream.write(dStrlen(expandedBuffer),expandedBuffer);
}
}
if(mFieldDictionary)
{
/// TGE_Theme
//mFieldDictionary->writeFields(this, stream, tabStop);
if(list.size()) //空一行,隔开两类Fields
stream.write(2,"\r\n");
mFieldDictionary->writeFields(this, stream, tabStop, flags);
}
//#endif
}
/// TGE_Theme
//void SimObject::write(Stream &stream, U32 tabStop, U32 flags)
//{
// // Only output selected objects if they want that.
// if((flags & SelectedOnly) && !isSelected())
// return;
//
// writeTabs(stream, tabStop);
// char buffer[1024];
// dSprintf(buffer, sizeof(buffer), "new %s(%s) {\r\n", getClassName(), getName() ? getName() : "");
// stream.write(dStrlen(buffer), buffer);
// writeFields(stream, tabStop + 1);
// writeTabs(stream, tabStop);
// stream.write(4, "};\r\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -