Initial commit
This commit is contained in:
287
engines/titanic/core/tree_item.cpp
Normal file
287
engines/titanic/core/tree_item.cpp
Normal file
@@ -0,0 +1,287 @@
|
||||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "titanic/core/tree_item.h"
|
||||
#include "titanic/core/dont_save_file_item.h"
|
||||
#include "titanic/core/file_item.h"
|
||||
#include "titanic/core/game_object.h"
|
||||
#include "titanic/core/game_object_desc_item.h"
|
||||
#include "titanic/core/link_item.h"
|
||||
#include "titanic/core/mail_man.h"
|
||||
#include "titanic/core/named_item.h"
|
||||
#include "titanic/core/node_item.h"
|
||||
#include "titanic/core/project_item.h"
|
||||
#include "titanic/core/view_item.h"
|
||||
#include "titanic/core/room_item.h"
|
||||
#include "titanic/pet_control/pet_control.h"
|
||||
#include "titanic/game_manager.h"
|
||||
#include "titanic/game/placeholder/place_holder.h"
|
||||
|
||||
namespace Titanic {
|
||||
|
||||
EMPTY_MESSAGE_MAP(CTreeItem, CMessageTarget);
|
||||
|
||||
CTreeItem::CTreeItem() : _parent(nullptr), _firstChild(nullptr),
|
||||
_nextSibling(nullptr), _priorSibling(nullptr), _field14(0) {
|
||||
}
|
||||
|
||||
void CTreeItem::dump(int indent) {
|
||||
CString line = dumpItem(indent);
|
||||
debug("%s", line.c_str());
|
||||
|
||||
CTreeItem *item = getFirstChild();
|
||||
while (item) {
|
||||
item->dump(indent + 1);
|
||||
|
||||
item = item->getNextSibling();
|
||||
}
|
||||
}
|
||||
|
||||
CString CTreeItem::dumpItem(int indent) const {
|
||||
CString result;
|
||||
for (int idx = 0; idx < indent; ++idx)
|
||||
result += '\t';
|
||||
result += getType()->_className;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void CTreeItem::save(SimpleFile *file, int indent) {
|
||||
file->writeNumberLine(0, indent);
|
||||
CMessageTarget::save(file, indent);
|
||||
}
|
||||
|
||||
void CTreeItem::load(SimpleFile *file) {
|
||||
file->readNumber();
|
||||
CMessageTarget::load(file);
|
||||
}
|
||||
|
||||
bool CTreeItem::isFileItem() const {
|
||||
return isInstanceOf(CFileItem::_type);
|
||||
}
|
||||
|
||||
bool CTreeItem::isRoomItem() const {
|
||||
return isInstanceOf(CRoomItem::_type);
|
||||
}
|
||||
|
||||
bool CTreeItem::isNodeItem() const {
|
||||
return isInstanceOf(CNodeItem::_type);
|
||||
}
|
||||
|
||||
bool CTreeItem::isViewItem() const {
|
||||
return isInstanceOf(CViewItem::_type);
|
||||
}
|
||||
|
||||
bool CTreeItem::isLinkItem() const {
|
||||
return isInstanceOf(CLinkItem::_type);
|
||||
}
|
||||
|
||||
bool CTreeItem::isPlaceHolderItem() const {
|
||||
return isInstanceOf(CPlaceHolder::_type);
|
||||
}
|
||||
|
||||
bool CTreeItem::isNamedItem() const {
|
||||
return isInstanceOf(CNamedItem::_type);
|
||||
}
|
||||
|
||||
bool CTreeItem::isGameObject() const {
|
||||
return isInstanceOf(CGameObject::_type);
|
||||
}
|
||||
|
||||
bool CTreeItem::isGameObjectDescItem() const {
|
||||
return isInstanceOf(CGameObjectDescItem::_type);
|
||||
}
|
||||
|
||||
CGameManager *CTreeItem::getGameManager() const {
|
||||
return _parent ? _parent->getGameManager() : nullptr;
|
||||
}
|
||||
|
||||
CProjectItem *CTreeItem::getRoot() const {
|
||||
CTreeItem *parent = getParent();
|
||||
|
||||
if (parent) {
|
||||
do {
|
||||
parent = parent->getParent();
|
||||
} while (parent->getParent());
|
||||
}
|
||||
|
||||
return dynamic_cast<CProjectItem *>(parent);
|
||||
}
|
||||
|
||||
CTreeItem *CTreeItem::getLastSibling() {
|
||||
CTreeItem *item = this;
|
||||
while (item->getNextSibling())
|
||||
item = item->getNextSibling();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
CTreeItem *CTreeItem::getLastChild() const {
|
||||
if (!_firstChild)
|
||||
return nullptr;
|
||||
return _firstChild->getLastSibling();
|
||||
}
|
||||
|
||||
CTreeItem *CTreeItem::scan(CTreeItem *item) const {
|
||||
if (_firstChild)
|
||||
return _firstChild;
|
||||
|
||||
const CTreeItem *treeItem = this;
|
||||
while (treeItem != item) {
|
||||
if (treeItem->_nextSibling)
|
||||
return treeItem->_nextSibling;
|
||||
|
||||
treeItem = treeItem->_parent;
|
||||
if (!treeItem)
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CTreeItem *CTreeItem::findChildInstanceOf(ClassDef *classDef) const {
|
||||
for (CTreeItem *treeItem = _firstChild; treeItem; treeItem = treeItem->getNextSibling()) {
|
||||
if (treeItem->isInstanceOf(classDef))
|
||||
return treeItem;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CTreeItem *CTreeItem::findNextInstanceOf(ClassDef *classDef, CTreeItem *startItem) const {
|
||||
CTreeItem *treeItem = startItem ? startItem->getNextSibling() : getFirstChild();
|
||||
|
||||
for (; treeItem; treeItem = treeItem->getNextSibling()) {
|
||||
if (treeItem->isInstanceOf(classDef))
|
||||
return treeItem;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void CTreeItem::addUnder(CTreeItem *newParent) {
|
||||
if (newParent->_firstChild)
|
||||
addSibling(newParent->_firstChild->getLastSibling());
|
||||
else
|
||||
setParent(newParent);
|
||||
}
|
||||
|
||||
void CTreeItem::setParent(CTreeItem *newParent) {
|
||||
_parent = newParent;
|
||||
_priorSibling = nullptr;
|
||||
_nextSibling = newParent->_firstChild;
|
||||
|
||||
if (newParent->_firstChild)
|
||||
newParent->_firstChild->_priorSibling = this;
|
||||
newParent->_firstChild = this;
|
||||
}
|
||||
|
||||
void CTreeItem::addSibling(CTreeItem *item) {
|
||||
_priorSibling = item;
|
||||
_nextSibling = item->_nextSibling;
|
||||
_parent = item->_parent;
|
||||
|
||||
if (item->_nextSibling)
|
||||
item->_nextSibling->_priorSibling = this;
|
||||
item->_nextSibling = this;
|
||||
}
|
||||
|
||||
void CTreeItem::moveUnder(CTreeItem *newParent) {
|
||||
if (newParent) {
|
||||
detach();
|
||||
addUnder(newParent);
|
||||
}
|
||||
}
|
||||
|
||||
void CTreeItem::destroyAll() {
|
||||
destroyChildren();
|
||||
detach();
|
||||
delete this;
|
||||
}
|
||||
|
||||
int CTreeItem::destroyChildren() {
|
||||
if (!_firstChild)
|
||||
return 0;
|
||||
|
||||
CTreeItem *item = _firstChild, *child, *nextSibling;
|
||||
int total = 0;
|
||||
|
||||
do {
|
||||
child = item->_firstChild;
|
||||
nextSibling = item->_nextSibling;
|
||||
|
||||
if (child)
|
||||
total += item->destroyChildren();
|
||||
item->detach();
|
||||
delete item;
|
||||
++total;
|
||||
} while ((item = nextSibling) != nullptr);
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
void CTreeItem::detach() {
|
||||
// Delink this item from any prior and/or next siblings
|
||||
if (_priorSibling)
|
||||
_priorSibling->_nextSibling = _nextSibling;
|
||||
if (_nextSibling)
|
||||
_nextSibling->_priorSibling = _priorSibling;
|
||||
|
||||
if (_parent && _parent->_firstChild == this)
|
||||
_parent->_firstChild = _nextSibling;
|
||||
|
||||
_priorSibling = _nextSibling = _parent = nullptr;
|
||||
}
|
||||
|
||||
void CTreeItem::attach(CTreeItem *item) {
|
||||
_nextSibling = item;
|
||||
_priorSibling = item->_priorSibling;
|
||||
_parent = item->_parent;
|
||||
|
||||
if (item->_priorSibling)
|
||||
item->_priorSibling->_nextSibling = this;
|
||||
|
||||
item->_priorSibling = this;
|
||||
if (item->_parent && !item->_parent->_firstChild)
|
||||
item->_parent->_firstChild = this;
|
||||
}
|
||||
|
||||
CNamedItem *CTreeItem::findByName(const CString &name, bool subMatch) {
|
||||
CString nameLower = name;
|
||||
nameLower.toLowercase();
|
||||
|
||||
for (CTreeItem *treeItem = this; treeItem; treeItem = treeItem->scan(this)) {
|
||||
CString itemName = treeItem->getName();
|
||||
itemName.toLowercase();
|
||||
|
||||
if (subMatch) {
|
||||
if (!itemName.left(nameLower.size()).compareTo(nameLower))
|
||||
return dynamic_cast<CNamedItem *>(treeItem);
|
||||
} else {
|
||||
if (!itemName.compareTo(nameLower))
|
||||
return dynamic_cast<CNamedItem *>(treeItem);
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // End of namespace Titanic
|
||||
Reference in New Issue
Block a user