1 //------------------------------------------------------------------------------
2 // emContext.h
3 //
4 // Copyright (C) 2005-2008,2010,2016,2018 Oliver Hamann.
5 //
6 // Homepage: http://eaglemode.sourceforge.net/
7 //
8 // This program is free software: you can redistribute it and/or modify it under
9 // the terms of the GNU General Public License version 3 as published by the
10 // Free Software Foundation.
11 //
12 // This program is distributed in the hope that it will be useful, but WITHOUT
13 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 // FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
15 // more details.
16 //
17 // You should have received a copy of the GNU General Public License version 3
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 //------------------------------------------------------------------------------
20 
21 #ifndef emContext_h
22 #define emContext_h
23 
24 #ifndef emAvlTree_h
25 #include <emCore/emAvlTree.h>
26 #endif
27 
28 #ifndef emCrossPtr_h
29 #include <emCore/emCrossPtr.h>
30 #endif
31 
32 #ifndef emTimer_h
33 #include <emCore/emTimer.h>
34 #endif
35 
36 class emModel;
37 class emRootContext;
38 
39 
40 //==============================================================================
41 //================================= emContext ==================================
42 //==============================================================================
43 
44 class emContext : public emEngine {
45 
46 public:
47 
48 	// Class for a context of models (read comments on emModel). It manages
49 	// an AVL tree for quickly refinding common models.
50 
51 	emContext(emContext & parentContext);
52 		// Construct a child context. For constructing a root context
53 		// please see emRootContext.
54 
55 	virtual ~emContext();
56 		// Destructor. This even deletes all common models in this
57 		// context, in an order respecting references between the
58 		// models. Child contexts and private models are not deleted by
59 		// this. They must have been destructed before or they must be
60 		// managed by common models.
61 
62 	void LinkCrossPtr(emCrossPtrPrivate & crossPtr);
63 		// This means emCrossPtr<emContext> is possible.
64 
65 	emRootContext & GetRootContext() const;
66 		// Get the root context.
67 
68 	emContext * GetParentContext() const;
69 		// Get the parent context. Returns NULL if this is the root
70 		// context.
71 
72 	emContext * GetFirstChildContext() const;
73 	emContext * GetLastChildContext() const;
74 	emContext * GetPrevContext() const;
75 	emContext * GetNextContext() const;
76 		// Get the first or last child context, or the previous or next
77 		// brother context, NULL if none.
78 
79 	emModel * Lookup(const type_info & modelClass,
80 	                 const char * name) const;
81 		// Search for a common model within this context.
82 		// Arguments:
83 		//   modelClass - Final class of the model.
84 		//   name       - Name of the model.
85 		// Returns: The model, or NULL if not found.
86 
87 	emModel * LookupInherited(const type_info & modelClass,
88 	                          const char * name) const;
89 		// Like Lookup, but if the model is not found in this context,
90 		// the parent context is searched, then the grad-parent, and so
91 		// on.
92 
93 	emString GetListing() const;
94 		// Just for debugging: Get a listing of all common models.
95 
96 	void GetModelInfo(int * pCommonCount, int * pPrivateCount=NULL,
97 	                  emModel * * * pArrayOfCommon=NULL) const;
98 		// Just for debugging: Get the number of common and private
99 		// models, and create an array of pointers to all common models.
100 		// The array must be deleted by the caller.
101 
102 protected:
103 
104 	virtual bool Cycle();
105 		// emContext has been derived from emEngine for convenience.
106 		// This default implementation does nothing and returns false.
107 
108 private:
109 
110 	friend class emModel;
111 	friend class emRootContext;
112 
113 	emContext(emScheduler & scheduler);
114 
115 	void RegisterModel(emModel * model);
116 	void UnregisterModel(emModel * model);
117 	static int CalcHashCode(const type_info & modelClass,
118 	                        const char * name);
119 	emModel * SearchUnused() const;
120 	emModel * SearchUnused(int minHash) const;
121 	emModel * SearchGarbage();
122 	emModel * SearchGarbage(int minHash);
123 	void CollectGarbage();
124 
125 	class SharedTimingEngine : public emEngine {
126 	public:
127 		SharedTimingEngine(emRootContext & rootContext,
128 		                   unsigned int gcPeriod);
129 		virtual ~SharedTimingEngine();
130 		virtual bool Cycle();
131 		emRootContext & RootContext;
132 		emTimer SecsTimer;
133 		unsigned int GCPeriod;
134 		unsigned int SecsCounter;
135 		unsigned int TimeOfGC;
136 	};
137 
138 	friend class SharedTimingEngine;
139 
140 	emRootContext & RootContext;
141 	emCrossPtrList CrossPtrList;
142 	SharedTimingEngine * SharedTiming;
143 	emContext * ParentContext;
144 	emContext * FirstChildContext;
145 	emContext * LastChildContext;
146 	emContext * PrevContext;
147 	emContext * NextContext;
148 	emAvlTree AvlTree;
149 	unsigned int ModelCount;
150 	bool DoGCOnModels;
151 };
152 
153 
154 //==============================================================================
155 //=============================== emRootContext ================================
156 //==============================================================================
157 
158 class emRootContext : public emContext {
159 
160 public:
161 
162 	emRootContext(emScheduler & scheduler);
163 		// Construct a root context.
164 
165 	virtual ~emRootContext();
166 		// Destructor.
167 };
168 
169 
170 //==============================================================================
171 //============================== Implementations ===============================
172 //==============================================================================
173 
LinkCrossPtr(emCrossPtrPrivate & crossPtr)174 inline void emContext::LinkCrossPtr(emCrossPtrPrivate & crossPtr)
175 {
176 	CrossPtrList.LinkCrossPtr(crossPtr);
177 }
178 
GetRootContext()179 inline emRootContext & emContext::GetRootContext() const
180 {
181 	return RootContext;
182 }
183 
GetParentContext()184 inline emContext * emContext::GetParentContext() const
185 {
186 	return ParentContext;
187 }
188 
GetFirstChildContext()189 inline emContext * emContext::GetFirstChildContext() const
190 {
191 	return FirstChildContext;
192 }
193 
GetLastChildContext()194 inline emContext * emContext::GetLastChildContext() const
195 {
196 	return LastChildContext;
197 }
198 
GetPrevContext()199 inline emContext * emContext::GetPrevContext() const
200 {
201 	return PrevContext;
202 }
203 
GetNextContext()204 inline emContext * emContext::GetNextContext() const
205 {
206 	return NextContext;
207 }
208 
emRootContext(emScheduler & scheduler)209 inline emRootContext::emRootContext(emScheduler & scheduler)
210 	: emContext(scheduler)
211 {
212 }
213 
214 
215 #endif
216