[Scummvm-cvs-logs] SF.net SVN: scummvm: [28050] scummex/branches/gsoc2007-gameresbrowser/src
zbychs at users.sourceforge.net
zbychs at users.sourceforge.net
Fri Jul 13 06:03:45 CEST 2007
Revision: 28050
http://scummvm.svn.sourceforge.net/scummvm/?rev=28050&view=rev
Author: zbychs
Date: 2007-07-12 21:03:42 -0700 (Thu, 12 Jul 2007)
Log Message:
-----------
I have added a bunch of comments, and refactored the code a bit.
Modified Paths:
--------------
scummex/branches/gsoc2007-gameresbrowser/src/ReadMe.txt
scummex/branches/gsoc2007-gameresbrowser/src/browser/CoreInterfaces.h
scummex/branches/gsoc2007-gameresbrowser/src/browser/Directories.cpp
scummex/branches/gsoc2007-gameresbrowser/src/browser/ExplorationTree.cpp
scummex/branches/gsoc2007-gameresbrowser/src/browser/ExplorationTree.h
scummex/branches/gsoc2007-gameresbrowser/src/browser/FileTypeRecognizer.cpp
scummex/branches/gsoc2007-gameresbrowser/src/browser/FileTypeRecognizer.h
scummex/branches/gsoc2007-gameresbrowser/src/browser/GUIInterfaces.h
scummex/branches/gsoc2007-gameresbrowser/src/browser/PanelProvider.cpp
scummex/branches/gsoc2007-gameresbrowser/src/browser/PanelProvider.h
scummex/branches/gsoc2007-gameresbrowser/src/browser/VirtualNode.cpp
scummex/branches/gsoc2007-gameresbrowser/src/browser/VirtualNode.h
scummex/branches/gsoc2007-gameresbrowser/src/browser/browser_stdafx.h
scummex/branches/gsoc2007-gameresbrowser/src/browserapp/Test1.cpp
scummex/branches/gsoc2007-gameresbrowser/src/browserapp/Test2.cpp
scummex/branches/gsoc2007-gameresbrowser/src/core/GUIDObject.h
scummex/branches/gsoc2007-gameresbrowser/src/core/ObjectChain.cpp
scummex/branches/gsoc2007-gameresbrowser/src/core/ObjectChain.h
scummex/branches/gsoc2007-gameresbrowser/src/core/pinslot.cpp
scummex/branches/gsoc2007-gameresbrowser/src/core/pinslot.h
scummex/branches/gsoc2007-gameresbrowser/src/core/pinslot_detail.h
scummex/branches/gsoc2007-gameresbrowser/src/core/plugin.h
scummex/branches/gsoc2007-gameresbrowser/src/core/plugin_detail.h
scummex/branches/gsoc2007-gameresbrowser/src/core/safe_static.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/AuxInterfaces.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/BitmapPanel.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/DirectoryPresenter.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/DirectoryPresenter.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/DiskFileProvider.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/DiskFileProvider.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/FileInfoPresenter.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/FileInfoPresenter.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/HtmlPresenter.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/HtmlPresenter.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/ImagePresenter.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/ImagePresenter.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/TextPresenter.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/TextPresenter.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/basic_plugin.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/BlockyBlockPresenter.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/BlockyBlockPresenter.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/CustomScummBlocks.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/ScummBlock.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/ScummBlock.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/ScummBlockInfoPresenter.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/ScummBlockInfoPresenter.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/ScummBlockPresenter.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/ScummBlockPresenter.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/ScummFileTypes.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/ScummImage.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/ScummImageDetail.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/ScummParser.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/ScummResource.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/ScummTag.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/scumm/scumm_plugin.cpp
Added Paths:
-----------
scummex/branches/gsoc2007-gameresbrowser/src/core/BObject.cpp
scummex/branches/gsoc2007-gameresbrowser/src/core/BObject.h
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/BasicParsers.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/BasicParsers.h
Removed Paths:
-------------
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/BMPParser.cpp
scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/BMPParser.h
Modified: scummex/branches/gsoc2007-gameresbrowser/src/ReadMe.txt
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/ReadMe.txt 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/ReadMe.txt 2007-07-13 04:03:42 UTC (rev 28050)
@@ -4,15 +4,19 @@
Directories:
-TODO: getMainForm must be done like ExplorationTree
+ core - pin/slot framework (object, object registry, object chain, etc.)
+ browser - the browser framework (uses core; this is what plugins see)
+
+ browserapp - the gui application (it uses core and browser; plugins don't see it)
- core - core files (pins/slots/plugins/registries/objects...)
- browser - all the browser specific classes (plugins can use core and browser)
- gui - wxWidgets browser gui (plugins can't use this)
- plugins - plugins (including the basic ones)
- samples - sample usages of the core/gui modules
+ plugins/basic - a basic plugin, providing the basic objects (like DirectoryPresenter,
+ BinaryPresenter, TextPresenter, ImagePresenter)
+ plugins/scumm - a scumm plugin (uses basic plugin)
+
+ samples - outdated samples usages of the core classes
+
List of sample files (samples directory):
pinslot_plugins.cpp - shows plugin/object chain usage
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browser/CoreInterfaces.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browser/CoreInterfaces.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browser/CoreInterfaces.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -4,7 +4,7 @@
#ifndef _CORE_INTERFACES_H_
#define _CORE_INTERFACES_H_
-#include "pinslot.h"
+#include "BObject.h"
#include "FileType.h"
#include <list>
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browser/Directories.cpp
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browser/Directories.cpp 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browser/Directories.cpp 2007-07-13 04:03:42 UTC (rev 28050)
@@ -162,7 +162,7 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-PIN_DESCS_EX(RootDirectory)
+PIN_DESCS(RootDirectory)
PIN_DESC(_directoryPin, PIN_DEFAULT | PIN_MULTICAST, getDirectoryImpl, releaseDirectoryImpl)
END_DESCS
@@ -194,7 +194,7 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-PIN_DESCS_EX(DiskDirectory)
+PIN_DESCS(DiskDirectory)
PIN_DESC(_directoryPin, PIN_DEFAULT | PIN_MULTICAST, getDirectoryImpl, releaseDirectoryImpl)
END_DESCS
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browser/ExplorationTree.cpp
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browser/ExplorationTree.cpp 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browser/ExplorationTree.cpp 2007-07-13 04:03:42 UTC (rev 28050)
@@ -27,15 +27,19 @@
//information about registered panel
struct PanelInfo {
- bool _activated;
- wxPanel* _page;
- size_t _pageIdx;
- PanelProvider* _panelProvider;
+ bool _activated; //wheather it's being displayed now
+ wxPanel* _page; //it's panel
+ size_t _pageIdx; //it's page index in the wxNotebook
+ PanelProvider* _panelProvider; //the panel provider it represents
PanelInfo(PanelProvider* panelProvider)
: _panelProvider(panelProvider), _activated(false), _page(NULL), _pageIdx(-1) {}
};
-//collection of registered panels
+bool _pinfo_compare(const PanelInfo* left, const PanelInfo* right) {
+ return *left->_panelProvider < *right->_panelProvider;
+}
+
+//collection of registered panels (a multimap VirtualNode -> Panels)
struct PanelMap {
typedef std::multimap<VirtualNode*, PanelInfo*> panel_map;
panel_map _panelInfos;
@@ -57,14 +61,26 @@
}
std::list<PanelInfo*> getPanelsFor(VirtualNode* node) {
- std::list<PanelInfo*> pinfos;
+ std::vector<PanelInfo*> pinfos;
+ VirtualNodeItemData* data = VirtualNodeItemData::getForNode(node->getTreeItem());
+ if (!data)
+ return std::list<PanelInfo*>();
+
+ const guid_list_t& parserGUIDs = data->getParsersOrdering();
+
panel_map::iterator i;
i = _panelInfos.find(node);
- for (; i != _panelInfos.end() && i->first == node; ++i)
- pinfos.push_back(i->second);
+ for (; i != _panelInfos.end() && i->first == node; ++i) {
+ PanelInfo* pinfo = i->second;
+ pinfo->_panelProvider->determineIndex(parserGUIDs);
+ pinfos.push_back(pinfo);
+ }
- return pinfos;
+ //We've got the panels. Let's sort them now.
+ std::sort(pinfos.begin(), pinfos.end(), &_pinfo_compare);
+
+ return std::list<PanelInfo*>(pinfos.begin(), pinfos.end());
}
void unregisterPanelProvider(PanelProvider* panelProvider) {
@@ -184,6 +200,7 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+// Try and complete the object chain of a given item
bool ExplorationTree::onIdleRec(const wxTreeItemId& item) {
ASSERT_VALID_TREE_ITEM(item);
@@ -208,17 +225,13 @@
return true;
}
- /*wxTreeItemIdValue cookie;
- wxTreeItemId child = _explorationTree->GetFirstChild(item, cookie);
- while (child.IsOk()) {
- if (onIdleRec(child))
- return true;
- child = _explorationTree->GetNextChild(item, cookie);
- }*/
-
return false;
}
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//complete any not completed items
+
bool ExplorationTree::onIdle() {
if (_notCompletedList.empty())
return false;
@@ -234,14 +247,8 @@
return false;
}
-void ExplorationTree::realizeVisible(bool dirsOnly /*= true*/) {
- /*wxTreeItemId item = _explorationTree->GetFirstVisibleItem();
- while (item.IsOk() &&
- _explorationTree->IsVisible(item)) { //WORKAROUND: in wxMSW this is necessary
- realizeNode(item, dirsOnly);
- item = _explorationTree->GetNextVisible(item);
- }*/
-}
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
bool ExplorationTree::isNodeRealized(const wxTreeItemId& item) {
ASSERT_VALID_TREE_ITEM(item);
@@ -252,7 +259,7 @@
return data->getRealized();
}
-bool ExplorationTree::realizeNode(const wxTreeItemId& item, bool dirsOnly /*= false*/) {
+bool ExplorationTree::realizeNode(const wxTreeItemId& item) {
ASSERT_VALID_TREE_ITEM(item);
VirtualNodeItemData* data = VirtualNodeItemData::getForNode(item);
if (!data)
@@ -271,13 +278,6 @@
ASSERT_STATICS_ALLOWED();
static BGUID directoryPresenterGUID(wxT("CoreObjects"), wxT("DirectoryPresenter"), 1);
- if (dirsOnly) {
- if (kidchain->isContained(directoryPresenterGUID))
- return true;
- //WORKAROUND: in wxMSW SetItemHasChildren does not work, so we include a Dummy:
- ExplorationTree::get()->deleteChildren(item); //delete the Dummy added by the ExplorationTree
- return true;
- }
if (!kidchain->isContained(directoryPresenterGUID))
ExplorationTree::get()->deleteChildren(item); //delete the Dummy added by the ExplorationTree
@@ -307,6 +307,9 @@
return true;
}
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
VirtualNode* ExplorationTree::getNode(const wxTreeItemId& item) {
if (!realizeNode(item))
return NULL;
@@ -331,6 +334,9 @@
return item;
}
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
wxTreeItemId ExplorationTree::appendItem(const wxTreeItemId& parent, wxString title, const wxTreeItemId& after) {
ASSERT_VALID_TREE_ITEM(parent);
wxTreeItemId item = _explorationTree->AppendItem(parent, title, -1, -1, NULL);
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browser/ExplorationTree.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browser/ExplorationTree.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browser/ExplorationTree.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -22,6 +22,66 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+// ExplorationTree
+//
+// The ExplorationTree is the heart of the Browser.
+//
+// It displays the tree of VirtualNodes.
+// It manages the panels for presenters (a wxNotebook of wxPanels).
+//
+// New panel is allocated for a VirtualNode when a PanelProvider
+// registers itself using ExplorationTree::registerPanelProvider().
+//
+// A registered PanelProvider have the following methods called by the ExplorationTree
+// when apropriate: getPanelTitle(), panelActivate() and panelDeactivate()
+//
+// A DirectoryController can register itself too (the DirectoryPresenter
+// does this). It then have expand() method called when the particular
+// node is expanded.
+//
+//
+// Adding of VirtualNodes into the tree consists of:
+// appendItem() - creating a new 'item' in the tree
+// new VirtualNode - creating a 'virtualNode'
+// new ObjectChain - creating an 'ochain' for it
+// ochain.addObject(virtualFile)
+// new VirtualNodeItemData(virtualNode, ochain) - creating information for the 'item'
+// ExplorationTree::get()->setItemData(item, itemData);
+//
+// (See DirectoryPresenter::expand() for a sample)
+//
+// The ExplorationTree uses the itemData to tie an 'item' with a VirtualNode.
+// To display a node it has to realize it's object chain first.
+// The ExplorationTree is lazy - it realizes the object chain when the item
+// has been selected, not before.
+//
+// The is one problem however: how the ExplorationTree know wheather the item
+// shold have a [+] used to expanding the item? The item has no child items yet,
+// cause it's VirtualNode hasn't been realized yet (so i.e. a DirectoryPresenter
+// can't say 'put a [+] mark' cause the DirectoryPresenter does not exist yet).
+//
+// The solution is as follows: initially all items have a [+].
+// In a free time (onIdle() method) ExplorationTree completes the object
+// chains of it's nodes, and if there is a DirectoryPresenter in the
+// chain - it leaves the [+], otherwise it removes the [+].
+//
+// Now that was completing. When the nodes are realized? When they are
+// activated. The realizeNode() method does this.
+//
+//
+// When an item is activated the following happens:
+// All the currently active panels are being deactivated (using their
+// panelDeactivate() method).
+// The node is being realized (realizeNode() method).
+// All the registered PanelProviders for the node are being activated
+// (using their panelActivate() method).
+//
+// What's the _rootObjectChain? Nothing really important. It's just an object
+// chain that is destroyed on application exit. So it's natural to insert
+// "root" items into it.
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
#define ASSERT_VALID_TREE_ITEM(item) \
ASSERT(item.IsOk())
@@ -33,9 +93,6 @@
class PanelProvider;
class DirectoryController;
-//ExplorationTree's items does not hold any objects by reference. They do however hold
-//them via SetItemData( new VirtualNodeItemData(BObject*) ).
-//ExplorationTree holds objects by reference via _rootObjectChain, though.
class BROWSER_API ExplorationTree {
static ExplorationTree* _instance;
@@ -48,13 +105,13 @@
VirtualNode* _activeNode;
DirMap* _dirMap;
-#ifdef _MSC_VER
-#pragma warning(disable : 4251)
-#endif
+ #ifdef _MSC_VER
+ #pragma warning(disable : 4251)
+ #endif
std::list<wxTreeItemId> _notCompletedList;
-#ifdef _MSC_VER
-#pragma warning(default : 4251)
-#endif
+ #ifdef _MSC_VER
+ #pragma warning(default : 4251)
+ #endif
private:
ExplorationTree();
@@ -67,13 +124,11 @@
static void initialize(wxTreeCtrl* explorationTree, wxNotebook* panelNotebook);
- //static wxTreeCtrl* _getTree();
- //wxTreeCtrl* getTree();
bool onIdleRec(const wxTreeItemId& item);
bool onIdle();
- void realizeVisible(bool dirsOnly = true);
+
bool isNodeRealized(const wxTreeItemId& item);
- bool realizeNode(const wxTreeItemId& item, bool dirsOnly = false);
+ bool realizeNode(const wxTreeItemId& item);
VirtualNode* getNode(const wxTreeItemId& item);
VirtualNode* getSelectedNode();
@@ -90,6 +145,7 @@
ObjectChain* getRootObjectChain();
+ //activating/deactivating panels
void pinfoDeactivate(PanelInfo* pinfo);
void pinfoActivate(PanelInfo* pinfo);
void nodeDeactivate();
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browser/FileTypeRecognizer.cpp
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browser/FileTypeRecognizer.cpp 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browser/FileTypeRecognizer.cpp 2007-07-13 04:03:42 UTC (rev 28050)
@@ -20,12 +20,6 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-
-//#include <wx/arrimpl.cpp> // this is a magic incantation which must be done!
-//WX_DEFINE_OBJARRAY(RecognizedFileTypes);
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
// Static fields
SAFE_EXPORT_CLASS_STATIC(BROWSER_API, RecognizedFileType, NotRecognized, RecognizedFileType,
@@ -38,7 +32,7 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-RecognizedFileType::RecognizedFileType() {} //HACK: for exporting std::vector<>
+RecognizedFileType::RecognizedFileType() {}
RecognizedFileType::RecognizedFileType(FileTypeMatch match, const BGUID& fileTypeGUID)
: _match(match), _fileTypeGUID(fileTypeGUID) {}
@@ -100,7 +94,7 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-SLOT_DESCS_EX(GenericFileTypeRecognizer)
+SLOT_DESCS(GenericFileTypeRecognizer)
SLOT_DESC(_fileSlot, SLOT_DEFAULT)
END_DESCS
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browser/FileTypeRecognizer.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browser/FileTypeRecognizer.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browser/FileTypeRecognizer.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -4,7 +4,7 @@
#ifndef _FILE_TYPE_RECOGNIZER_H_
#define _FILE_TYPE_RECOGNIZER_H_
-#include "pinslot.h"
+#include "BObject.h"
#include "FileType.h"
#include "CoreInterfaces.h"
@@ -18,12 +18,12 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-
+//
// When a VirtualFile is to be presented the following happens:
// - recognize() is run on all FileTypeRecognizers found
// -- we get a list of file type GUID's
// - we find all FileTypeParsers for each file type GUID and choose one of them
-
+//
// How the priorities work:
// - FileTypeMatch can be IDEAL, GOOD or POOR, example:
// BMP: BMPFileType - IDEAL,
@@ -31,7 +31,7 @@
// - ResolvedParsersPriority can be IDEAL, GOOD or POOR, example:
// BMPFileType: BMPParser + BMPInformationParser - IDEAL,
// BinaryParser - POOR
-
+//
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
@@ -98,8 +98,10 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+// GenericFileTypeRecognizer is a utility base class for FileTypeRecognizers
+// It provides a doRecognize() method for subclasses to override, which has
+// additional benefit of having a direct access to the IFile interface.
-//utility base class for FileTypeRecognizers
class BROWSER_API GenericFileTypeRecognizer : public BObject, public FileTypeRecognizer {
DECLARE_BOBJECT_CLASS(GenericFileTypeRecognizer, BObject)
@@ -119,6 +121,12 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+//
+// Simple Recognizers and Resolvers below.
+// Pretty self explanatory, really.
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
class BROWSER_API TextFileTypeRecognizer : public GenericFileTypeRecognizer {
DECLARE_BOBJECT_CLASS(TextFileTypeRecognizer, BObject)
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browser/GUIInterfaces.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browser/GUIInterfaces.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browser/GUIInterfaces.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -4,7 +4,7 @@
#ifndef _GUI_INTERFACES_H_
#define _GUI_INTERFACES_H_
-#include "pinslot.h"
+#include "BObject.h"
class wxImage;
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browser/PanelProvider.cpp
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browser/PanelProvider.cpp 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browser/PanelProvider.cpp 2007-07-13 04:03:42 UTC (rev 28050)
@@ -5,6 +5,7 @@
#include "PanelProvider.h"
#include "ExplorationTree.h"
+#include "ObjectChain.h"
#include <iostream>
@@ -17,7 +18,7 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-SLOT_DESCS_EX(PanelProvider)
+SLOT_DESCS(PanelProvider)
SLOT_DESC(_panelRecieverSlot, SLOT_DEFAULT)
SLOT_DESC(_nodeSlot, SLOT_DEFAULT)
END_DESCS
@@ -34,6 +35,9 @@
return false;
}
+ //register with the ExplorationTree for the node we represent
+ //this way we'll get getPanelTitle(), panelActivate(), and panelDeactivate()
+ //events from the tree
ExplorationTree::get()->registerPanelProvider(_inodeprovider->getNode(), this);
return true;
@@ -61,4 +65,53 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+int PanelProvider::getIndex() const {
+ return _panelIndex;
}
+
+// What we got is a list of parsers (parserGUIDs).
+// What we want is our index in the panel Notebook.
+// So we're finding in our ancestors (in the ObjectChain) a parser with
+// one of those GUIDs. Our index is this GUIDs index in the list.
+int PanelProvider::determineIndex(const guid_list_t& parserGUIDs) {
+ if (_panelIndex != -1)
+ return _panelIndex;
+
+ ObjectChain* ochain = this->getSingleObjectChain();
+ std::list<BObject*> ancestors = ochain->getAncestorsAndSelf(this);
+
+ //get first ancestor with a guid from parserGUIDs
+ std::list<BObject*>::iterator k;
+ int ancestorIndex = 0;
+ for (k = ancestors.begin(); k != ancestors.end(); ++k, ++ancestorIndex) {
+ BObject* ancestor = *k;
+ const BGUID& ancestorGUID = ancestor->get_GUID();
+ if (ancestorIndex <= 1)
+ _presenterGUID = ancestorGUID;
+
+ guid_list_t::const_iterator i;
+ int panelPriority = 0;
+ for (i = parserGUIDs.begin(); i != parserGUIDs.end(); ++i, ++panelPriority) {
+ const BGUID& parserGUID = *(*i);
+
+ if (ancestorGUID == parserGUID) {
+ _panelIndex = (panelPriority << 8) + ancestorIndex;
+ return _panelIndex; //and return the GUID's index
+ }
+ }
+ }
+
+ _panelIndex = 10000; //a big number, if ancestor not found...
+ return _panelIndex;
+}
+
+bool PanelProvider::operator<(const PanelProvider& right) const {
+ if (getIndex() < right.getIndex()) return true;
+ if (getIndex() > right.getIndex()) return false;
+ return _presenterGUID < right._presenterGUID;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+}
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browser/PanelProvider.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browser/PanelProvider.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browser/PanelProvider.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -6,7 +6,7 @@
#include <wx/wx.h>
-#include "pinslot.h"
+#include "BObject.h"
#include "VirtualNode.h"
namespace Browser {
@@ -15,14 +15,25 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+// PanelReciever is an abstract interface of any BObject that wants to be
+// displayed in a panel beside the exploration tree.
class BROWSER_API PanelReciever {
public:
virtual coreString getPanelTitle() = 0;
virtual void panelActivate(wxPanel* panel) = 0;
virtual void panelDeactivate() = 0;
+ virtual ~PanelReciever() {}
};
+//same as above, but can return an index in the panel list
+class BROWSER_API OrderedPanelReciever : public PanelReciever {
+public:
+ virtual int determineIndex(const guid_list_t& parserGUIDs) = 0;
+ virtual int getIndex() const = 0; //can be called only after determineIndex() has been called
+ //virtual bool operator<(const OrderedPanelReciever& right) const = 0;
+};
+
class BROWSER_API IPanelReciever : public IInterface, public PanelReciever {
public:
GUID_FOR(IPanelReciever, wxT("CoreInterfaces"), 1);
@@ -30,8 +41,9 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+// IPanelRecieverImpl delegates method invocations to the apropraiate PanelReciever (_that)
+// For a sample use see the TextPresenter class.
-//IPanelRecieverImpl delegates method invocations to the apropraiate PanelReciever (_that)
class BROWSER_API IPanelRecieverImpl : public IPanelReciever {
protected:
PanelReciever* _that;
@@ -55,13 +67,13 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-
// How the PanelProvider works:
+//
// PanelProvider registers itself in ExplorationTree.
// PanelProvider is then delegating PanelReciever methods from ExplorationTree,
// via IPanelReciever slot, to the proper object.
-class BROWSER_API PanelProvider : public BObject, public PanelReciever {
+class BROWSER_API PanelProvider : public BObject, public OrderedPanelReciever {
DECLARE_BOBJECT_CLASS(PanelProvider, BObject)
protected:
@@ -70,17 +82,28 @@
IPanelReciever* _ipanelreciever;
INodeProvider* _inodeprovider;
+
+ //these are kept for ordering panels
+ int _panelIndex;
+ BGUID _presenterGUID;
public:
ASSIGN_DESC(0,wxT("CoreObjects"), 1)
SLOTS_DECL
+ PanelProvider()
+ : _ipanelreciever(NULL), _inodeprovider(NULL), _panelIndex(-1) {}
+
virtual bool doRealize(ObjectChain* ochain);
virtual void doUnrealize(ObjectChain* ochain);
virtual coreString getPanelTitle();
virtual void panelActivate(wxPanel* panel);
virtual void panelDeactivate();
+
+ virtual int determineIndex(const guid_list_t& parserGUIDs);
+ virtual int getIndex() const;
+ virtual bool operator<(const PanelProvider& right) const;
};
/////////////////////////////////////////////////////////////////////////////
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browser/VirtualNode.cpp
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browser/VirtualNode.cpp 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browser/VirtualNode.cpp 2007-07-13 04:03:42 UTC (rev 28050)
@@ -50,7 +50,14 @@
_ochain = ochain;
}
+const guid_list_t& VirtualNodeItemData::getParsersOrdering() {
+ return _parsersOrdering;
+}
+void VirtualNodeItemData::setParsersOrdering(const guid_list_t& parsers) {
+ _parsersOrdering = parsers;
+}
+
/*static*/ VirtualNodeItemData* VirtualNodeItemData::getForNode(const wxTreeItemId& item) {
if (!item.IsOk())
return NULL;
@@ -119,7 +126,7 @@
}
-PIN_DESCS_EX(VirtualNode)
+PIN_DESCS(VirtualNode)
PIN_DESC(_nodePin, PIN_MULTICAST, getNodeProviderImpl, releaseNodeProviderImpl)
END_DESCS
@@ -136,7 +143,7 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-PIN_DESCS_EX(VirtualFile)
+PIN_DESCS(VirtualFile)
PIN_DESC(_filePin, PIN_DEFAULT | PIN_MULTICAST, getFile, releaseFile)
PIN_DESC(_streamPin, PIN_DEFAULT | PIN_MULTICAST, getFile, releaseFile)
END_DESCS
@@ -169,7 +176,7 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-PIN_DESCS_EX(VirtualDirectory)
+PIN_DESCS(VirtualDirectory)
PIN_DESC(_directoryPin, PIN_DEFAULT | PIN_MULTICAST, getDirectory, releaseDirectory)
END_DESCS
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browser/VirtualNode.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browser/VirtualNode.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browser/VirtualNode.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -6,7 +6,7 @@
#include "browser_stdafx.h"
-#include "pinslot.h"
+#include "BObject.h"
#include "CoreInterfaces.h"
@@ -25,12 +25,17 @@
class VirtualNode;
+// This class contains information tied to the visual representation of
+// a VirtualNode in the ExplorationTree. It enables the ExplorationTree
+// to get the VirtualNode from it's visual representation.
class BROWSER_API VirtualNodeItemData : public wxTreeItemData {
- VirtualNode* _node;
- bool _realized;
- bool _completed;
- ObjectChain* _ochain;
+ VirtualNode* _node; //the node we're tied to
+ bool _realized; //weather _node's object chain has been realized
+ bool _completed; //weather it has been completed
+ ObjectChain* _ochain; //_node's object chain
+ guid_list_t _parsersOrdering; //order in which parsers should be displayed
+
public:
VirtualNodeItemData(VirtualNode* node, ObjectChain* ochain);
//virtual ~VirtualNodeItemData() {}
@@ -42,6 +47,8 @@
void setCompleted(bool completed);
ObjectChain* getObjectChain();
void setObjectChain(ObjectChain* ochain);
+ const guid_list_t& getParsersOrdering();
+ void setParsersOrdering(const guid_list_t& parsers);
static VirtualNodeItemData* getForNode(const wxTreeItemId& item);
static VirtualNode* getNode(const wxTreeItemId& item);
@@ -50,6 +57,8 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+// INodeProvider is an interface, exposed by VirtulNode, that allows the
+// presenters get reference to the node they are presenting.
class BROWSER_API INodeProvider : public IInterface {
public:
GUID_FOR(INodeProvider, wxT("CoreInterfaces"), 1);
@@ -61,12 +70,14 @@
class INodeProviderImpl;
-//TODO: make it realizable in multiple chains
+// VirtualNode is an abstract piece of hierachical data, displayed in the
+// ExplorationTree. See the docs (Game Resource Browser Architecture Overview)
+// for an... overview.
+// TODO: make it realizable in multiple chains
class BROWSER_API VirtualNode : public BObject {
DECLARE_BOBJECT_CLASS(VirtualNode, BObject)
- //coreString _name;
- wxTreeItemId _mineTreeItem;
+ wxTreeItemId _mineTreeItem; //our tree item in the ExplorationTree
protected:
Pin<INodeProvider>* _nodePin;
@@ -93,7 +104,7 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-//this class defines an object that can deliver given IFile interface
+//this class defines a VirtualNode that can deliver given IFile interface
class BROWSER_API VirtualFile : public VirtualNode {
DECLARE_BOBJECT_CLASS(VirtualFile, VirtualNode)
@@ -123,7 +134,7 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-//this class defines an object that can deliver given IDirectory interface
+//this class defines a VirtualNode that can deliver given IDirectory interface
class BROWSER_API VirtualDirectory : public VirtualNode {
DECLARE_BOBJECT_CLASS(VirtualDirectory, VirtualNode)
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browser/browser_stdafx.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browser/browser_stdafx.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browser/browser_stdafx.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -19,7 +19,7 @@
//just to make compilation faster
#ifdef WX_PRECOMP
-#include "pinslot.h"
+#include "BObject.h"
#endif
#endif //_BROWSER_STDAFX_H_
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browserapp/Test1.cpp
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browserapp/Test1.cpp 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browserapp/Test1.cpp 2007-07-13 04:03:42 UTC (rev 28050)
@@ -29,7 +29,7 @@
#include "Directories.h"
//#include "DirectoryPresenter.h"
-//#include "BMPParser.h"
+//#include "BasicParsers.h"
//#include "ImagePresenter.h"
//#include "FileInfoPresenter.h"
#include "PanelProvider.h"
@@ -95,8 +95,6 @@
if (foxes.IsOk() && foxes.FileExists() && foxes.IsFileReadable())
rootDir->addFile(wxT("Foxes"), toString(foxes.GetFullPath()));
-
- ExplorationTree::get()->realizeVisible();
}
/////////////////////////////////////////////////////////////////////////////
@@ -138,8 +136,6 @@
if (foxes.IsOk() && foxes.FileExists() && foxes.IsFileReadable())
rootDir->addFile(wxT("Foxes"), toString(foxes.GetFullPath()));
-
- ExplorationTree::get()->realizeVisible();
}
/////////////////////////////////////////////////////////////////////////////
Modified: scummex/branches/gsoc2007-gameresbrowser/src/browserapp/Test2.cpp
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/browserapp/Test2.cpp 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/browserapp/Test2.cpp 2007-07-13 04:03:42 UTC (rev 28050)
@@ -29,7 +29,7 @@
#include "Directories.h"
//#include "DirectoryPresenter.h"
-//#include "BMPParser.h"
+//#include "BasicParsers.h"
//#include "ImagePresenter.h"
//#include "FileInfoPresenter.h"
#include "PanelProvider.h"
@@ -93,12 +93,28 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+//HACK: manual loading of the Scumm plugin
+
+#ifdef _MSC_VER
+ #define DLL_IMPORT __declspec(dllimport)
+#else
+ #define DLL_IMPORT
+#endif
+
+extern "C" {
+DLL_IMPORT const Plugin& getPlugin();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
void MainForm::OnTest2(wxCommandEvent& event) {
OnTest1Cleanup(event);
infoout << wxT("Registering Test2 Plugin.") << std::endl;
ObjectRegistry::get()->registerPlugin( &getTest2Plugin, false );
+ ObjectRegistry::get()->registerPlugin( &getPlugin, false );
FileTypeRegistry::get()->registerPlugins();
wxTreeItemId rootItem = ExplorationTree::get()->addRoot(wxT("RootDirectory"));
@@ -116,8 +132,6 @@
if (dataFN.IsOk() && dataFN.DirExists() && dataFN.IsDirReadable())
rootDir->addSubDir(wxT("data"), dataDir);
-
- ExplorationTree::get()->realizeVisible();
}
/////////////////////////////////////////////////////////////////////////////
@@ -159,6 +173,7 @@
infoout << wxT("Registering Test2 Plugin.") << std::endl;
ObjectRegistry::get()->registerPlugin( &getTest2Plugin, false );
+ ObjectRegistry::get()->registerPlugin( &getPlugin, false );
FileTypeRegistry::get()->registerPlugins();
wxTreeItemId rootItem = ExplorationTree::get()->addRoot(wxT("RootDirectory"));
@@ -178,8 +193,6 @@
//rootDir->addSubDir(wxT("data"), wxT("data"));
rootDir->addFile(fileName, fileName);
-
- ExplorationTree::get()->realizeVisible();
}
/////////////////////////////////////////////////////////////////////////////
Added: scummex/branches/gsoc2007-gameresbrowser/src/core/BObject.cpp
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/core/BObject.cpp (rev 0)
+++ scummex/branches/gsoc2007-gameresbrowser/src/core/BObject.cpp 2007-07-13 04:03:42 UTC (rev 28050)
@@ -0,0 +1,360 @@
+/////////////////////////////////////////////////////////////////////////////
+// pinslot.cpp
+//
+// Declares Pins and Slots
+// (plus factories, templates and macros for them)
+//
+
+#include "core_stdafx.h"
+
+#include <iostream>
+
+#include "BObject.h"
+#include "safe_static.h"
+
+#include "debugmem.h" //turn memory debugging ON
+
+
+namespace Core {
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// BObjectDesc - no philosophy here
+
+BObjectDesc::BObjectDesc(coreString name, const BGUID& objectGUID, int flags,
+ const PinSlotDescs& pinDescs, const PinSlotDescs& slotDescs)
+ : _name(name), _objectGUID(objectGUID), _flags(flags),
+ _pinDescs(pinDescs), _slotDescs(slotDescs) {}
+
+int BObjectDesc::get_flags() const {
+ return _flags;
+}
+const coreString& BObjectDesc::get_name() const {
+ return _name;
+}
+const BGUID& BObjectDesc::get_GUID() const {
+ return _objectGUID;
+}
+const PinSlotDescs& BObjectDesc::get_pins() const {
+ return _pinDescs;
+}
+const PinSlotDescs& BObjectDesc::get_slots() const {
+ return _slotDescs;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// init_pins_slots(), delete_pins_slots()
+//
+// As said in the BObject.h's comments, these functions are called during the
+// initialisation/deinitialisation phases of the BObject lifecycle.
+//
+// Their purpose is to initialize pins and slots of this object.
+//
+// How the initialisation works:
+// Pins and slots should be declared in a class like this:
+// Pin<IFoo>* _fooPin;
+// Slot<IFoo>* _fooSlot;
+//
+// They need to be initialized. One could do it by hand, but that would be
+// tedious. Instead we use RTTI for that.
+//
+// Every pin and slot is described in the class' RTTI.
+// An RTTI for a pin/slot (PinSlotDesc) knows how to access the said pin/slot.
+// For the purposes of the automatic initialisation it also knows how to
+// instantiate it (the PinSlotDesc::makePinSlot() method).
+//
+// So in init_pins_slots() we iterate over pins descriptions and instantiate the
+// pins. Same for slots. delete_pins_slots() is similar.
+//
+
+//do not call manually!
+void BObject::init_pins_slots() {
+ PinSlotDescs::the_map::const_iterator i;
+ const PinSlotDescs::the_map& pdescs = get_pins().getTheMap();
+ for (i = pdescs.begin(); i != pdescs.end(); ++i) {
+ PinSlotDesc* desc = i->second;
+ desc->makePinSlot(this);
+ }
+ const PinSlotDescs::the_map& sdescs = get_slots().getTheMap();
+ for (i = sdescs.begin(); i != sdescs.end(); ++i) {
+ PinSlotDesc* desc = i->second;
+ desc->makePinSlot(this);
+ }
+}
+
+//do not call manually!
+void BObject::delete_pins_slots() {
+ PinSlotDescs::the_map::const_iterator i;
+ const PinSlotDescs::the_map& pdescs = get_pins().getTheMap();
+ for (i = pdescs.begin(); i != pdescs.end(); ++i) {
+ PinSlotDesc* desc = i->second;
+ delete desc->getPinSlot(this);
+ }
+ const PinSlotDescs::the_map& sdescs = get_slots().getTheMap();
+ for (i = sdescs.begin(); i != sdescs.end(); ++i) {
+ PinSlotDesc* desc = i->second;
+ delete desc->getPinSlot(this);
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+BObject::BObject() {
+ _realized = false;
+ _ochain = NULL;
+}
+
+void BObject::initialize() {
+ InitializedObjects::get()->registerObject(this);
+ RCObject::initialize();
+ init_pins_slots();
+}
+
+void BObject::destroy() {
+ ASSERT( !isRealizedAnywhere() );
+ delete_pins_slots();
+ RCObject::destroy();
+ InitializedObjects::get()->unregisterObject(this);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//The implementations provided here are a good base for an object that can be
+//realized only in one ObjectChain at once. At the moment this is the case for
+//all objects in the Browser.
+
+bool BObject::isRealizedAnywhere() {
+ return _realized;
+}
+
+bool BObject::isRealized(ObjectChain* ochain) {
+ return _realized && (_ochain == ochain);
+}
+
+bool BObject::realize(ObjectChain* ochain) {
+ if (isRealizedAnywhere())
+ return false;
+ dumpRealizing(ochain);
+ bool res = doRealize(ochain);
+ dumpRealized(ochain, res);
+ return res;
+}
+
+bool BObject::doRealize(ObjectChain* ochain) {
+ _ochain = ochain;
+ _realized = true;
+ return true;
+}
+
+void BObject::unrealize(ObjectChain* ochain) {
+ if (!isRealized(ochain))
+ return;
+ dumpUnrealizing(ochain);
+ doUnrealize(ochain);
+ dumpUnrealized(ochain);
+}
+
+void BObject::doUnrealize(ObjectChain* ochain) {
+ _ochain = NULL;
+ _realized = false;
+}
+
+ObjectChain* BObject::getSingleObjectChain() {
+ if (!isRealized(_ochain))
+ return NULL;
+ return _ochain;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// The BObject has no pins nor slots - so these methods return empty lists:
+
+const PinSlotDescs& BObject::get_pins() const {
+ return this->get_desc().get_pins();
+}
+
+const PinSlotDescs& BObject::get_slots() const {
+ return this->get_desc().get_slots();
+}
+
+const PinSlotDescs& BObject::static_pins() {
+ ASSERT_STATICS_ALLOWED();
+ static PinSlotDescs descs;
+ return descs;
+}
+
+const PinSlotDescs& BObject::static_slots() {
+ ASSERT_STATICS_ALLOWED();
+ static PinSlotDescs descs;
+ return descs;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// Getting pins and slots for a given interface
+
+PinType* BObject::get_pin(const BGUID& interfaceGUID) {
+ return static_cast<PinType*>(get_pinSlot( interfaceGUID, get_pins() ));
+}
+
+SlotType* BObject::get_slot(const BGUID& interfaceGUID) {
+ return static_cast<SlotType*>(get_pinSlot( interfaceGUID, get_slots() ));
+}
+
+PinSlotType* BObject::get_pinSlot(const BGUID& interfaceGUID, const PinSlotDescs& descs) {
+ PinSlotDesc* desc = descs.find(interfaceGUID);
+ if (!desc)
+ return NULL;
+ return desc->getPinSlot(this);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// DEBUG METHODS BELOW
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// Debug routines for dumping object's realisation/unrealisation
+
+int _dump_realize_indent = 0;
+
+void dump_realize_indent() {
+ ASSERT_STATICS_ALLOWED();
+ ASSERT(_dump_realize_indent >= 0);
+ int indent = _dump_realize_indent;
+ while (indent-- > 0)
+ infoout << wxT(" ");
+}
+
+#define NO_REALIZE_DEBUG
+#ifdef NO_REALIZE_DEBUG
+
+void BObject::dumpRealizing(ObjectChain* ochain) {}
+//void BObject::dumpRealized(ObjectChain* ochain, bool result) {}
+
+void BObject::dumpRealized(ObjectChain* ochain, bool result) {
+ if (result)
+ return;
+ ASSERT_STATICS_ALLOWED();
+ _dump_realize_indent--;
+ dump_realize_indent();
+ infoout << (result ? wxT("REALIZED: ") : wxT("R-FAILED: "));
+ infoout << this->dumpName().c_str() << wxT("\t\t") << this << wxT(" oc: ") << ochain << std::endl;
+}
+
+void BObject::dumpUnrealizing(ObjectChain* ochain) {}
+void BObject::dumpUnrealized(ObjectChain* ochain) {}
+
+#else
+
+void BObject::dumpRealizing(ObjectChain* ochain) {
+ dump_realize_indent();
+ infoout << wxT("REALIZING:");
+ infoout << this->dumpName().c_str() << wxT("\t\t") << this << wxT(" oc: ") << ochain << std::endl;
+ ASSERT_STATICS_ALLOWED();
+ _dump_realize_indent++;
+}
+
+void BObject::dumpRealized(ObjectChain* ochain, bool result) {
+ ASSERT_STATICS_ALLOWED();
+ _dump_realize_indent--;
+ dump_realize_indent();
+ infoout << (result ? wxT("REALIZED: ") : wxT("R-FAILED: "));
+ infoout << this->dumpName().c_str() << wxT("\t\t") << this << wxT(" oc: ") << ochain << std::endl;
+}
+
+void BObject::dumpUnrealizing(ObjectChain* ochain) {
+ dump_realize_indent();
+ infoout << wxT("UNREALIZING: ");
+ infoout << this->dumpName().c_str() << wxT("\t\t") << this << wxT(" oc: ") << ochain << std::endl;
+ ASSERT_STATICS_ALLOWED();
+ _dump_realize_indent++;
+}
+
+void BObject::dumpUnrealized(ObjectChain* ochain) {
+ ASSERT_STATICS_ALLOWED();
+ _dump_realize_indent--;
+ dump_realize_indent();
+ infoout << wxT("UNREALIZED: ");
+ infoout << this->dumpName().c_str() << wxT("\t\t") << this << wxT(" oc: ") << ochain << std::endl;
+}
+
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// Also for debugging
+
+/*virtual*/ void BObject::dumpObjectChains(streamout& os) {
+}
+
+//a name used for debugging
+/*virtual*/ coreString BObject::dumpName() {
+ return this->get_GUID().identifier;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// InitializedObjects
+
+InitializedObjects* InitializedObjects::_instance = NULL;
+
+/*static*/ InitializedObjects* InitializedObjects::get() {
+ ASSERT_STATICS_ALLOWED();
+ static bool _allow_creation = true;
+ if (!_instance) {
+ ASSERT(_allow_creation);
+ _allow_creation = false;
+ _instance = new InitializedObjects();
+ }
+
+ return _instance;
+}
+
+/*static*/ void InitializedObjects::release() {
+ if (_instance) {
+ ASSERT( _instance->_initializedObjects.size() == 0 );
+ delete _instance;
+ }
+
+ _instance = NULL;
+}
+
+void InitializedObjects::registerObject(BObject* obj) {
+ ASSERT(!isValid(obj));
+
+ _initializedObjects.insert(obj);
+}
+
+void InitializedObjects::unregisterObject(BObject* obj) {
+ ASSERT(isValid(obj));
+
+ _initializedObjects.erase(obj);
+}
+
+bool InitializedObjects::isValid(BObject* obj) {
+ std::set<BObject*>::const_iterator i;
+ i = _initializedObjects.find(obj);
+ return i != _initializedObjects.end();
+}
+
+void InitializedObjects::report() {
+ infoout << wxT("------------ DUMPING INITIALIZED OBJECTS -------------") << std::endl;
+ infoout << wxT("OBJECTS COUNT: ") << _initializedObjects.size() << std::endl;
+
+ std::set<BObject*>::const_iterator i;
+ for (i = _initializedObjects.begin(); i != _initializedObjects.end(); ++i) {
+ BObject* obj = *i;
+ infoout << obj->dumpName().c_str() << wxT(":\t\t") << obj << std::endl;
+ }
+
+ infoout << wxT("---------- DONE DUMPING INITIALIZED OBJECTS ----------") << std::endl;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+} // namespace Core
Property changes on: scummex/branches/gsoc2007-gameresbrowser/src/core/BObject.cpp
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Added: scummex/branches/gsoc2007-gameresbrowser/src/core/BObject.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/core/BObject.h (rev 0)
+++ scummex/branches/gsoc2007-gameresbrowser/src/core/BObject.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -0,0 +1,287 @@
+/////////////////////////////////////////////////////////////////////////////
+// pinslot.h
+//
+// Declares Pins and Slots
+// (plus factories, templates and macros for them)
+//
+
+#pragma once
+#ifndef _BOBJECT_H
+#define _BOBJECT_H
+
+#include "pinslot.h"
+#include "rcobject.h"
+
+#include <set> // for InitializedObjects
+
+namespace Core {
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+//TODO: use IS_... in ObjectChain::complete() logic
+enum BObjectFlags {
+ IS_FILE_TYPE_RECOGNIZER = 1,
+ IS_FILE_TYPE_RESOLVER = 2,
+ IS_PROVIDER = 4, //unused for now
+ IS_FILTER = 8, //unused for now
+ IS_PRESENTER = 16, //unused for now
+};
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// BObjectDesc gives additional runtime type information about an object:
+// it's guid, a human readable name (for debugging), it's flags, and
+// most importantly the descriptions of its pins and slots.
+//
+// BObjectDesc is a per-class information, that can be accessed statically
+// through Class::static_desc(), as well as dynamically from an BObject using
+// obj->get_desc().
+//
+// This extra run-time type information allows us to implement an ObjectRegistry,
+// which can be querried for object classes meeting our needs (i.e. objects
+// that expose an IText slot). Static information is used to look for a proper
+// class, and then instantiate an object from it if required (see ObjectPlugin
+// class from plugin.h).
+//
+// It also allows to implement ObjectChain::complete() logic. Here the dynamic
+// information is used to querry for the existing object's pins and slots, which
+// are then connected apropriately.
+
+struct CORE_API BObjectDesc {
+private:
+ coreString _name;
+ const BGUID _objectGUID;
+ int _flags;
+ const PinSlotDescs& _pinDescs;
+ const PinSlotDescs& _slotDescs;
+
+public:
+ BObjectDesc(coreString name, const BGUID& objectGUID, int flags,
+ const PinSlotDescs& pinDescs, const PinSlotDescs& slotDescs);
+
+ int get_flags() const;
+ const coreString& get_name() const;
+ const BGUID& get_GUID() const;
+ const PinSlotDescs& get_pins() const;
+ const PinSlotDescs& get_slots() const;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// BObject
+//
+// BObject is a reference counted object that is capable of holding pins and slots.
+//
+// Pins and slots should be declared in a class like this:
+// Pin<IFoo>* _fooPin;
+// Slot<IFoo>* _fooSlot;
+//
+//
+// How the RTTI for a BObject is constructed:
+// There are two macros for that:
+//
+// DECLARE_BOBJECT_CLASS(clazz, super) - declares this_class,
+// and super_class typdefs
+// ASSIGN_DESC(flags, facility, version) - implements get_desc() and
+// static_desc() methods and
+// assigns a guid for the class
+// flags - some of the BObjectFlags
+// facility, version - along with the class' name they produce a guid
+//
+//
+// How pins and slots RTTI is constructed:
+// PINS_DECL - declare static_pins() method
+// SLOTS_DECL - declare static_slots() method
+//
+// PIN_DESCS(clazz) - implement static_pins() method
+// PIN_DESC(_fooPin, pinFlags, getFun, releaseFun)
+// PIN_DESC(_barPin, pinFlags, getFun, releaseFun)
+// END_DESCS
+// SLOT_DESCS(clazz) - implement static_slots() method
+// PIN_DESC(_fooSlot, slotFlags)
+// PIN_DESC(_barSlot, slotFlags)
+// END_DESCS
+//
+// The above macros simply construct the PinSlotDescs for particular pins and slots.
+// The list of pin descs is implemented as a static variable in the static_pins()
+// method. The PIN_DESC() macro simply inserts a new element into this list.
+//
+//
+// So our final derived BObject look like this:
+//
+// class MyObject : public BObject {
+// DECLARE_BOBJECT_CLASS(clazz, super)
+//
+// Pin<IFoo>* _fooPin;
+// Slot<IFoo>* _fooSlot;
+//
+// public:
+// ASSIGN_DESC(0, "MyObjects", 1)
+//
+// PINS_DECL
+// SLOTS_DECL
+//
+// IFoo* createIFoo() {
+// return new IFoo();
+// }
+//
+// void releaseIFoo(IFoo* ifoo) {
+// delete ifoo;
+// }
+//
+// };
+//
+// PIN_DESCS(MyObject)
+// PIN_DESC(_fooPin, PIN_DEFAULT, createIFoo, releaseIFoo)
+// END_DESCS
+// SLOT_DESCS(MyObject)
+// PIN_DESC(_fooSlot, SLOT_DEFAULT)
+// END_DESCS
+//
+// This is of course only one possible implementation of the pin/slot architecture.
+// I've chosen it because it's the most flexible one. And really easy to use, I think.
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// BObject
+
+class ObjectChain;
+
+class CORE_API BObject : public RCObject, public GUIDObject {
+
+private:
+ // These functions are called during the initialize()/destroy() lifetime
+ // phases (see docs for an overview of a BObjects lifetime).
+ // Their purpose is to initialize/destroy pins and slots.
+ void init_pins_slots();
+ void delete_pins_slots();
+
+public:
+
+ BObject();
+
+ // Those methods below are here, and not in the constructor/destructor, because
+ // they use virtual functions. So they need to be called on a fully constructed
+ // object. (see docs for an overview of a BObjects lifetime)
+
+ //when overriding allways run super
+ virtual void initialize();
+ virtual void destroy();
+
+ //other lifecycle methods:
+
+ virtual bool isRealizedAnywhere(); //check if this object is realized
+ //in any object chain
+
+ virtual bool isRealized(ObjectChain* ochain); //check if this object is realized
+ //in a particular object chain
+
+ //invoked to initialize the object in the ObjectChain
+ //realize can query the ObjectChain (the object is already a member of it)
+ virtual bool realize(ObjectChain* ochain);
+ virtual bool doRealize(ObjectChain* ochain);
+
+ //invoked to uninitialize the object in the ObjectChain
+ //unrealize can query the ObjectChain (the object is still a member of it)
+ virtual void unrealize(ObjectChain* ochain);
+ virtual void doUnrealize(ObjectChain* ochain);
+
+ //get any object chain we're initalized in - usefull for objects that can be
+ //initialized in only one object chain (all Browser's object at the moment)
+ virtual ObjectChain* getSingleObjectChain();
+
+protected:
+ bool _realized; //see isRealizedAnywhere()
+ ObjectChain* _ochain; //the object chain we're realized in
+
+public:
+ //methods for accessing object's run-time type information
+ //subclasses must provide their implementations of the following methods:
+ // get_desc()
+ // static_desc()
+ // static_pins() - if there are any new pins it the subclass
+ // static_slots() - if there are any new slots it the subclass
+
+ //get dynamic RTTI
+ virtual const BObjectDesc& get_desc() const = 0;
+
+ //get dynamic information about pins/slots (uses get_desc() internally)
+ const PinSlotDescs& get_pins() const;
+ const PinSlotDescs& get_slots() const;
+
+ //get static RTTI - subclasses must define it (BObject is abstract anyway, so it don't need to)
+ //static const BObjectDesc& static_desc();
+
+ //functions providing static information about pins and slots
+ static const PinSlotDescs& static_pins();
+ static const PinSlotDescs& static_slots();
+
+ //methods to get a pin/slot for a given interface
+ PinType* get_pin(const BGUID& interfaceGUID);
+ SlotType* get_slot(const BGUID& interfaceGUID);
+
+private:
+ PinSlotType* get_pinSlot(const BGUID& interfaceGUID, const PinSlotDescs& descs);
+
+public:
+ //debugging routines:
+
+ //function used to dump any object chains this object may own
+ //the semantics of an object chain being "owned" by an BObject is not defined
+ //(for a DirectoryPresenter these are the object chains it created for it's files)
+ virtual void dumpObjectChains(streamout& os);
+
+ //functions used for debugging object realisation/unrealisation
+ void dumpRealizing(ObjectChain* ochain);
+ void dumpRealized(ObjectChain* ochain, bool result);
+ void dumpUnrealizing(ObjectChain* ochain);
+ void dumpUnrealized(ObjectChain* ochain);
+
+ //a name used for debugging
+ virtual coreString dumpName();
+};
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// InitializedObjects is a singleton that holds a set of all existing BObjects.
+// This is for debugging purposes only.
+
+class CORE_API InitializedObjects {
+ static InitializedObjects* _instance;
+ InitializedObjects() {}
+
+ #ifdef _MSC_VER
+ #pragma warning(disable : 4251)
+ #endif
+ std::set<BObject*> _initializedObjects;
+ #ifdef _MSC_VER
+ #pragma warning(default : 4251)
+ #endif
+
+public:
+ static InitializedObjects* get();
+ static void release();
+
+ void registerObject(BObject* obj);
+ void unregisterObject(BObject* obj);
+ bool isValid(BObject* obj);
+
+ void report();
+};
+
+#define ASSERT_VALID(obj) \
+ ASSERT( InitializedObjects::get()->isValid(obj) )
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// Include all the hacky stuff
+
+} // namespace Core
+
+#include "pinslot_detail.h"
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+#endif /* _BOBJECT_H */
Property changes on: scummex/branches/gsoc2007-gameresbrowser/src/core/BObject.h
___________________________________________________________________
Name: svn:mime-type
+ text/plain
Name: svn:eol-style
+ native
Modified: scummex/branches/gsoc2007-gameresbrowser/src/core/GUIDObject.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/core/GUIDObject.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/core/GUIDObject.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
// GUIDObject.h
//
-// Declares GUIDObject and some helpers
+// Declares GUIDObject and some helpers.
//
#ifndef _GUIDOBJECT_H_
@@ -24,13 +24,14 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+// GUIDObject is an interface for any class having a guid
class CORE_API GUIDObject {
public:
virtual const BGUID& get_GUID() = 0;
+ virtual ~GUIDObject() {} //so that GCC won't complain on -Wall
};
-//TODO: MAKE IT NOT INLINE - safer for DLL's (same for other inlines...)
#define ASSIGN_GUID_VERBOSE(name, facility, version) \
virtual const BGUID& get_GUID() { \
return /*clazz::*/static_GUID(); \
Modified: scummex/branches/gsoc2007-gameresbrowser/src/core/ObjectChain.cpp
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/core/ObjectChain.cpp 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/core/ObjectChain.cpp 2007-07-13 04:03:42 UTC (rev 28050)
@@ -221,8 +221,7 @@
bool res = true;
//iterate over pins and slots and disconnect them:
- //(careful not to disconnect pins/slots that are connected in some other
- //ObjectChain)
+
PinSlotDescs::the_map::const_iterator i;
const PinSlotDescs::the_map& pins = obj->get_pins().getTheMap();
for (i = pins.begin(); i != pins.end(); ++i) {
@@ -248,6 +247,7 @@
objects.erase(obj); //the ref count just went down
}
+//order the object front-to-back and realize them
bool ObjectChain::realize() {
ordered_objs objs;
order_back_to_front(objs);
@@ -265,6 +265,7 @@
return res;
}
+//order the object back-to-front and unrealize them
void ObjectChain::unrealize() {
ordered_objs objs;
order_back_to_front(objs);
@@ -281,6 +282,7 @@
}
}
+//remove the objects in back-to-front order
void ObjectChain::removeAllObjects() {
ordered_objs objs;
order_back_to_front(objs);
@@ -299,6 +301,7 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+//returns any not yet connected default pin (or slot) of an object
PinSlotDesc* ObjectChain::_get_not_connected(BObject* obj, bool ifPin) {
PinSlotDescs::the_map::const_iterator i;
@@ -325,7 +328,18 @@
return NULL;
}
-//FIXME: implement whole completion logic
+// This method implements the completion logic as described in the
+// docs. Nothing particuraly interesting in it's implementation.
+//
+// The algorith is simple:
+// - find not yet connected pin,
+// - find an object in the graph with a matching slot,
+// - if there's none instantiate one from the ObjectRegistry,
+// - connect the objects and find another not connected pin.
+//
+// - do the same for not connected slots, but don't instantiate new objects.
+//
+// FIXME: implement whole completion logic, speed it up
void ObjectChain::complete() {
PinSlotDesc* desc;
ordered_objs objs;
@@ -557,6 +571,68 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+//functor for determining, wheather a node with a specified GUID has been visited
+struct ocVisitAncestorGUID {
+ const BGUID& _ancestorGUID;
+ BObject* _foundObj;
+ ocVisitAncestorGUID(const BGUID& ancestorGUID)
+ : _ancestorGUID(ancestorGUID), _foundObj(NULL) {}
+
+ int operator()(BObject* obj, int level) {
+ if (_ancestorGUID == obj->get_GUID()) {
+ _foundObj = obj;
+ return tree_algos::DONE;
+ }
+ return tree_algos::CONTINUE;
+ }
+ BObject* getFoundObj() {
+ return _foundObj;
+ }
+};
+
+//functor for collecting all the ancestors
+struct ocVisitAncestor {
+ std::list<BObject*> _ancestors;
+ int operator()(BObject* obj, int level) {
+ _ancestors.push_back(obj);
+ return tree_algos::CONTINUE;
+ }
+ const std::list<BObject*>& getAncestors() {
+ return _ancestors;
+ }
+};
+
+BObject* ObjectChain::getAncestorOrSelf(BObject* obj, const BGUID& ancestorGUID) {
+ ASSERT( objects.count(obj) == 1 ); // must be our object
+
+ //bfs:
+ //initial node: = obj
+ //expand: for every slot in node add connected pin's owner
+ //visit: return true if node's guid == ancestorGUID
+
+ ocVisitAncestorGUID visit(ancestorGUID);
+ ocExpand expand(this);
+ bool found = tree_algos::bfs(obj, visit, expand);
+ return visit.getFoundObj();
+}
+
+std::list<BObject*> ObjectChain::getAncestorsAndSelf(BObject* obj) {
+ ASSERT( objects.count(obj) == 1 ); // must be our object
+
+ //bfs:
+ //initial node: = obj
+ //expand: for every slot in node add connected pin's owner
+ //visit: collect visited nodes
+
+ ocVisitAncestor visit;
+ ocExpand expand(this);
+ bool found = tree_algos::bfs(obj, visit, expand);
+ return visit.getAncestors();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
int _dump_ochain_indent = 0;
coreString _doi() {
Modified: scummex/branches/gsoc2007-gameresbrowser/src/core/ObjectChain.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/core/ObjectChain.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/core/ObjectChain.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -8,18 +8,24 @@
#ifndef ZZ_OCHAIN_H
#define ZZ_OCHAIN_H
-#include "pinslot.h"
+#include "BObject.h"
#include <ostream>
#include <map>
#include <set>
#include <vector>
+#include <list>
namespace Core {
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+// ObjectChain is a class that represents a directed acyclic graph of BObjects.
+// It has a few utility functions to manipulate the graph, however to most
+// important one is the complete() method. This method automatically "completes"
+// the graph, instantiating new objects from ObjectRegistry if required.
+// See the docs for details.
//Connecting Pins and Slots does not change ref counts.
//ObjectChain holds BObjects and connections between them.
@@ -51,6 +57,7 @@
public:
+ //dumps object chain's graph in a .dot format to a file
bool dumpObjectChain(coreString fileName);
void dumpObjectChainStart(coreString ochainname, streamout& os);
void dumpObjectChain(coreString ochainname, streamout& os);
@@ -62,10 +69,17 @@
bool isContained(const RCPtr<BObject>& obj);
bool isContained(const BGUID& objGUID);
+ //get obj's ancestor with a given GUID in the object chain's DAG
+ //if obj have this GUID - return obj
+ BObject* getAncestorOrSelf(BObject* obj, const BGUID& ancestorGUID);
+
+ //returns all the ancestors of the obj and the obj in a list
+ //obj is first, last ancestor is last
+ std::list<BObject*> getAncestorsAndSelf(BObject* obj);
+
+ //complete, realize and unrealize the object chain - see the docs for details
void complete();
-
bool realize();
-
void unrealize();
//returns true if connected
@@ -123,7 +137,7 @@
private:
- //Order objects in wxT("destruction") order
+ //Order objects in "destruction" order
//it stores the result in objs
void order_back_to_front(ordered_objs& objs);
@@ -159,6 +173,7 @@
SlotType* _match_slot(PinType* pin, SlotType* slot);
}*/
+ //returns any not yet connected default pin (or slot) of an object
PinSlotDesc* _get_not_connected(BObject* obj, bool ifPin);
};
Modified: scummex/branches/gsoc2007-gameresbrowser/src/core/pinslot.cpp
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/core/pinslot.cpp 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/core/pinslot.cpp 2007-07-13 04:03:42 UTC (rev 28050)
@@ -81,9 +81,8 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-// 'annotation_map' is not too pretty. Maybe it should be cleaned up a bit - later.
-// It has one very concrete purpose - to hold pins' ans slots' descriptions.
-// Not for broad use.
+// annotation_map has one very concrete purpose - to hold pins' ans slots'
+// descriptions. Not for broad use.
namespace pinslot_detail {
@@ -148,320 +147,4 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-BObjectDesc::BObjectDesc(coreString name, const BGUID& objectGUID, int flags,
- const PinSlotDescs& pinDescs, const PinSlotDescs& slotDescs)
- : _name(name), _objectGUID(objectGUID), _flags(flags),
- _pinDescs(pinDescs), _slotDescs(slotDescs) {}
-
-int BObjectDesc::get_flags() const {
- return _flags;
-}
-const coreString& BObjectDesc::get_name() const {
- return _name;
-}
-const BGUID& BObjectDesc::get_GUID() const {
- return _objectGUID;
-}
-const PinSlotDescs& BObjectDesc::get_pins() const {
- return _pinDescs;
-}
-const PinSlotDescs& BObjectDesc::get_slots() const {
- return _slotDescs;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-// InitializedObjects
-
-InitializedObjects* InitializedObjects::_instance = NULL;
-
-/*static*/ InitializedObjects* InitializedObjects::get() {
- ASSERT_STATICS_ALLOWED();
- static bool _allow_creation = true;
- if (!_instance) {
- ASSERT(_allow_creation);
- _allow_creation = false;
- _instance = new InitializedObjects();
- }
-
- return _instance;
-}
-
-/*static*/ void InitializedObjects::release() {
- if (_instance) {
- ASSERT( _instance->_initializedObjects.size() == 0 );
- delete _instance;
- }
-
- _instance = NULL;
-}
-
-void InitializedObjects::registerObject(BObject* obj) {
- ASSERT(!isValid(obj));
-
- _initializedObjects.insert(obj);
-}
-
-void InitializedObjects::unregisterObject(BObject* obj) {
- ASSERT(isValid(obj));
-
- _initializedObjects.erase(obj);
-}
-
-bool InitializedObjects::isValid(BObject* obj) {
- std::set<BObject*>::const_iterator i;
- i = _initializedObjects.find(obj);
- return i != _initializedObjects.end();
-}
-
-void InitializedObjects::report() {
- infoout << wxT("------------ DUMPING INITIALIZED OBJECTS -------------") << std::endl;
- infoout << wxT("OBJECTS COUNT: ") << _initializedObjects.size() << std::endl;
-
- std::set<BObject*>::const_iterator i;
- for (i = _initializedObjects.begin(); i != _initializedObjects.end(); ++i) {
- BObject* obj = *i;
- infoout << obj->dumpName().c_str() << wxT(":\t\t") << obj << std::endl;
- }
-
- infoout << wxT("---------- DONE DUMPING INITIALIZED OBJECTS ----------") << std::endl;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-// BObject is a reference counted object that is capable of holding pins and slots.
-
-int _dump_realize_indent = 0;
-
-void dump_realize_indent() {
- ASSERT_STATICS_ALLOWED();
- ASSERT(_dump_realize_indent >= 0);
- int indent = _dump_realize_indent;
- while (indent-- > 0)
- infoout << wxT(" ");
-}
-
-#define NO_REALIZE_DEBUG
-#ifdef NO_REALIZE_DEBUG
-
-void BObject::dumpRealizing(ObjectChain* ochain) {}
-//void BObject::dumpRealized(ObjectChain* ochain, bool result) {}
-
-void BObject::dumpRealized(ObjectChain* ochain, bool result) {
- if (result)
- return;
- ASSERT_STATICS_ALLOWED();
- _dump_realize_indent--;
- dump_realize_indent();
- infoout << (result ? wxT("REALIZED: ") : wxT("R-FAILED: "));
- infoout << this->dumpName().c_str() << wxT("\t\t") << this << wxT(" oc: ") << ochain << std::endl;
-}
-
-void BObject::dumpUnrealizing(ObjectChain* ochain) {}
-void BObject::dumpUnrealized(ObjectChain* ochain) {}
-
-#else
-
-void BObject::dumpRealizing(ObjectChain* ochain) {
- dump_realize_indent();
- infoout << wxT("REALIZING:");
- infoout << this->dumpName().c_str() << wxT("\t\t") << this << wxT(" oc: ") << ochain << std::endl;
- ASSERT_STATICS_ALLOWED();
- _dump_realize_indent++;
-}
-
-void BObject::dumpRealized(ObjectChain* ochain, bool result) {
- ASSERT_STATICS_ALLOWED();
- _dump_realize_indent--;
- dump_realize_indent();
- infoout << (result ? wxT("REALIZED: ") : wxT("R-FAILED: "));
- infoout << this->dumpName().c_str() << wxT("\t\t") << this << wxT(" oc: ") << ochain << std::endl;
-}
-
-void BObject::dumpUnrealizing(ObjectChain* ochain) {
- dump_realize_indent();
- infoout << wxT("UNREALIZING: ");
- infoout << this->dumpName().c_str() << wxT("\t\t") << this << wxT(" oc: ") << ochain << std::endl;
- ASSERT_STATICS_ALLOWED();
- _dump_realize_indent++;
-}
-
-void BObject::dumpUnrealized(ObjectChain* ochain) {
- ASSERT_STATICS_ALLOWED();
- _dump_realize_indent--;
- dump_realize_indent();
- infoout << wxT("UNREALIZED: ");
- infoout << this->dumpName().c_str() << wxT("\t\t") << this << wxT(" oc: ") << ochain << std::endl;
-}
-
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
-//do not call manually!
-void BObject::init_pins_slots() {
- PinSlotDescs::the_map::const_iterator i;
- const PinSlotDescs::the_map& pdescs = get_pins().getTheMap();
- for (i = pdescs.begin(); i != pdescs.end(); ++i) {
- PinSlotDesc* desc = i->second;
- desc->makePinSlot(this);
- }
- const PinSlotDescs::the_map& sdescs = get_slots().getTheMap();
- for (i = sdescs.begin(); i != sdescs.end(); ++i) {
- PinSlotDesc* desc = i->second;
- desc->makePinSlot(this);
- }
-}
-
-//do not call manually!
-void BObject::delete_pins_slots() {
- PinSlotDescs::the_map::const_iterator i;
- const PinSlotDescs::the_map& pdescs = get_pins().getTheMap();
- for (i = pdescs.begin(); i != pdescs.end(); ++i) {
- PinSlotDesc* desc = i->second;
- delete desc->getPinSlot(this);
- }
- const PinSlotDescs::the_map& sdescs = get_slots().getTheMap();
- for (i = sdescs.begin(); i != sdescs.end(); ++i) {
- PinSlotDesc* desc = i->second;
- delete desc->getPinSlot(this);
- }
-}
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
-BObject::BObject() {
- _realized = false;
- _ochain = NULL;
-}
-
-// Those methods below are here, and not in the constructor/destructor, because
-// they use virtual functions. So they need to be called on a fully constructed
-// object.
-
-//when overriding allways run super
-/*virtual*/ void BObject::initialize() {
- InitializedObjects::get()->registerObject(this);
- RCObject::initialize();
- init_pins_slots();
-}
-
-//when overriding allways run super
-/*virtual*/ void BObject::destroy() {
- ASSERT( !isRealizedAnywhere() );
- delete_pins_slots();
- RCObject::destroy();
- InitializedObjects::get()->unregisterObject(this);
-}
-
-//other lifecycle methods:
-//The implementations provided here are a good base for an object that can be
-//realized only in one ObjectChain at once.
-
-/*virtual*/ bool BObject::isRealizedAnywhere() {
- return _realized;
-}
-
-/*virtual*/ bool BObject::isRealized(ObjectChain* ochain) {
- return _realized && (_ochain == ochain);
-}
-
-//invoked to initialize the object in the ObjectChain
-//realize can query the ObjectChain (the object is already a member of it)
-/*virtual*/ bool BObject::realize(ObjectChain* ochain) {
- if (isRealizedAnywhere())
- return false;
- dumpRealizing(ochain);
- bool res = doRealize(ochain);
- dumpRealized(ochain, res);
- return res;
-}
-
-/*virtual*/ bool BObject::doRealize(ObjectChain* ochain) {
- _ochain = ochain;
- _realized = true;
- return true;
-}
-
-//invoked to uninitialize the object in the ObjectChain
-//unrealize can query the ObjectChain (the object is still a member of it)
-/*virtual*/ void BObject::unrealize(ObjectChain* ochain) {
- if (!isRealized(ochain))
- return;
- dumpUnrealizing(ochain);
- doUnrealize(ochain);
- dumpUnrealized(ochain);
-}
-
-/*virtual*/ void BObject::doUnrealize(ObjectChain* ochain) {
- _ochain = NULL;
- _realized = false;
-}
-
-/*virtual*/ ObjectChain* BObject::getSingleObjectChain() {
- if (!isRealized(_ochain))
- return NULL;
- return _ochain;
-}
-
-/*virtual*/ void BObject::dumpObjectChains(streamout& os) {
-}
-
-//a name used for debugging
-/*virtual*/ coreString BObject::dumpName() {
- return this->get_GUID().identifier;
-}
-
-/*GUID_FOR(BObject, wxT("CoreObjects"), 1)
-virtual const BObjectDesc& get_desc() const {
- return BObject::static_desc();
-}
-static const BObjectDesc& static_desc() {
- static BObjectDesc desc(wxT("BObject"), BObject::static_GUID(), 0,
- BObject::static_pins(), BObject::static_slots());
- return desc;
-}*/
-
-/*virtual*/ const PinSlotDescs& BObject::get_pins() const {
- return this->get_desc().get_pins();
-}
-/*virtual*/ const PinSlotDescs& BObject::get_slots() const {
- return this->get_desc().get_slots();
-}
-
-/*static*/ const PinSlotDescs& BObject::static_pins() {
- ASSERT_STATICS_ALLOWED();
- static PinSlotDescs descs;
- return descs;
-}
-
-/*static*/ const PinSlotDescs& BObject::static_slots() {
- ASSERT_STATICS_ALLOWED();
- static PinSlotDescs descs;
- return descs;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
-PinType* BObject::get_pin(const BGUID& interfaceGUID) {
- return static_cast<PinType*>(get_pinSlot( interfaceGUID, get_pins() ));
-}
-
-SlotType* BObject::get_slot(const BGUID& interfaceGUID) {
- return static_cast<SlotType*>(get_pinSlot( interfaceGUID, get_slots() ));
-}
-
-PinSlotType* BObject::get_pinSlot(const BGUID& interfaceGUID, const PinSlotDescs& descs) {
- PinSlotDesc* desc = descs.find(interfaceGUID);
- if (!desc)
- return NULL;
- return desc->getPinSlot(this);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
} // namespace Core
Modified: scummex/branches/gsoc2007-gameresbrowser/src/core/pinslot.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/core/pinslot.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/core/pinslot.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -10,13 +10,10 @@
#define _PINSLOT_H
#include <map> // for PinSlotDescs
-#include <set> // for InitializedObjects
#include "GUIDObject.h"
-#include "tostring.h"
#include "debugmem.h" //turn memory debugging ON
-#include "rcobject.h" //Scott Meyers' reference counted object
namespace Core {
@@ -26,7 +23,7 @@
//CAUTION: Flags (besides IS_PIN and IS_SLOT) are only *hints* for the automatic
// pin/slot connecting in the ObjectChain.
// I.e. you can't rely on a singlecast pin to be connected to only once.
-enum {
+enum PinSlotFlags {
IS_PIN = 1,
IS_SLOT = 2,
PIN_DEFAULT = 4, //ObjectChain should try to connect it with some slot
@@ -34,21 +31,13 @@
PIN_MULTICAST = 16, //ObjectChain is allowed to connect many slots to this pin
};
-//TODO: introduce BObjectDesc
-//TODO: use IS_... in ObjectChain::complete() logic
-enum {
- IS_FILE_TYPE_RECOGNIZER = 1,
- IS_FILE_TYPE_RESOLVER = 2,
- IS_PROVIDER = 4, //unused for now
- IS_FILTER = 8, //unused for now
- IS_PRESENTER = 16, //unused for now
-};
-
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Interface
//Interfaces are not reference counted.
+//Interfaces bits of data exchanged between object.
+//See docs for an overview.
class CORE_API IInterface : public GUIDObject {
public:
@@ -58,6 +47,11 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Pins and Slots
+//
+// Pins and slots are used to connect objects. See docs for an overview.
+//
+// Pins and slots have descriptions which tell what interface they expose/accept,
+// and their flags (PIN_DEFAULT etc.)
struct _PinSlotDesc;
@@ -79,14 +73,18 @@
virtual bool isConnected() = 0;
};
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// Pin<T> is a typesafe pin.
+// The semantics of getInterface() and releaseInterface() is described in docs.
+// (In short: a slot's getInterface() invokes it's connected pin's getInterface().
+// Same with releaseInterface(). One must release every interface he aquired.)
+
template<typename I>
struct Pin : PinType {
virtual I* getInterface() = 0;
virtual void releaseInterface(I* iface) = 0;
- /*virtual IInterface* getInterface() {
- return static_cast<IInterface*>(I* (*)())getInterface();
- }*/
virtual void releaseInterface(IInterface* iface) {
releaseInterface(static_cast<I*>(iface));
}
@@ -97,9 +95,6 @@
virtual I* getInterface() = 0;
virtual void connect(Pin<I>* _pin) = 0;
- /*virtual IInterface* getInterface() {
- return static_cast<IInterface*>(I* (*)())getInterface();
- }*/
virtual void connect(PinType* _pin) {
connect(static_cast<Pin<I>*>(_pin));
}
@@ -108,16 +103,16 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Desciptor of Slots and Pins
-// As for now a descriptor has:
+// Descriptor has:
// interfaceGUID - a guid of the interface that this pin/slot provides/accepts
// name - a human readable name
// flags - flags of a pin/slot (default/multicast/pin/slot...)
struct CORE_API _PinSlotDesc {
private:
+ coreString name;
const BGUID interfaceGUID;
int flags;
- coreString name;
public:
_PinSlotDesc(coreString _name, const BGUID& _interfaceGUID, int _flags);
@@ -151,28 +146,19 @@
PinType* get_pin(BObject* that) const;
SlotType* get_slot(BObject* that) const;
-
- /*
- template<typename I>
- Pin<I>* get_pin(BObject* that) const {
- ASSERT( I::static_GUID() == interfaceGUID ); //don't ask for some other interface
- PinType* pin = get_pin(that);
- return static_cast<Pin<I>*>(pin);
- }
-
- template<typename I>
- Slot<I>* get_slot(BObject* that) const {
- ASSERT( I::static_GUID() == interfaceGUID ); //don't ask for some other interface
- SlotType* slot = get_slot(that);
- return static_cast<Slot<I>*>(slot);
- }
- */
};
-// A pin/slot descriptor parametrized by 'maker' and 'accesor' functors.
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// PinSlotDescImpl is a concrete implementation of a PinSlotDesc.
+// It knows how to instantiate the pin/slot it describes (using pinSlotFactory),
+// and how to retrieve this pin/slot from a given object (using pinSlotGet).
+//
+// A pin/slot descriptor is parametrized by 'maker' and 'accesor' functors.
// PinSlotDescImpl uses those functors to implement it's 'makePinSlot' and
// 'getPinSlot' methods.
// (see Makers and Accessors in pinslot_detail.h for more details)
+
template<typename GD, typename FD>
struct PinSlotDescImpl : PinSlotDesc {
GD pinSlotGet;
@@ -204,6 +190,7 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Pins implementation
+//
// DelegatingPin is a Pin parametrized by 'get' and 'release' functors.
// DelegatingPin uses those functors to implement it's 'getInterface' and
// 'releaseInterface' methods.
@@ -242,6 +229,13 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Slots implementation
+//
+// This is a concrete Slot implementation.
+// connect() and disconnect() methods are pretty self explanatory.
+//
+// The slot caches the interface it aquired, so that any consecutive calls to
+// getInterface() return the cached interface (and this fact is relied on in
+// the code).
template<typename I, typename T, int flags>
struct SlotImpl : Slot<I> {
@@ -282,6 +276,7 @@
return pin != NULL;
}
+ //returns the slot description
virtual const _PinSlotDesc& get_desc() const {
return static_desc();
}
@@ -295,10 +290,10 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-// 'annotation_map' is not too pretty. Maybe it should be cleaned up a bit - later.
-// It has one very concrete purpose - to hold pins' ans slots' descriptions.
-// Not for broad use.
+// annotation_map has one very concrete purpose - to hold pins' ans slots'
+// descriptions. Not for broad use.
+//create a wxWidgets map GUID -> PinSlotDesc*
EXPORT_GUID_MAP(PinSlotDesc*, guid_pinslotdesc_map_t, class CORE_API);
namespace pinslot_detail {
@@ -331,156 +326,6 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
-struct CORE_API BObjectDesc {
-private:
- const BGUID _objectGUID;
- int _flags;
- coreString _name;
- const PinSlotDescs& _pinDescs;
- const PinSlotDescs& _slotDescs;
-
-public:
- BObjectDesc(coreString name, const BGUID& objectGUID, int flags,
- const PinSlotDescs& pinDescs, const PinSlotDescs& slotDescs);
-
- int get_flags() const;
- const coreString& get_name() const;
- const BGUID& get_GUID() const;
- const PinSlotDescs& get_pins() const;
- const PinSlotDescs& get_slots() const;
-};
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-// For debug:
-
-#define ASSERT_VALID(obj) \
- ASSERT( InitializedObjects::get()->isValid(obj) )
-
-class BObject;
-
-class CORE_API InitializedObjects {
- static InitializedObjects* _instance;
- InitializedObjects() {}
-
-#ifdef _MSC_VER
-#pragma warning(disable : 4251)
-#endif
- std::set<BObject*> _initializedObjects;
-#ifdef _MSC_VER
-#pragma warning(default : 4251)
-#endif
-
-public:
- static InitializedObjects* get();
- static void release();
-
- void registerObject(BObject* obj);
- void unregisterObject(BObject* obj);
- bool isValid(BObject* obj);
-
- void report();
-};
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-// BObject is a reference counted object that is capable of holding pins and slots.
-
-class ObjectChain;
-
-class CORE_API BObject : public RCObject, public GUIDObject {
-
-private:
-
- //do not call manually!
- void init_pins_slots();
-
- //do not call manually!
- void delete_pins_slots();
-
-public:
-
- BObject();
-
- // Those methods below are here, and not in the constructor/destructor, because
- // they use virtual functions. So they need to be called on a fully constructed
- // object.
-
- //when overriding allways run super
- virtual void initialize();
- //when overriding allways run super
- virtual void destroy();
-
- //other lifecycle methods:
- //The implementations provided here are a good base for an object that can be
- //realized only in one ObjectChain at once.
-
- virtual bool isRealizedAnywhere();
-
- virtual bool isRealized(ObjectChain* ochain);
-
- void dumpRealizing(ObjectChain* ochain);
- void dumpRealized(ObjectChain* ochain, bool result);
- void dumpUnrealizing(ObjectChain* ochain);
- void dumpUnrealized(ObjectChain* ochain);
-
- //invoked to initialize the object in the ObjectChain
- //realize can query the ObjectChain (the object is already a member of it)
- virtual bool realize(ObjectChain* ochain);
- virtual bool doRealize(ObjectChain* ochain);
-
- //invoked to uninitialize the object in the ObjectChain
- //unrealize can query the ObjectChain (the object is still a member of it)
- virtual void unrealize(ObjectChain* ochain);
- virtual void doUnrealize(ObjectChain* ochain);
-
- virtual ObjectChain* getSingleObjectChain();
-
- virtual void dumpObjectChains(streamout& os);
-
- //a name used for debugging
- virtual coreString dumpName();
-
-protected:
- bool _realized;
- ObjectChain* _ochain;
-
-public:
-
- virtual const BObjectDesc& get_desc() const = 0;
-
- /*virtual*/ const PinSlotDescs& get_pins() const;
- /*virtual*/ const PinSlotDescs& get_slots() const;
-
- static const PinSlotDescs& static_pins();
- static const PinSlotDescs& static_slots();
-
- /*template<typename I>
- Pin<I>* get_pin() {
- return static_cast<Pin<I>*>( get_pin(I::static_GUID()) );
- }
-
- template<typename I>
- Slot<I>* get_slot() {
- return static_cast<Slot<I>*>( get_slot(I::static_GUID()) );
- }*/
-
- PinType* get_pin(const BGUID& interfaceGUID);
- SlotType* get_slot(const BGUID& interfaceGUID);
-
-private:
- PinSlotType* get_pinSlot(const BGUID& interfaceGUID, const PinSlotDescs& descs);
-};
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-// Include all the hacky stuff
-
} // namespace Core
-#include "pinslot_detail.h"
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
#endif /* _PINSLOT_H */
Modified: scummex/branches/gsoc2007-gameresbrowser/src/core/pinslot_detail.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/core/pinslot_detail.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/core/pinslot_detail.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -63,13 +63,13 @@
static const PinSlotDescs& static_slots();
-#define PIN_DESCS_EX(clazz) \
+#define PIN_DESCS(clazz) \
const PinSlotDescs& clazz::static_pins() { \
ASSERT_STATICS_ALLOWED(); \
static PinSlotDescs descs( \
PinSlotDescs(true).insert_copy(clazz::super_class::static_pins())
-#define SLOT_DESCS_EX(clazz) \
+#define SLOT_DESCS(clazz) \
const PinSlotDescs& clazz::static_slots() { \
ASSERT_STATICS_ALLOWED(); \
static PinSlotDescs descs( \
@@ -77,13 +77,13 @@
//inline definitions in the class
/*
-#define PIN_DESCS \
+#define PIN_DESCS_IMPL \
static const PinSlotDescs& static_pins() { \
ASSERT_STATICS_ALLOWED(); \
static PinSlotDescs descs( \
PinSlotDescs(true).insert_copy(super_class::static_pins())
-#define SLOT_DESCS \
+#define SLOT_DESCS_IMPL \
static const PinSlotDescs& static_slots() { \
ASSERT_STATICS_ALLOWED(); \
static PinSlotDescs descs( \
Modified: scummex/branches/gsoc2007-gameresbrowser/src/core/plugin.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/core/plugin.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/core/plugin.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -10,7 +10,7 @@
#define ZZ_PLUGIN_H
#include "guid.h"
-#include "pinslot.h"
+#include "BObject.h"
#include <map>
@@ -18,11 +18,43 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+// Plugins
+//
+// Plugin is a collection of ObjectPlugins.
+// ObjectPlugin knows about one BObject derived class, and can create
+// instances of this class.
+//
+// How to write a plugin:
+//
+// PLUGIN_DESC(MyPlugin, "MyPlugins", 1)
+// PLUGGED_OBJECT(MyObject)
+// PLUGGED_OBJECT(MyOtherObject)
+// PLUGIN_END
+//
+// These macros simply create a Plugin subclass, and fill its object plugins
+// collection with ObjectPluginImpl<MyObject>() objects (see below).
+//
+// How to register it into the ObjectRegistry:
+//
+// REGISTER_PLUGIN(MyPlugin)
+//
+// Which translates to:
+// ObjectRegistry::get()->registerPlugin( &getMyPlugin, false );
+// FileTypeRegistry::get()->registerPlugins();
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+class Plugin;
class ObjectPlugin;
+//define wxWidgets map GUID -> ObjectPlugin*
EXPORT_GUID_MAP(ObjectPlugin*, guid_oplug_map_t, class CORE_API);
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// Plugin
+
class CORE_API Plugin : public GUIDObject {
public:
//CAUTION: the ObjectPlugins map is keyed with the plugins GUID, not
@@ -35,6 +67,13 @@
virtual ~Plugin() {}
};
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// ObjectPlugin
+//
+// An ObjectPlugin knows how to instantiate one class of objects: newInstance()
+// It can also be asked for descriptions of those objects: get_desc()
+
class CORE_API ObjectPlugin : public GUIDObject {
public:
@@ -44,18 +83,23 @@
virtual ~ObjectPlugin() {}
- /*virtual*/ const BGUID& getObjectGUID() const {
+ const BGUID& getObjectGUID() const {
return this->get_desc().get_GUID();
}
- /*virtual*/ const PinSlotDescs& get_pins() const {
+ const PinSlotDescs& get_pins() const {
return this->get_desc().get_pins();
}
- /*virtual*/ const PinSlotDescs& get_slots() const {
+ const PinSlotDescs& get_slots() const {
return this->get_desc().get_slots();
}
};
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+// ObjectPluginImpl<T> is an implementation of an ObjectPlugin that
+// creates objects of class T.
+
template<typename T>
class ObjectPluginImpl : public ObjectPlugin {
public:
Modified: scummex/branches/gsoc2007-gameresbrowser/src/core/plugin_detail.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/core/plugin_detail.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/core/plugin_detail.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -70,10 +70,16 @@
}
#define PLUGIN_DESC(PluginClazz, facility, version) \
+ PLUGIN_DESC_(PluginClazz, get##PluginClazz, facility, version, PLUGIN_EXPORT)
+#define PLUGIN_DESC_RAW(PluginClazz, facility, version) \
PLUGIN_DESC_(PluginClazz, getPlugin, facility, version, PLUGIN_EXPORT)
#define PLUGIN_DESC_EX(PluginClazz, facility, version, API) \
PLUGIN_DESC_(PluginClazz, get##PluginClazz, facility, version, API)
+#define REGISTER_PLUGIN(PluginClazz) \
+ ObjectRegistry::get()->registerPlugin( &get##PluginClazz, false ); \
+ FileTypeRegistry::get()->registerPlugins();
+
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
Modified: scummex/branches/gsoc2007-gameresbrowser/src/core/safe_static.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/core/safe_static.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/core/safe_static.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -6,6 +6,23 @@
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+// Safe statics are to assure that no accesses to static objects are done
+// before they are constructed and after they are destructed.
+// Such an access can cause hard to find bugs.
+// (None of this would be necessary is C++ specified the order of creation/
+// destruction of static objects...)
+//
+// A safe static is basically a function that has a static variable inside,
+// and returns a reference to it.
+// This variable gets initialized at first invocation of the function, so
+// there's no way you can acces it before it constructs.
+//
+// To make destruction safe, you must call set_statics_not_allowed() at the
+// end of the program. Access to a safe static after that point causes failed
+// assertions.
+//
+// The EXPORT macros below export those statics from a DLL.
+// The LOCAL versions dont.
namespace Core {
//extern /*CORE_API*/ bool statics_allowed;
Modified: scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/AuxInterfaces.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/AuxInterfaces.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/AuxInterfaces.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -4,7 +4,7 @@
#ifndef _AUX_INTERFACES_H_
#define _AUX_INTERFACES_H_
-#include "pinslot.h"
+#include "BObject.h"
namespace Browser {
Deleted: scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/BMPParser.cpp
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/BMPParser.cpp 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/BMPParser.cpp 2007-07-13 04:03:42 UTC (rev 28050)
@@ -1,272 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// BMPParser.cpp
-
-#include "basic_stdafx.h"
-
-#include "BMPParser.h"
-
-#include <iostream>
-
-#include <wx/image.h>
-#include "streams/wx2scstream.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include "debugmem.h"
-
-namespace Browser {
-
-using namespace Core;
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
-SLOT_DESCS_EX(TextParser)
- SLOT_DESC(_fileSlot, SLOT_DEFAULT)
-END_DESCS
-PIN_DESCS_EX(TextParser)
- PIN_DESC_r(_textPin, PIN_DEFAULT | PIN_MULTICAST, getTextImpl, ITextImpl)
-END_DESCS
-
-
-ITextImpl* TextParser::getTextImpl() {
- //infoout << wxT("TextParser::getTextImpl(): ") << std::endl;
-
- IFile* ifile = _fileSlot->getInterface();
- if (!ifile) {
- errout << wxT("TextParser::getTextImpl(): could not get IFile interface") << std::endl;
- return new ITextImpl(wxT("ERROR"), wxT("could not get IFile interface"));
- }
-
- Common::SeekableReadStream* stream = ifile->getStream();
-
- if (!stream) {
- _fileSlot->releaseInterface();
- errout << wxT("TextParser::getTextImpl(): null stream") << std::endl;
- return new ITextImpl(wxT("ERROR"), wxT("null stream"));
- }
-
- uint32 size = stream->size();
- char* text = new char[size+1];
- text[size] = '\0';
- stream->seek(0, SEEK_SET);
- stream->read(text, size);
- bool res = !stream->ioFailed();
-
- _fileSlot->releaseInterface();
-
- //FIXME: This will read the text in what encoding???
- wxString str(toString(text));
- delete [] text;
-
- if (!res) {
- errout << wxT("TextParser::getTextImpl(): stream ioFailed") << std::endl;
- return new ITextImpl(wxT("ERROR"), wxT("stream ioFailed"));
- }
-
- return new ITextImpl(/*ifile->getName()*/ wxT("Text"), str);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
-SLOT_DESCS_EX(BinaryParser)
- SLOT_DESC(_fileSlot, SLOT_DEFAULT)
-END_DESCS
-PIN_DESCS_EX(BinaryParser)
- PIN_DESC_r(_textPin, PIN_DEFAULT | PIN_MULTICAST, getTextImpl, ITextImpl)
-END_DESCS
-
-//taken from ScummEx
-wxString _data_to_hex(byte* data, uint32 size, uint32 start_offset = 0, bool truncated = false) {
-
- const int bytes_per_line = 8;
- const int max_lines = 50;
-
- uint32 orig_size = size;
- if (size > bytes_per_line * max_lines) {
- truncated = true;
- size = bytes_per_line * max_lines;
- }
- int len = (int)size;
- int nlines = len / bytes_per_line;
-
- wxChar* text = new wxChar[
- (16 + (3*bytes_per_line) + (bytes_per_line/4) + bytes_per_line) * nlines + 256];
-
- int i;
- uint32 offset = start_offset;
- wxChar buf[256];
- buf[0] = wxT('\0');
- text[0] = wxT('\0');
- while (len >= bytes_per_line) {
- stprintf(buf, 255, wxT("%06X: "), offset);
- tstrcat(text, buf);
- for (i = 0; i < bytes_per_line; i++) {
- stprintf(buf, 255, wxT("%02X "), data[i]);
- tstrcat(text, buf);
- if (i % 4 == 3) {
- stprintf(buf, 255, wxT(" "));
- tstrcat(text, buf);
- }
- }
- stprintf(buf, 255, wxT(" |"));
- tstrcat(text, buf);
- for (i = 0; i < bytes_per_line; i++) {
- wxChar c = data[i];
- if (c < 32 || c >= 127)
- c = wxT('.');
- stprintf(buf, 255, wxT("%c"), c);
- tstrcat(text, buf);
- }
- stprintf(buf, 255, wxT("|\n"));
- tstrcat(text, buf);
- data += bytes_per_line;
- len -= bytes_per_line;
- offset += bytes_per_line;
- }
-
- if (len > 0) {
- stprintf(buf, 255, wxT("%06X: "), offset);
- tstrcat(text, buf);
- for (i = 0; i < len; i++) {
- stprintf(buf, 255, wxT("%02X "), data[i]);
- tstrcat(text, buf);
- if (i % 4 == 3) {
- stprintf(buf, 255, wxT(" "));
- tstrcat(text, buf);
- }
- }
-
- for (; i < bytes_per_line; i++) {
- stprintf(buf, 255, wxT(" "));
- tstrcat(text, buf);
- if (i % 4 == 3) {
- stprintf(buf, 255, wxT(" "));
- tstrcat(text, buf);
- }
- }
- stprintf(buf, 255, wxT(" |"));
- tstrcat(text, buf);
- for (i = 0; i < len; i++) {
- wxChar c = data[i];
- if (c < 32 || c >= 127)
- c = wxT('.');
- stprintf(buf, 255, wxT("%c"), c);
- tstrcat(text, buf);
- }
- for (; i < bytes_per_line; i++) {
- stprintf(buf, 255, wxT(" "));
- tstrcat(text, buf);
- }
- stprintf(buf, 255, wxT("|\n"));
- tstrcat(text, buf);
- }
-
- if (truncated) {
- stprintf(buf, 255, wxT("\nThe file has been truncated.\n"));
- tstrcat(text, buf);
- }
-
- wxString str(text);
- delete [] text;
-
- return str;
-}
-
-ITextImpl* BinaryParser::getTextImpl() {
- //infoout << wxT("BinaryParser::getTextImpl(): ") << std::endl;
-
- IFile* ifile = _fileSlot->getInterface();
- if (!ifile) {
- errout << wxT("BinaryParser::getTextImpl(): could not get IFile interface") << std::endl;
- return new ITextImpl(wxT("ERROR"), wxT("could not get IFile interface"));
- }
-
- Common::SeekableReadStream* stream = ifile->getStream();
-
- if (!stream) {
- _fileSlot->releaseInterface();
- errout << wxT("BinaryParser::getTextImpl(): null stream") << std::endl;
- return new ITextImpl(wxT("ERROR"), wxT("null stream"));
- }
-
- uint32 size = stream->size();
- bool truncated = size > 512;
- if (truncated) size = 512;
-
- byte* data = new byte[size];
- stream->seek(0, SEEK_SET);
- stream->read(data, size);
- bool res = !stream->ioFailed();
-
- _fileSlot->releaseInterface();
-
- if (!res) {
- delete [] data;
- errout << wxT("BinaryParser::getTextImpl(): stream ioFailed") << std::endl;
- return new ITextImpl(wxT("ERROR"), wxT("stream ioFailed"));
- }
-
- wxString str = _data_to_hex(data, size, 0, truncated);
- delete [] data;
-
- return new ITextImpl(/*ifile->getName()*/ wxT("Binary"), str, true);
-}
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
-SLOT_DESCS_EX(BMPParser)
- SLOT_DESC(_fileSlot, SLOT_DEFAULT)
-END_DESCS
-PIN_DESCS_EX(BMPParser)
- PIN_DESC(_imagePin, PIN_DEFAULT | PIN_MULTICAST, getImageImpl, releaseImageImpl)
-END_DESCS
-
-
-IImageImpl* BMPParser::getImageImpl() {
- //infoout << wxT("BMPParser::getImageImpl(): ") << std::endl;
-
- IFile* ifile = _fileSlot->getInterface();
- if (!ifile) {
- errout << wxT("BMPParser::getImageImpl(): could not get IFile interface") << std::endl;
- return NULL;
- }
-
- Common::SeekableReadStream* stream = ifile->getStream();
-
- if (!stream) {
- _fileSlot->releaseInterface();
- errout << wxT("BMPParser::getImageImpl(): null stream") << std::endl;
- return NULL;
- }
-
- stream->seek(0, SEEK_SET);
- wxInputStream* input = new wxScummInputStream(stream);
-
- wxImage* image = new wxImage();
- bool res = image->LoadFile(*input, wxBITMAP_TYPE_BMP);
-
- delete input;
- _fileSlot->releaseInterface();
-
- if (!res) {
- errout << wxT("BMPParser::getImageImpl(): image LoadFile failed") << std::endl;
- delete image;
- return NULL;
- }
-
- return new IImageImpl(image, true);
-}
-
-void BMPParser::releaseImageImpl(IImageImpl* iface) {
- //infoout << wxT("BMPParser::releaseImageImpl(): ") << std::endl;
- delete iface;
-}
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
-} // namespace Browser
Deleted: scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/BMPParser.h
===================================================================
--- scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/BMPParser.h 2007-07-12 21:21:33 UTC (rev 28049)
+++ scummex/branches/gsoc2007-gameresbrowser/src/plugins/basic/BMPParser.h 2007-07-13 04:03:42 UTC (rev 28050)
@@ -1,81 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// BMPParser.h
-
-#ifndef _BMPPARSER_H_
-#define _BMPPARSER_H_
-
-#include "pinslot.h"
-
-#include "AuxInterfaces.h"
-#include "GUIInterfaces.h"
-#include "CoreInterfaces.h"
-
-namespace Browser {
-
-using namespace Core;
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
-class BASIC_PLUGIN_API TextParser : public BObject {
- DECLARE_BOBJECT_CLASS(TextParser, BObject)
-
-protected:
- Slot<IFile>* _fileSlot;
- Pin<IText>* _textPin;
-
-public:
- ASSIGN_DESC(0,wxT("CoreObjects"), 1)
-
- PINS_DECL
- SLOTS_DECL
-
- ITextImpl* getTextImpl();
-};
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
-class BASIC_PLUGIN_API BinaryParser : public BObject {
- DECLARE_BOBJECT_CLASS(BinaryParser, BObject)
-
-protected:
- Slot<IFile>* _fileSlot;
- Pin<IText>* _textPin;
-
-public:
- ASSIGN_DESC(0,wxT("CoreObjects"), 1)
-
- PINS_DECL
- SLOTS_DECL
-
- ITextImpl* getTextImpl();
-};
-
-/////////////////////////////////////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////////////////
-
-class BASIC_PLUGIN_API BMPParser : public BObject {
- DECLARE_BOBJECT_CLASS(BMPParser, BObject)
-
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list