fix MD3 model entities crash on OS X (by renaming a class; apparently something weird...
[xonotic/netradiant.git] / plugins / entity / model.h
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined(INCLUDED_MODEL_H)
23 #define INCLUDED_MODEL_H
24
25 #include "entitylib.h"
26 #include "traverselib.h"
27 #include "generic/callback.h"
28 #include "stream/stringstream.h"
29 #include "os/path.h"
30 #include "moduleobserver.h"
31
32 class EModel : public ModuleObserver
33 {
34   ResourceReference m_resource;
35   scene::Traversable& m_traverse;
36   scene::Node* m_node;
37   Callback m_modelChanged;
38
39 public:
40   EModel(scene::Traversable& traversable, const Callback& modelChanged)
41     : m_resource(""), m_traverse(traversable), m_node(0), m_modelChanged(modelChanged)
42   {
43     m_resource.attach(*this);
44   }
45   ~EModel()
46   {
47     m_resource.detach(*this);
48   }
49
50   void realise()
51   {
52     m_resource.get()->load();
53     m_node = m_resource.get()->getNode();
54     if(m_node != 0)
55     {
56       m_traverse.insert(*m_node);
57     }
58   }
59   void unrealise()
60   {
61     if(m_node != 0)
62     {
63       m_traverse.erase(*m_node);
64     }
65   }
66   
67   void modelChanged(const char* value)
68   {
69     StringOutputStream cleaned(string_length(value));
70     cleaned << PathCleaned(value);
71     m_resource.detach(*this);
72     m_resource.setName(cleaned.c_str());
73     m_resource.attach(*this);
74     m_modelChanged();
75   }
76   typedef MemberCaller1<EModel, const char*, &EModel::modelChanged> ModelChangedCaller;
77
78   const char* getName() const
79   {
80     return m_resource.getName();
81   }
82   scene::Node* getNode() const
83   {
84     return m_node;
85   }
86 };
87
88 class SingletonModel
89 {
90   TraversableNode m_traverse;
91   EModel m_model;
92 public:
93   SingletonModel()
94     : m_model(m_traverse, Callback())
95   {
96   }
97
98   void attach(scene::Traversable::Observer* observer)
99   {
100     m_traverse.attach(observer);
101   }
102   void detach(scene::Traversable::Observer* observer)
103   {
104     m_traverse.detach(observer);
105   }
106
107   scene::Traversable& getTraversable()
108   {
109     return m_traverse;
110   }
111
112   void modelChanged(const char* value)
113   {
114     m_model.modelChanged(value);
115   }
116   typedef MemberCaller1<SingletonModel, const char*, &SingletonModel::modelChanged> ModelChangedCaller;
117
118   scene::Node* getNode() const
119   {
120     return m_model.getNode();
121   }
122 };
123
124 #endif