Cafu Engine
ObserverPattern.hpp
Go to the documentation of this file.
1 /*
2 Cafu Engine, http://www.cafu.de/
3 Copyright (c) Carsten Fuchs and other contributors.
4 This project is licensed under the terms of the MIT license.
5 */
6 
7 #ifndef CAFU_OBSERVER_PATTERN_HPP_INCLUDED
8 #define CAFU_OBSERVER_PATTERN_HPP_INCLUDED
9 
10 /// \file
11 /// This file provides the classes for the Observer pattern as described in the book by the GoF.
12 /// Note that implementations of ObserverT normally maintain a pointer to the subject(s) that they observe,
13 /// e.g. in order to be able to redraw themselves also outside of and independent from the NotifySubjectChanged() method.
14 /// This however in turn creates problems when the life of the observer begins before or ends after the life of the observed subject(s).
15 /// In fact, it seems that the observers have to maintain lists of valid, observed subjects as the subjects maintain lists of observers.
16 /// Fortunately, these possibly tough problems can (and apparently must) be addressed by the concrete implementation classes of
17 /// observers and subjects, not by the base classes that the Observer pattern describes and provided herein.
18 
19 #include "Math3D/BoundingBox.hpp"
20 #include "Templates/Array.hpp"
21 #include "Templates/Pointer.hpp"
22 
23 #include "wx/string.h"
24 
25 
26 namespace cf { namespace GameSys { class EntityT; } }
27 namespace cf { namespace TypeSys { class VarBaseT; } }
28 namespace MapEditor { class CompMapEntityT; }
29 class SubjectT;
30 class MapElementT;
31 class MapPrimitiveT;
32 
33 
34 //#####################################
35 //# New observer notifications hints. #
36 //#####################################
38 {
39  MEMD_GENERIC, ///< Generic change of map elements (useful if the subject doesn't know what exactly has been changed).
40  MEMD_TRANSFORM, ///< A map element has been transformed.
41  MEMD_PRIMITIVE_PROPS_CHANGED, ///< The properties of a map primitive have been modified.
42  MEMD_SURFACE_INFO_CHANGED, ///< The surface info of a map element has changed. Note that surface info changes also include the selection of faces.
43  MEMD_ASSIGN_PRIM_TO_ENTITY, ///< A map primitive has been assigned to another entity (the world or any custom entity).
44  MEMD_VISIBILITY ///< The visibility of a map element has changed.
45 };
46 
48 {
49  EMD_COMPONENTS, ///< The set of components has changed (e.g. added, deleted, order changed).
50  EMD_HIERARCHY ///< The position of an entity in the entity hierarchy has changed.
51 };
52 
53 enum MapDocOtherDetailT
54 {
55  UPDATE_GRID,
56  UPDATE_POINTFILE,
57  UPDATE_GLOBALOPTIONS
58 };
59 //############################################
60 //# End of new observer notifications hints. #
61 //############################################
62 
63 
64 class ObserverT
65 {
66  public:
67 
68  //###################################################################################################################################
69  //# New observer notifications methods. These methods differ from the basic observer pattern from the GoF and are CaWE specific! #
70  //# Note that the new methods are NOT pure virtual since a concrete observer might not be interested in some of these notifications #
71  //###################################################################################################################################
72 
73  /// Notifies the observer that some other detail than those specifically addressed below has changed.
74  virtual void NotifySubjectChanged(SubjectT* Subject, MapDocOtherDetailT OtherDetail) { }
75 
76  /// Notifies the observer that the selection in the current subject has been changed.
77  /// @param Subject The map document in which the selection has been changed.
78  /// @param OldSelection Array of the previously selected objects.
79  /// @param NewSelection Array of the new selected objects.
80  virtual void NotifySubjectChanged_Selection(SubjectT* Subject, const ArrayT<MapElementT*>& OldSelection, const ArrayT<MapElementT*>& NewSelection) { }
81 
82  /// Notifies the observer that the groups in the current subject have been changed (new group added, group deleted, visibility changed, anything).
83  /// @param Subject The map document in which the group inventory has been changed.
84  virtual void NotifySubjectChanged_Groups(SubjectT* Subject) { }
85 
86  /// Notifies the observer that one or more entities have been created.
87  /// @param Subject The map document in which the entities have been created.
88  /// @param Entities List of created entities.
90 
91  /// Notifies the observer that one or more map primitives have been created.
92  /// @param Subject The map document in which the primitives have been created.
93  /// @param Primitives List of created map primitives.
94  virtual void NotifySubjectChanged_Created(SubjectT* Subject, const ArrayT<MapPrimitiveT*>& Primitives) { }
95 
96  /// Notifies the observer that one or more entities have been deleted.
97  /// @param Subject The map document in which the entities have been deleted.
98  /// @param Entities List of deleted entities.
100 
101  /// Notifies the observer that one or more map primitives have been deleted.
102  /// @param Subject The map document in which the primitives have been deleted.
103  /// @param Primitives List of deleted map primitives.
104  virtual void NotifySubjectChanged_Deleted(SubjectT* Subject, const ArrayT<MapPrimitiveT*>& Primitives) { }
105 
106  /// @name Modification notification method and overloads.
107  /// These methods notify the observer that one or more map elements have been modified.
108  /// The first 3 parameters are common to all of these methods since they are the basic information needed to communicate
109  /// an object modification.
110  //@{
111 
112  /// @param Subject The map document in which the elements have been modified.
113  /// @param MapElements List of modified map elements.
114  /// @param Detail Information about what has been modified:
115  /// Can be one of MEMD_PRIMITIVE_PROPS_CHANGED, MEMD_GENERIC, MEMD_ASSIGN_PRIM_TO_ENTITY and MEMD_MATERIAL_CHANGED.
116  virtual void NotifySubjectChanged_Modified(SubjectT* Subject, const ArrayT<MapElementT*>& MapElements, MapElemModDetailE Detail) { }
117 
118  /// @param Subject The map document in which the elements have been modified.
119  /// @param MapElements List of modified map elements.
120  /// @param Detail Information about what has been modified:
121  /// Can be MEMD_TRANSFORM or MEMD_PRIMITIVE_PROPS_CHANGED.
122  /// In the case of MEMD_PRIMITIVE_PROPS_CHANGED one can assume that
123  /// only map primitives (no entities) are in the MapElements array.
124  /// @param OldBounds Holds the bounds of each objects BEFORE the modification (has the same size as MapElements).
125  virtual void NotifySubjectChanged_Modified(SubjectT* Subject, const ArrayT<MapElementT*>& MapElements, MapElemModDetailE Detail, const ArrayT<BoundingBox3fT>& OldBounds) { }
126 
127  /// @param Subject The map document in which the entities have been modified.
128  /// @param Entities List of modified map entities.
129  /// @param Detail Information about what has been modified.
130  virtual void Notify_EntChanged(SubjectT* Subject, const ArrayT< IntrusivePtrT<MapEditor::CompMapEntityT> >& Entities, EntityModDetailE Detail) { }
131 
132  /// Notifies the observer that a variable has changed.
133  /// @param Subject The map document in which a variable has changed.
134  /// @param Var The variable whose value has changed.
135  virtual void Notify_VarChanged(SubjectT* Subject, const cf::TypeSys::VarBaseT& Var) { }
136  //@}
137 
138  //############################################
139  //# End of new observer notification methods #
140  //############################################
141 
142 
143  /// This method is called whenever a subject is about the be destroyed (and become unavailable).
144  /// \param dyingSubject The subject that is being destroyed.
145  virtual void NotifySubjectDies(SubjectT* dyingSubject)=0;
146 
147  /// The virtual destructor.
148  virtual ~ObserverT();
149 
150 
151  protected:
152 
153  /// The constructor. It is protected so that only derived classes can create instances of this class.
154  ObserverT();
155 };
156 
157 
158 class SubjectT
159 {
160  public:
161 
162  /// Registers the observer Obs for notification on updates of this class.
163  /// \param Obs The observer that is to be registered.
164  void RegisterObserver(ObserverT* Obs);
165 
166  /// Unregisters the observer Obs from further notification on updates of this class.
167  /// \param Obs The observer that is to be unregistered.
168  void UnregisterObserver(ObserverT* Obs);
169 
170 
171  //###################################################################################################################################
172  //# New observer notifications methods. These methods differ from the basic observer pattern from the GoF and are CaWE specific! #
173  //# For detailed comments on the parameters, see the equivalent methods in ObserverT #
174  //###################################################################################################################################
175  void UpdateAllObservers(MapDocOtherDetailT OtherDetail);
176  void UpdateAllObservers_SelectionChanged(const ArrayT<MapElementT*>& OldSelection, const ArrayT<MapElementT*>& NewSelection);
177  void UpdateAllObservers_GroupsChanged();
178  void UpdateAllObservers_Created(const ArrayT< IntrusivePtrT<cf::GameSys::EntityT> >& Entities);
179  void UpdateAllObservers_Created(const ArrayT<MapPrimitiveT*>& Primitives);
180  void UpdateAllObservers_Deleted(const ArrayT< IntrusivePtrT<cf::GameSys::EntityT> >& Entites);
181  void UpdateAllObservers_Deleted(const ArrayT<MapPrimitiveT*>& Primitives);
182  void UpdateAllObservers_Modified(const ArrayT<MapElementT*>& MapElements, MapElemModDetailE Detail);
183  void UpdateAllObservers_Modified(const ArrayT<MapElementT*>& MapElements, MapElemModDetailE Detail, const ArrayT<BoundingBox3fT>& OldBounds);
184  void UpdateAllObservers_EntChanged(const ArrayT< IntrusivePtrT<MapEditor::CompMapEntityT> >& Entities, EntityModDetailE Detail);
185  void UpdateAllObservers_EntChanged(const ArrayT< IntrusivePtrT<cf::GameSys::EntityT> >& Entities, EntityModDetailE Detail);
186  void UpdateAllObservers_EntChanged(IntrusivePtrT<cf::GameSys::EntityT> Entity, EntityModDetailE Detail);
187  void UpdateAllObservers_VarChanged(const cf::TypeSys::VarBaseT& Var);
188  void UpdateAllObservers_SubjectDies();
189 
190  /// The virtual destructor.
191  virtual ~SubjectT();
192 
193 
194  protected:
195 
196  /// The constructor. It is protected so that only derived classes can create instances of this class.
197  SubjectT();
198 
199 
200  private:
201 
202  /// The list of the observers that have registered for notification on updates of this class.
203  ArrayT<ObserverT*> m_Observers;
204 };
205 
206 #endif
MapElemModDetailE
Definition: ObserverPattern.hpp:37
virtual ~ObserverT()
The virtual destructor.
Definition: ObserverPattern.cpp:19
SubjectT()
The constructor. It is protected so that only derived classes can create instances of this class...
Definition: ObserverPattern.cpp:24
virtual ~SubjectT()
The virtual destructor.
Definition: ObserverPattern.cpp:149
virtual void NotifySubjectChanged_Modified(SubjectT *Subject, const ArrayT< MapElementT * > &MapElements, MapElemModDetailE Detail, const ArrayT< BoundingBox3fT > &OldBounds)
Definition: ObserverPattern.hpp:125
virtual void NotifySubjectChanged_Modified(SubjectT *Subject, const ArrayT< MapElementT * > &MapElements, MapElemModDetailE Detail)
Definition: ObserverPattern.hpp:116
The visibility of a map element has changed.
Definition: ObserverPattern.hpp:44
virtual void Notify_EntChanged(SubjectT *Subject, const ArrayT< IntrusivePtrT< MapEditor::CompMapEntityT > > &Entities, EntityModDetailE Detail)
Definition: ObserverPattern.hpp:130
virtual void NotifySubjectChanged_Selection(SubjectT *Subject, const ArrayT< MapElementT * > &OldSelection, const ArrayT< MapElementT * > &NewSelection)
Notifies the observer that the selection in the current subject has been changed. ...
Definition: ObserverPattern.hpp:80
Generic change of map elements (useful if the subject doesn't know what exactly has been changed)...
Definition: ObserverPattern.hpp:39
This class adds no functionality of its own, but only exists for proper type separation.
Definition: MapPrimitive.hpp:21
The position of an entity in the entity hierarchy has changed.
Definition: ObserverPattern.hpp:50
virtual void NotifySubjectChanged_Groups(SubjectT *Subject)
Notifies the observer that the groups in the current subject have been changed (new group added...
Definition: ObserverPattern.hpp:84
virtual void NotifySubjectChanged_Created(SubjectT *Subject, const ArrayT< MapPrimitiveT * > &Primitives)
Notifies the observer that one or more map primitives have been created.
Definition: ObserverPattern.hpp:94
EntityModDetailE
Definition: ObserverPattern.hpp:47
virtual void Notify_VarChanged(SubjectT *Subject, const cf::TypeSys::VarBaseT &Var)
Notifies the observer that a variable has changed.
Definition: ObserverPattern.hpp:135
The surface info of a map element has changed. Note that surface info changes also include the select...
Definition: ObserverPattern.hpp:42
virtual void NotifySubjectChanged_Deleted(SubjectT *Subject, const ArrayT< IntrusivePtrT< cf::GameSys::EntityT > > &Entities)
Notifies the observer that one or more entities have been deleted.
Definition: ObserverPattern.hpp:99
Definition: ObserverPattern.hpp:64
void UnregisterObserver(ObserverT *Obs)
Unregisters the observer Obs from further notification on updates of this class.
Definition: ObserverPattern.cpp:40
The set of components has changed (e.g. added, deleted, order changed).
Definition: ObserverPattern.hpp:49
The properties of a map primitive have been modified.
Definition: ObserverPattern.hpp:41
virtual void NotifySubjectChanged_Deleted(SubjectT *Subject, const ArrayT< MapPrimitiveT * > &Primitives)
Notifies the observer that one or more map primitives have been deleted.
Definition: ObserverPattern.hpp:104
virtual void NotifySubjectChanged(SubjectT *Subject, MapDocOtherDetailT OtherDetail)
Notifies the observer that some other detail than those specifically addressed below has changed...
Definition: ObserverPattern.hpp:74
virtual void NotifySubjectDies(SubjectT *dyingSubject)=0
This method is called whenever a subject is about the be destroyed (and become unavailable).
Definition: ObserverPattern.hpp:158
ObserverT()
The constructor. It is protected so that only derived classes can create instances of this class...
Definition: ObserverPattern.cpp:14
This is the common base class for the VarT classes.
Definition: Variables.hpp:113
void RegisterObserver(ObserverT *Obs)
Registers the observer Obs for notification on updates of this class.
Definition: ObserverPattern.cpp:29
This is the base class for all elements ("objects") that can exist in a map.
Definition: MapElement.hpp:57
virtual void NotifySubjectChanged_Created(SubjectT *Subject, const ArrayT< IntrusivePtrT< cf::GameSys::EntityT > > &Entities)
Notifies the observer that one or more entities have been created.
Definition: ObserverPattern.hpp:89
A map primitive has been assigned to another entity (the world or any custom entity).
Definition: ObserverPattern.hpp:43
A map element has been transformed.
Definition: ObserverPattern.hpp:40