📄 simbase.cc
字号:
{
}
void SimObject::onDeleteNotify(SimObject*)
{
}
void SimObject::onNameChange(const char*)
{
}
void SimObject::onStaticModified(const char*)
{
}
bool SimObject::processArguments(S32 argc, const char**)
{
return argc == 0;
}
//---------------------------------------------------------------------------
static Chunker<SimObject::Notify> notifyChunker(128000);
SimObject::Notify *SimObject::mNotifyFreeList = NULL;
SimObject::Notify *SimObject::allocNotify()
{
if(mNotifyFreeList)
{
SimObject::Notify *ret = mNotifyFreeList;
mNotifyFreeList = ret->next;
return ret;
}
return notifyChunker.alloc();
}
void SimObject::freeNotify(SimObject::Notify* note)
{
AssertFatal(note->type != SimObject::Notify::Invalid, "Invalid notify");
note->type = SimObject::Notify::Invalid;
note->next = mNotifyFreeList;
mNotifyFreeList = note;
}
//------------------------------------------------------------------------------
SimObject::Notify* SimObject::removeNotify(void *ptr, SimObject::Notify::Type type)
{
Notify **list = &mNotifyList;
while(*list)
{
if((*list)->ptr == ptr && (*list)->type == type)
{
SimObject::Notify *ret = *list;
*list = ret->next;
return ret;
}
list = &((*list)->next);
}
return NULL;
}
void SimObject::deleteNotify(SimObject* obj)
{
AssertFatal(!obj->isDeleted(),
"SimManager::deleteNotify: Object is being deleted");
Notify *note = allocNotify();
note->ptr = (void *) this;
note->next = obj->mNotifyList;
note->type = Notify::DeleteNotify;
obj->mNotifyList = note;
note = allocNotify();
note->ptr = (void *) obj;
note->next = mNotifyList;
note->type = Notify::ClearNotify;
mNotifyList = note;
//obj->deleteNotifyList.pushBack(this);
//clearNotifyList.pushBack(obj);
}
void SimObject::registerReference(SimObject **ptr)
{
Notify *note = allocNotify();
note->ptr = (void *) ptr;
note->next = mNotifyList;
note->type = Notify::ObjectRef;
mNotifyList = note;
}
void SimObject::unregisterReference(SimObject **ptr)
{
Notify *note = removeNotify((void *) ptr, Notify::ObjectRef);
freeNotify(note);
}
void SimObject::clearNotify(SimObject* obj)
{
Notify *note = obj->removeNotify((void *) this, Notify::DeleteNotify);
if(note)
freeNotify(note);
note = removeNotify((void *) obj, Notify::ClearNotify);
if(note)
freeNotify(note);
}
void SimObject::processDeleteNotifies()
{
// clear out any delete notifies and
// object refs.
while(mNotifyList)
{
Notify *note = mNotifyList;
mNotifyList = note->next;
AssertFatal(note->type != Notify::ClearNotify, "Clear notes should be all gone.");
if(note->type == Notify::DeleteNotify)
{
SimObject *obj = (SimObject *) note->ptr;
Notify *cnote = obj->removeNotify((void *)this, Notify::ClearNotify);
obj->onDeleteNotify(this);
freeNotify(cnote);
}
else
{
// it must be an object ref - a pointer refs this object
*((SimObject **) note->ptr) = NULL;
}
freeNotify(note);
}
}
void SimObject::clearAllNotifications()
{
for(Notify **cnote = &mNotifyList; *cnote; )
{
Notify *temp = *cnote;
if(temp->type == Notify::ClearNotify)
{
*cnote = temp->next;
Notify *note = ((SimObject *) temp->ptr)->removeNotify((void *) this, Notify::DeleteNotify);
freeNotify(temp);
freeNotify(note);
}
else
cnote = &(temp->next);
}
}
//---------------------------------------------------------------------------
void SimObject::initPersistFields()
{
Parent::initPersistFields();
}
bool SimObject::addToSet(SimObjectId spid)
{
if (mFlags.test(Added) == false)
return false;
SimObject* ptr = Sim::findObject(spid);
if (ptr)
{
SimSet* sp = dynamic_cast<SimSet*>(ptr);
AssertFatal(sp != 0,
"SimObject::addToSet: "
"ObjectId does not refer to a set object");
sp->addObject(this);
return true;
}
return false;
}
bool SimObject::addToSet(const char *ObjectName)
{
if (mFlags.test(Added) == false)
return false;
SimObject* ptr = Sim::findObject(ObjectName);
if (ptr)
{
SimSet* sp = dynamic_cast<SimSet*>(ptr);
AssertFatal(sp != 0,
"SimObject::addToSet: "
"ObjectName does not refer to a set object");
sp->addObject(this);
return true;
}
return false;
}
bool SimObject::removeFromSet(SimObjectId sid)
{
if (mFlags.test(Added) == false)
return false;
SimSet *set;
if(Sim::findObject(sid, set))
{
set->removeObject(this);
return true;
}
return false;
}
bool SimObject::removeFromSet(const char *objectName)
{
if (mFlags.test(Added) == false)
return false;
SimSet *set;
if(Sim::findObject(objectName, set))
{
set->removeObject(this);
return true;
}
return false;
}
void SimObject::inspectPreApply()
{
}
void SimObject::inspectPostApply()
{
}
IMPLEMENT_CONOBJECT(SimObject);
//---------------------------------------------------------------------------
IMPLEMENT_CO_DATABLOCK_V1(SimDataBlock);
SimObjectId SimDataBlock::sNextObjectId = DataBlockObjectIdFirst;
S32 SimDataBlock::sNextModifiedKey = 0;
//---------------------------------------------------------------------------
SimDataBlock::SimDataBlock()
{
setModDynamicFields(true);
setModStaticFields(true);
}
bool SimDataBlock::onAdd()
{
Parent::onAdd();
// This initialization is done here, and not in the constructor,
// because some jokers like to construct and destruct objects
// (without adding them to the manager) to check what class
// they are.
modifiedKey = ++sNextModifiedKey;
AssertFatal(sNextObjectId <= DataBlockObjectIdLast,
"Exceeded maximum number of data blocks");
// add DataBlock to the DataBlockGroup unless it is client side ONLY DataBlock
if (getId() >= DataBlockObjectIdFirst && getId() <= DataBlockObjectIdLast)
if (SimGroup* grp = Sim::getDataBlockGroup())
grp->addObject(this);
return true;
}
void SimDataBlock::assignId()
{
// We don't want the id assigned by the manager, but it may have
// already been assigned a correct data block id.
if (getId() < DataBlockObjectIdFirst || getId() > DataBlockObjectIdLast)
setId(sNextObjectId++);
}
void SimDataBlock::onStaticModified(const char*)
{
modifiedKey = sNextModifiedKey++;
}
/*void SimDataBlock::setLastError(const char*)
{
} */
void SimDataBlock::packData(BitStream*)
{
}
void SimDataBlock::unpackData(BitStream*)
{
}
bool SimDataBlock::preload(bool, char[256])
{
return true;
}
ConsoleFunction(deleteDataBlocks, void, 1, 1, "Delete all the datablocks we've downloaded. "
"This is usually done in preparation of downloading a new set of datablocks, "
" such as occurs on a mission change, but it's also good post-mission cleanup.")
{
argc; argv;
// delete from last to first:
SimGroup *grp = Sim::getDataBlockGroup();
for(S32 i = grp->size() - 1; i >= 0; i--)
{
SimObject *obj = (*grp)[i];
obj->deleteObject();
}
SimDataBlock::sNextObjectId = DataBlockObjectIdFirst;
SimDataBlock::sNextModifiedKey = 0;
}
//---------------------------------------------------------------------------
void SimSet::addObject(SimObject* obj)
{
lock();
objectList.pushBack(obj);
deleteNotify(obj);
unlock();
}
void SimSet::removeObject(SimObject* obj)
{
lock();
objectList.remove(obj);
clearNotify(obj);
unlock();
}
void SimSet::pushObject(SimObject* pObj)
{
lock();
objectList.pushBackForce(pObj);
deleteNotify(pObj);
unlock();
}
void SimSet::popObject()
{
MutexHandle handle;
handle.lock(mMutex);
if (objectList.size() == 0)
{
AssertWarn(false, "Stack underflow in SimSet::popObject");
return;
}
SimObject* pObject = objectList[objectList.size() - 1];
objectList.removeStable(pObject);
clearNotify(pObject);
}
bool SimSet::reOrder( SimObject *obj, SimObject *target )
{
MutexHandle handle;
handle.lock(mMutex);
iterator itrS, itrD;
if ( (itrS = find(begin(),end(),obj)) == end() )
{
return false; // object must be in list
}
if ( obj == target )
{
return true; // don't reorder same object but don't indicate error
}
if ( !target ) // if no target, then put to back of list
{
if ( itrS != (end()-1) ) // don't move if already last object
{
objectList.erase(itrS); // remove object from its current location
objectList.push_back(obj); // push it to the back of the list
}
}
else // if target, insert object in front of target
{
if ( (itrD = find(begin(),end(),target)) == end() )
return false; // target must be in list
objectList.erase(itrS);
//Tinman - once itrS has been erased, itrD won't be pointing at the same place anymore - re-find...
itrD = find(begin(),end(),target);
objectList.insert(itrD,obj);
}
return true;
}
void SimSet::onDeleteNotify(SimObject *object)
{
removeObject(object);
Parent::onDeleteNotify(object);
}
void SimSet::onRemove()
{
MutexHandle handle;
handle.lock(mMutex);
objectList.sortId();
if (objectList.size())
{
// This backwards iterator loop doesn't work if the
// list is empty, check the size first.
for (SimObjectList::iterator ptr = objectList.end() - 1;
ptr >= objectList.begin(); ptr--)
{
clearNotify(*ptr);
}
}
handle.unlock();
Parent::onRemove();
}
void SimSet::write(Stream &stream, U32 tabStop, U32 flags)
{
MutexHandle handle;
handle.lock(mMutex);
// export selected only?
if((flags & SelectedOnly) && !isSelected())
{
for(U32 i = 0; i < size(); i++)
(*this)[i]->write(stream, tabStop, flags);
return;
}
/// TGE_Theme
//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);
char buffer[1024];
writeTabs(stream, tabStop);
dSprintf(buffer, sizeof(buffer), "new %s(%s)\r\n", getClassName(), getName() ? getName() : "");
stream.write(dStrlen(buffer), buffer);
writeTabs(stream, tabStop);
stream.write(3, "{\r\n");
writeFields(stream, tabStop + 1);
/// end TGE_Theme
if(size())
{
stream.write(2, "\r\n");
static const char* sTitle = "//对象列表...\r\n";
writeTabs(stream, tabStop+1);
stream.write(dStrlen(sTitle), sTitle);
for(U32 i = 0; i < size(); i++)
{
(*this)[i]->write(stream, tabStop + 1, flags);
stream.write(2, "\r\n"); /// TGE_Theme
}
}
/// TGE_Theme
writeTabs(stream, tabStop);
dSprintf(buffer, sizeof(buffer), "};//new %s(%s)\r\n", getClassName(), getName() ? getName() : "");
stream.write(dStrlen(buffer), buffer);
//stream.write(4, "};\r\n");
/// end TGE_Theme
}
#ifdef TGE_RPG
SimObject* SimSet::duplicate(bool bWithChildren,bool bRegister)
{
SimObject* pNew = Parent::duplicate(bWithChildren,bRegister);
SimSet* pSet = dynamic_cast<SimSet*>(pNew);
if(pSet && bWithChildren && size())
{
SimObject* pChildNew;
for(U32 i = 0; i < size(); i++)
{
pChildNew = (*this)[i]->duplicate(bWithChildren,bRegister);
pSet->addObject(pChildNew);
}
}
return pNew;
}
SimObject* GuiCellArrayControl::duplicate(bool bWithChildren,bool bRegister)
{
SimObject* pNew = SimObject::duplicate(bWithChildren, bRegister);
SimSet* pSet = dynamic_cast<SimSet*>(pNew);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -