maplib.h

Go to the documentation of this file.
00001 /*
00002  Copyright (C) 2001-2006, William Joseph.
00003  All Rights Reserved.
00004 
00005  This file is part of GtkRadiant.
00006 
00007  GtkRadiant is free software; you can redistribute it and/or modify
00008  it under the terms of the GNU General Public License as published by
00009  the Free Software Foundation; either version 2 of the License, or
00010  (at your option) any later version.
00011 
00012  GtkRadiant is distributed in the hope that it will be useful,
00013  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  GNU General Public License for more details.
00016 
00017  You should have received a copy of the GNU General Public License
00018  along with GtkRadiant; if not, write to the Free Software
00019  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020  */
00021 
00022 #if !defined (INCLUDED_MAPLIB_H)
00023 #define INCLUDED_MAPLIB_H
00024 
00025 #include "nameable.h"
00026 #include "mapfile.h"
00027 
00028 #include "traverselib.h"
00029 #include "transformlib.h"
00030 #include "scenelib.h"
00031 #include "string/string.h"
00032 #include "instancelib.h"
00033 #include "selectionlib.h"
00034 #include "generic/callback.h"
00035 
00036 class NameableString: public Nameable
00037 {
00038         std::string m_name;
00039     public:
00040         NameableString (const std::string& name) :
00041             m_name(name)
00042         {
00043         }
00044 
00045         std::string name () const
00046         {
00047             return m_name;
00048         }
00049         void attach (const NameCallback& callback)
00050         {
00051         }
00052         void detach (const NameCallback& callback)
00053         {
00054         }
00055 };
00056 
00057 const std::size_t MAPFILE_MAX_CHANGES = std::numeric_limits<std::size_t>::max();
00058 
00059 class UndoFileChangeTracker: public UndoTracker, public MapFile
00060 {
00061         std::size_t m_size;
00062         std::size_t m_saved;
00063         typedef void (UndoFileChangeTracker::*Pending) ();
00064         Pending m_pending;
00065         Callback m_changed;
00066 
00067     public:
00068         UndoFileChangeTracker () :
00069             m_size(0), m_saved(MAPFILE_MAX_CHANGES), m_pending(0)
00070         {
00071         }
00072         void print ()
00073         {
00074             globalOutputStream() << "saved: " << Unsigned(m_saved) << " size: " << Unsigned(m_size) << "\n";
00075         }
00076 
00077         void push ()
00078         {
00079             ++m_size;
00080             m_changed();
00081             //print();
00082         }
00083         void pop ()
00084         {
00085             --m_size;
00086             m_changed();
00087             //print();
00088         }
00089         void pushOperation ()
00090         {
00091             if (m_size < m_saved) {
00092                 // redo queue has been flushed.. it is now impossible to get back to the saved state via undo/redo
00093                 m_saved = MAPFILE_MAX_CHANGES;
00094             }
00095             push();
00096         }
00097         void clear ()
00098         {
00099             m_size = 0;
00100             m_changed();
00101             //print();
00102         }
00103         void clearRedo (void)
00104         {
00105             // do nothing special
00106         }
00107         void begin ()
00108         {
00109             m_pending = Pending(&UndoFileChangeTracker::pushOperation);
00110         }
00111         void undo ()
00112         {
00113             m_pending = Pending(&UndoFileChangeTracker::pop);
00114         }
00115         void redo ()
00116         {
00117             m_pending = Pending(&UndoFileChangeTracker::push);
00118         }
00119 
00120         void changed ()
00121         {
00122             if (m_pending != 0) {
00123                 ((*this).*m_pending)();
00124                 m_pending = 0;
00125             }
00126         }
00127 
00128         void save ()
00129         {
00130             m_saved = m_size;
00131             m_changed();
00132         }
00133         bool saved () const
00134         {
00135             return m_saved == m_size;
00136         }
00137 
00138         void setChangedCallback (const Callback& changed)
00139         {
00140             m_changed = changed;
00141             m_changed();
00142         }
00143 
00144         std::size_t changes () const
00145         {
00146             return m_size;
00147         }
00148 };
00149 
00150 class MapRoot: public scene::Node, public scene::Instantiable, public scene::Traversable::Observer
00151 {
00152         class TypeCasts
00153         {
00154                 NodeTypeCastTable m_casts;
00155             public:
00156                 TypeCasts ()
00157                 {
00158                     NodeContainedCast<MapRoot, scene::Traversable>::install(m_casts);
00159                     NodeContainedCast<MapRoot, TransformNode>::install(m_casts);
00160                     NodeContainedCast<MapRoot, MapFile>::install(m_casts);
00161                 }
00162                 NodeTypeCastTable& get ()
00163                 {
00164                     return m_casts;
00165                 }
00166         };
00167 
00168         IdentityTransform m_transform;
00169         TraversableNodeSet m_traverse;
00170         InstanceSet m_instances;
00171         typedef SelectableInstance Instance;
00172         NameableString m_name;
00173         UndoFileChangeTracker m_changeTracker;
00174     public:
00175         typedef LazyStatic<TypeCasts> StaticTypeCasts;
00176 
00177         scene::Traversable& get (NullType<scene::Traversable> )
00178         {
00179             return m_traverse;
00180         }
00181         TransformNode& get (NullType<TransformNode> )
00182         {
00183             return m_transform;
00184         }
00185         Nameable& get (NullType<Nameable> )
00186         {
00187             return m_name;
00188         }
00189         MapFile& get (NullType<MapFile> )
00190         {
00191             return m_changeTracker;
00192         }
00193 
00194         MapRoot (const std::string& name) :
00195             scene::Node(this, StaticTypeCasts::instance().get()), m_name(name)
00196         {
00197             m_isRoot = true;
00198 
00199             m_traverse.attach(this);
00200 
00201             GlobalUndoSystem().trackerAttach(m_changeTracker);
00202         }
00203         ~MapRoot ()
00204         {
00205             GlobalUndoSystem().trackerDetach(m_changeTracker);
00206             m_traverse.detach(this);
00207         }
00208         scene::Node& node ()
00209         {
00210             return *this;
00211         }
00212 
00213         InstanceCounter m_instanceCounter;
00214         void instanceAttach (const scene::Path& path)
00215         {
00216             if (++m_instanceCounter.m_count == 1) {
00217                 m_traverse.instanceAttach(path_find_mapfile(path.begin(), path.end()));
00218             }
00219         }
00220         void instanceDetach (const scene::Path& path)
00221         {
00222             if (--m_instanceCounter.m_count == 0) {
00223                 m_traverse.instanceDetach(path_find_mapfile(path.begin(), path.end()));
00224             }
00225         }
00226 
00227         void insert (scene::Node& child)
00228         {
00229             m_instances.insert(child);
00230         }
00231         void erase (scene::Node& child)
00232         {
00233             m_instances.erase(child);
00234         }
00235 
00236         scene::Node& clone () const
00237         {
00238             return (new MapRoot(*this))->node();
00239         }
00240 
00241         scene::Instance* create (const scene::Path& path, scene::Instance* parent)
00242         {
00243             return new Instance(path, parent);
00244         }
00245         void forEachInstance (const scene::Instantiable::Visitor& visitor)
00246         {
00247             m_instances.forEachInstance(visitor);
00248         }
00249         void insert (scene::Instantiable::Observer* observer, const scene::Path& path, scene::Instance* instance)
00250         {
00251             m_instances.insert(observer, path, instance);
00252             instanceAttach(path);
00253         }
00254         scene::Instance* erase (scene::Instantiable::Observer* observer, const scene::Path& path)
00255         {
00256             instanceDetach(path);
00257             return m_instances.erase(observer, path);
00258         }
00259 };
00260 
00261 inline void MapRoot_Construct ()
00262 {
00263 }
00264 
00265 inline void MapRoot_Destroy ()
00266 {
00267 }
00268 
00269 inline NodeSmartReference NewMapRoot (const std::string& name)
00270 {
00271     return NodeSmartReference((new MapRoot(name))->node());
00272 }
00273 
00274 #endif

Generated by  doxygen 1.6.2