entitylib.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_ENTITYLIB_H)
00023 #define INCLUDED_ENTITYLIB_H
00024 
00025 #include "ireference.h"
00026 #include "debugging/debugging.h"
00027 
00028 #include "ientity.h"
00029 #include "irender.h"
00030 #include "igl.h"
00031 #include "selectable.h"
00032 
00033 #include "generic/callback.h"
00034 #include "math/aabb.h"
00035 #include "undolib.h"
00036 #include "string/pooledstring.h"
00037 #include "generic/referencecounted.h"
00038 #include "scenelib.h"
00039 #include "container/container.h"
00040 #include "eclasslib.h"
00041 
00042 #include <list>
00043 #include <set>
00044 
00045 inline void arrow_draw (const Vector3& origin, const Vector3& direction)
00046 {
00047     Vector3 up(0, 0, 1);
00048     Vector3 left(-direction[1], direction[0], 0);
00049 
00050     Vector3 endpoint(origin + direction * 32.0);
00051 
00052     Vector3 tip1(endpoint + direction * (-8.0) + up * (-4.0));
00053     Vector3 tip2(tip1 + up * 8.0);
00054     Vector3 tip3(endpoint + direction * (-8.0) + left * (-4.0));
00055     Vector3 tip4(tip3 + left * 8.0);
00056 
00057     glBegin(GL_LINES);
00058 
00059     glVertex3fv(origin);
00060     glVertex3fv(endpoint);
00061 
00062     glVertex3fv(endpoint);
00063     glVertex3fv(tip1);
00064 
00065     glVertex3fv(endpoint);
00066     glVertex3fv(tip2);
00067 
00068     glVertex3fv(endpoint);
00069     glVertex3fv(tip3);
00070 
00071     glVertex3fv(endpoint);
00072     glVertex3fv(tip4);
00073 
00074     glVertex3fv(tip1);
00075     glVertex3fv(tip3);
00076 
00077     glVertex3fv(tip3);
00078     glVertex3fv(tip2);
00079 
00080     glVertex3fv(tip2);
00081     glVertex3fv(tip4);
00082 
00083     glVertex3fv(tip4);
00084     glVertex3fv(tip1);
00085 
00086     glEnd();
00087 }
00088 
00089 class SelectionIntersection;
00090 
00091 inline void aabb_testselect (const AABB& aabb, SelectionTest& test, SelectionIntersection& best)
00092 {
00093     const IndexPointer::index_type indices[24] = { 2, 1, 5, 6, 1, 0, 4, 5, 0, 1, 2, 3, 3, 7, 4, 0, 3, 2, 6, 7, 7, 6, 5,
00094             4, };
00095 
00096     Vector3 points[8];
00097     aabb_corners(aabb, points);
00098     test.TestQuads(VertexPointer(reinterpret_cast<VertexPointer::pointer> (points), sizeof(Vector3)), IndexPointer(
00099             indices, 24), best);
00100 }
00101 
00102 inline void aabb_draw_wire (const Vector3 points[8])
00103 {
00104     const unsigned char indices[] = { 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 };
00105     glVertexPointer(3, GL_FLOAT, 0, points);
00106     glDrawElements(GL_LINES, sizeof(indices) / sizeof(indices[0]), GL_UNSIGNED_BYTE, indices);
00107 }
00108 
00109 inline void aabb_draw_flatshade (const Vector3 points[8])
00110 {
00111     glBegin(GL_QUADS);
00112 
00113     glNormal3fv(aabb_normals[0]);
00114     glVertex3fv(points[2]);
00115     glVertex3fv(points[1]);
00116     glVertex3fv(points[5]);
00117     glVertex3fv(points[6]);
00118 
00119     glNormal3fv(aabb_normals[1]);
00120     glVertex3fv(points[1]);
00121     glVertex3fv(points[0]);
00122     glVertex3fv(points[4]);
00123     glVertex3fv(points[5]);
00124 
00125     glNormal3fv(aabb_normals[2]);
00126     glVertex3fv(points[0]);
00127     glVertex3fv(points[1]);
00128     glVertex3fv(points[2]);
00129     glVertex3fv(points[3]);
00130 
00131     glNormal3fv(aabb_normals[3]);
00132     glVertex3fv(points[0]);
00133     glVertex3fv(points[3]);
00134     glVertex3fv(points[7]);
00135     glVertex3fv(points[4]);
00136 
00137     glNormal3fv(aabb_normals[4]);
00138     glVertex3fv(points[3]);
00139     glVertex3fv(points[2]);
00140     glVertex3fv(points[6]);
00141     glVertex3fv(points[7]);
00142 
00143     glNormal3fv(aabb_normals[5]);
00144     glVertex3fv(points[7]);
00145     glVertex3fv(points[6]);
00146     glVertex3fv(points[5]);
00147     glVertex3fv(points[4]);
00148 
00149     glEnd();
00150 }
00151 
00152 inline void aabb_draw_wire (const AABB& aabb)
00153 {
00154     Vector3 points[8];
00155     aabb_corners(aabb, points);
00156     aabb_draw_wire(points);
00157 }
00158 
00159 inline void aabb_draw_flatshade (const AABB& aabb)
00160 {
00161     Vector3 points[8];
00162     aabb_corners(aabb, points);
00163     aabb_draw_flatshade(points);
00164 }
00165 
00166 inline void aabb_draw_textured (const AABB& aabb)
00167 {
00168     Vector3 points[8];
00169     aabb_corners(aabb, points);
00170 
00171     glBegin(GL_QUADS);
00172 
00173     glNormal3fv(aabb_normals[0]);
00174     glTexCoord2fv(aabb_texcoord_topleft);
00175     glVertex3fv(points[2]);
00176     glTexCoord2fv(aabb_texcoord_topright);
00177     glVertex3fv(points[1]);
00178     glTexCoord2fv(aabb_texcoord_botright);
00179     glVertex3fv(points[5]);
00180     glTexCoord2fv(aabb_texcoord_botleft);
00181     glVertex3fv(points[6]);
00182 
00183     glNormal3fv(aabb_normals[1]);
00184     glTexCoord2fv(aabb_texcoord_topleft);
00185     glVertex3fv(points[1]);
00186     glTexCoord2fv(aabb_texcoord_topright);
00187     glVertex3fv(points[0]);
00188     glTexCoord2fv(aabb_texcoord_botright);
00189     glVertex3fv(points[4]);
00190     glTexCoord2fv(aabb_texcoord_botleft);
00191     glVertex3fv(points[5]);
00192 
00193     glNormal3fv(aabb_normals[2]);
00194     glTexCoord2fv(aabb_texcoord_topleft);
00195     glVertex3fv(points[0]);
00196     glTexCoord2fv(aabb_texcoord_topright);
00197     glVertex3fv(points[1]);
00198     glTexCoord2fv(aabb_texcoord_botright);
00199     glVertex3fv(points[2]);
00200     glTexCoord2fv(aabb_texcoord_botleft);
00201     glVertex3fv(points[3]);
00202 
00203     glNormal3fv(aabb_normals[3]);
00204     glTexCoord2fv(aabb_texcoord_topleft);
00205     glVertex3fv(points[0]);
00206     glTexCoord2fv(aabb_texcoord_topright);
00207     glVertex3fv(points[3]);
00208     glTexCoord2fv(aabb_texcoord_botright);
00209     glVertex3fv(points[7]);
00210     glTexCoord2fv(aabb_texcoord_botleft);
00211     glVertex3fv(points[4]);
00212 
00213     glNormal3fv(aabb_normals[4]);
00214     glTexCoord2fv(aabb_texcoord_topleft);
00215     glVertex3fv(points[3]);
00216     glTexCoord2fv(aabb_texcoord_topright);
00217     glVertex3fv(points[2]);
00218     glTexCoord2fv(aabb_texcoord_botright);
00219     glVertex3fv(points[6]);
00220     glTexCoord2fv(aabb_texcoord_botleft);
00221     glVertex3fv(points[7]);
00222 
00223     glNormal3fv(aabb_normals[5]);
00224     glTexCoord2fv(aabb_texcoord_topleft);
00225     glVertex3fv(points[7]);
00226     glTexCoord2fv(aabb_texcoord_topright);
00227     glVertex3fv(points[6]);
00228     glTexCoord2fv(aabb_texcoord_botright);
00229     glVertex3fv(points[5]);
00230     glTexCoord2fv(aabb_texcoord_botleft);
00231     glVertex3fv(points[4]);
00232 
00233     glEnd();
00234 }
00235 
00236 inline void aabb_draw_solid (const AABB& aabb, RenderStateFlags state)
00237 {
00238     if (state & RENDER_TEXTURE) {
00239         aabb_draw_textured(aabb);
00240     } else {
00241         aabb_draw_flatshade(aabb);
00242     }
00243 }
00244 
00245 inline void aabb_draw (const AABB& aabb, RenderStateFlags state)
00246 {
00247     if (state & RENDER_FILL) {
00248         aabb_draw_solid(aabb, state);
00249     } else {
00250         aabb_draw_wire(aabb);
00251     }
00252 }
00253 
00254 class RenderableSolidAABB: public OpenGLRenderable
00255 {
00256         const AABB& m_aabb;
00257     public:
00258         RenderableSolidAABB (const AABB& aabb) :
00259             m_aabb(aabb)
00260         {
00261         }
00262         void render (RenderStateFlags state) const
00263         {
00264             aabb_draw_solid(m_aabb, state);
00265         }
00266 };
00267 
00268 class RenderableWireframeAABB: public OpenGLRenderable
00269 {
00270         const AABB& m_aabb;
00271     public:
00272         RenderableWireframeAABB (const AABB& aabb) :
00273             m_aabb(aabb)
00274         {
00275         }
00276         void render (RenderStateFlags state) const
00277         {
00278             aabb_draw_wire(m_aabb);
00279         }
00280 };
00281 
00286 class KeyValue: public EntityKeyValue
00287 {
00288         typedef UnsortedSet<KeyObserver> KeyObservers;
00289 
00290         std::size_t m_refcount;
00291         KeyObservers m_observers;
00292         std::string m_string;
00293         const char* m_empty;
00294         ObservedUndoableObject<std::string> m_undo;
00295         static EntityCreator::KeyValueChangedFunc m_entityKeyValueChanged;
00296     public:
00297 
00298         KeyValue (const char* string, const char* empty) :
00299             m_refcount(0), m_string(string), m_empty(empty), m_undo(m_string, UndoImportCaller(*this))
00300         {
00301             notify();
00302         }
00303         ~KeyValue ()
00304         {
00305             ASSERT_MESSAGE(m_observers.empty(), "KeyValue::~KeyValue: observers still attached");
00306         }
00307 
00308         static void setKeyValueChangedFunc (EntityCreator::KeyValueChangedFunc func)
00309         {
00310             m_entityKeyValueChanged = func;
00311         }
00312 
00313         void IncRef ()
00314         {
00315             ++m_refcount;
00316         }
00317         void DecRef ()
00318         {
00319             if (--m_refcount == 0) {
00320                 delete this;
00321             }
00322         }
00323 
00324         void instanceAttach (MapFile* map)
00325         {
00326             m_undo.instanceAttach(map);
00327         }
00328         void instanceDetach (MapFile* map)
00329         {
00330             m_undo.instanceDetach(map);
00331         }
00332 
00333         void attach (const KeyObserver& observer)
00334         {
00335             (*m_observers.insert(observer))(c_str());
00336         }
00337         void detach (const KeyObserver& observer)
00338         {
00339             observer(m_empty);
00340             m_observers.erase(observer);
00341         }
00342         const char* c_str () const
00343         {
00344             if (m_string.empty())
00345                 return m_empty;
00346             return m_string.c_str();
00347         }
00348         void assign (const std::string& other)
00349         {
00350             if (m_string != other) {
00351                 m_undo.save();
00352                 m_string = other;
00353                 notify();
00354             }
00355         }
00356 
00357         void notify ()
00358         {
00359             m_entityKeyValueChanged();
00360             KeyObservers::reverse_iterator i = m_observers.rbegin();
00361             while (i != m_observers.rend()) {
00362                 (*i++)(c_str());
00363             }
00364         }
00365 
00366         void importState (const std::string& string)
00367         {
00368             m_string = string;
00369 
00370             notify();
00371         }
00372         typedef MemberCaller1<KeyValue, const std::string&, &KeyValue::importState> UndoImportCaller;
00373 };
00374 
00380 class EntityKeyValues: public Entity
00381 {
00382     public:
00383         typedef KeyValue Value;
00384 
00385         static StringPool& getPool ()
00386         {
00387             return Static<StringPool, KeyContext>::instance();
00388         }
00389     private:
00390         static EntityCreator::KeyValueChangedFunc m_entityKeyValueChanged;
00391         static Counter* m_counter;
00392 
00393         EntityClass* m_eclass;
00394 
00395         class KeyContext
00396         {
00397         };
00398         typedef Static<StringPool, KeyContext> KeyPool;
00399         typedef PooledString<KeyPool> Key;
00400         typedef SmartPointer<KeyValue> KeyValuePtr;
00401         typedef UnsortedMap<Key, KeyValuePtr> KeyValues;
00402         KeyValues m_keyValues;
00403 
00404         typedef UnsortedSet<Observer*> Observers;
00405         Observers m_observers;
00406 
00407         ObservedUndoableObject<KeyValues> m_undo;
00408         bool m_instanced;
00409 
00410         bool m_observerMutex;
00411 
00412         void notifyInsert (const char* key, Value& value)
00413         {
00414             m_observerMutex = true;
00415             for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) {
00416                 (*i)->insert(key, value);
00417             }
00418             m_observerMutex = false;
00419         }
00420         void notifyErase (const char* key, Value& value)
00421         {
00422             m_observerMutex = true;
00423             for (Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i) {
00424                 (*i)->erase(key, value);
00425             }
00426             m_observerMutex = false;
00427         }
00428         void forEachKeyValue_notifyInsert ()
00429         {
00430             for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00431                 notifyInsert((*i).first.c_str(), *(*i).second);
00432             }
00433         }
00434         void forEachKeyValue_notifyErase ()
00435         {
00436             for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00437                 notifyErase((*i).first.c_str(), *(*i).second);
00438             }
00439         }
00440 
00441         void insert (const char* key, const KeyValuePtr& keyValue)
00442         {
00443             KeyValues::iterator i = m_keyValues.insert(KeyValues::value_type(key, keyValue));
00444             notifyInsert(key, *(*i).second);
00445 
00446             if (m_instanced) {
00447                 (*i).second->instanceAttach(m_undo.map());
00448             }
00449         }
00450 
00451         void insert (const char* key, const char* value)
00452         {
00453             KeyValues::iterator i = m_keyValues.find(key);
00454             if (i != m_keyValues.end()) {
00455                 (*i).second->assign(value);
00456             } else {
00457                 m_undo.save();
00458                 insert(key, KeyValuePtr(new KeyValue(value, EntityClass_valueForKey(*m_eclass, key))));
00459             }
00460         }
00461 
00462         void erase (KeyValues::iterator i)
00463         {
00464             if (m_instanced) {
00465                 (*i).second->instanceDetach(m_undo.map());
00466             }
00467 
00468             Key key((*i).first);
00469             KeyValuePtr value((*i).second);
00470             m_keyValues.erase(i);
00471             notifyErase(key.c_str(), *value);
00472         }
00473 
00474         void erase (const char* key)
00475         {
00476             KeyValues::iterator i = m_keyValues.find(key);
00477             if (i != m_keyValues.end()) {
00478                 m_undo.save();
00479                 erase(i);
00480             }
00481         }
00482 
00488         const char* getKeyValueOrNull (const std::string& key) const
00489         {
00490             KeyValues::const_iterator i = m_keyValues.find(key.c_str());
00491             if (i != m_keyValues.end())
00492                 return (*i).second->c_str();
00493             else
00494                 return (const char*) 0;
00495         }
00496 
00497     public:
00498         bool m_isContainer;
00499 
00500         EntityKeyValues (EntityClass* eclass) :
00501             m_eclass(eclass), m_undo(m_keyValues, UndoImportCaller(*this)), m_instanced(false), m_observerMutex(false),
00502                     m_isContainer(!eclass->fixedsize)
00503         {
00504         }
00505         EntityKeyValues (const EntityKeyValues& other) :
00506             Entity(other), m_eclass(&other.getEntityClass()), m_undo(m_keyValues, UndoImportCaller(*this)),
00507                     m_instanced(false), m_observerMutex(false), m_isContainer(other.m_isContainer)
00508         {
00509             for (KeyValues::const_iterator i = other.m_keyValues.begin(); i != other.m_keyValues.end(); ++i) {
00510                 insert((*i).first.c_str(), (*i).second->c_str());
00511             }
00512         }
00513         ~EntityKeyValues ()
00514         {
00515             for (Observers::iterator i = m_observers.begin(); i != m_observers.end();) {
00516                 // post-increment to allow current element to be removed safely
00517                 (*i++)->clear();
00518             }
00519             ASSERT_MESSAGE(m_observers.empty(), "EntityKeyValues::~EntityKeyValues: observers still attached");
00520         }
00521 
00522         static void setKeyValueChangedFunc (EntityCreator::KeyValueChangedFunc func)
00523         {
00524             m_entityKeyValueChanged = func;
00525             KeyValue::setKeyValueChangedFunc(func);
00526         }
00527         static void setCounter (Counter* counter)
00528         {
00529             m_counter = counter;
00530         }
00531 
00532         void importState (const KeyValues& keyValues)
00533         {
00534             for (KeyValues::iterator i = m_keyValues.begin(); i != m_keyValues.end();) {
00535                 erase(i++);
00536             }
00537 
00538             for (KeyValues::const_iterator i = keyValues.begin(); i != keyValues.end(); ++i) {
00539                 insert((*i).first.c_str(), (*i).second);
00540             }
00541 
00542             m_entityKeyValueChanged();
00543         }
00544         typedef MemberCaller1<EntityKeyValues, const KeyValues&, &EntityKeyValues::importState> UndoImportCaller;
00545 
00546         void attach (Observer& observer)
00547         {
00548             ASSERT_MESSAGE(!m_observerMutex, "observer cannot be attached during iteration");
00549             m_observers.insert(&observer);
00550             for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00551                 observer.insert((*i).first.c_str(), *(*i).second);
00552             }
00553         }
00554         void detach (Observer& observer)
00555         {
00556             ASSERT_MESSAGE(!m_observerMutex, "observer cannot be detached during iteration");
00557             m_observers.erase(&observer);
00558             for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00559                 observer.erase((*i).first.c_str(), *(*i).second);
00560             }
00561         }
00562 
00563         void forEachKeyValue_instanceAttach (MapFile* map)
00564         {
00565             for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00566                 (*i).second->instanceAttach(map);
00567             }
00568         }
00569         void forEachKeyValue_instanceDetach (MapFile* map)
00570         {
00571             for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00572                 (*i).second->instanceDetach(map);
00573             }
00574         }
00575 
00576         void instanceAttach (MapFile* map)
00577         {
00578             if (m_counter != 0) {
00579                 m_counter->increment();
00580             }
00581 
00582             m_instanced = true;
00583             forEachKeyValue_instanceAttach(map);
00584             m_undo.instanceAttach(map);
00585         }
00586         void instanceDetach (MapFile* map)
00587         {
00588             if (m_counter != 0) {
00589                 m_counter->decrement();
00590             }
00591 
00592             m_undo.instanceDetach(map);
00593             forEachKeyValue_instanceDetach(map);
00594             m_instanced = false;
00595         }
00596 
00597         // entity
00598         EntityClass& getEntityClass () const
00599         {
00600             return *m_eclass;
00601         }
00602         void forEachKeyValue (Visitor& visitor) const
00603         {
00604             for (KeyValues::const_iterator i = m_keyValues.begin(); i != m_keyValues.end(); ++i) {
00605                 visitor.visit((*i).first.c_str(), (*i).second->c_str());
00606             }
00607         }
00608 
00612         void setKeyValue (const std::string& key, const std::string& value)
00613         {
00614             if (value.empty()) {
00615                 erase(key.c_str());
00616             } else {
00617                 insert(key.c_str(), value.c_str());
00618             }
00619             m_entityKeyValueChanged();
00620         }
00621 
00627         const char* getKeyValue (const std::string& key) const
00628         {
00629             const char* value = getKeyValueOrNull(key);
00630             if (value)
00631                 return value;
00632             else
00633                 return EntityClass_valueForKey(*m_eclass, key);
00634         }
00635 
00639         void addMandatoryKeyValues ()
00640         {
00641             for (EntityClassAttributes::const_iterator i = m_eclass->m_attributes.begin(); i
00642                     != m_eclass->m_attributes.end(); ++i) {
00643                 if (i->second.m_mandatory && getKeyValueOrNull(i->first) == 0) {
00644                     this->setKeyValue(i->first, m_eclass->getDefaultForAttribute(i->first));
00645                     g_debug("addMandatoryKeyValues: adding %s\n", i->first.c_str());
00646                 }
00647             }
00648         }
00649 
00650         bool isContainer () const
00651         {
00652             return m_isContainer;
00653         }
00654 };
00655 
00658 class ResourceReference
00659 {
00660         std::string m_name;
00661         Resource* m_resource;
00662     public:
00663         ResourceReference (const std::string& name) :
00664             m_name(name)
00665         {
00666             capture();
00667         }
00668         ResourceReference (const ResourceReference& other) :
00669             m_name(other.m_name)
00670         {
00671             capture();
00672         }
00673         ResourceReference& operator= (const ResourceReference& other)
00674         {
00675             ResourceReference tmp(other);
00676             tmp.swap(*this);
00677             return *this;
00678         }
00679         ~ResourceReference ()
00680         {
00681             GlobalReferenceCache().release(m_name);
00682         }
00683 
00684         void capture ()
00685         {
00686             m_resource = GlobalReferenceCache().capture(m_name);
00687         }
00688 
00689         const std::string& getName () const
00690         {
00691             return m_name;
00692         }
00693         void setName (const std::string& name)
00694         {
00695             ResourceReference tmp(name);
00696             tmp.swap(*this);
00697         }
00698 
00699         void swap (ResourceReference& other)
00700         {
00701             std::swap(m_resource, other.m_resource);
00702             std::swap(m_name, other.m_name);
00703         }
00704 
00705         void attach (ModuleObserver& observer)
00706         {
00707             m_resource->attach(observer);
00708         }
00709         void detach (ModuleObserver& observer)
00710         {
00711             m_resource->detach(observer);
00712         }
00713 
00714         Resource* get ()
00715         {
00716             return m_resource;
00717         }
00718 };
00719 
00720 namespace std
00721 {
00724     inline void swap (ResourceReference& self, ResourceReference& other)
00725     {
00726         self.swap(other);
00727     }
00728 }
00729 
00730 #endif

Generated by  doxygen 1.6.2