source: trunk/include/cppbase/bs_base.h@ 433

Last change on this file since 433 was 250, checked in by umoeller, 23 years ago

Build updates, moved files from warpin.

  • Property svn:eol-style set to CRLF
  • Property svn:keywords set to Author Date Id Revision
File size: 10.1 KB
Line 
1
2/*
3 * bs_base.h:
4 *
5 *@@added V0.9.14 (2001-07-12) [umoeller]
6 *@@include #include "base\bs_base.h"
7 */
8
9/*
10 * This file Copyright (C) 2001 Ulrich M”ller.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation, in version 2 as it comes in the COPYING
14 * file of this distribution.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20
21#ifndef BSBASE_HEADER_INCLUDED
22 #define BSBASE_HEADER_INCLUDED
23
24 /* ******************************************************************
25 *
26 * Root classes
27 *
28 ********************************************************************/
29
30 /*
31 *@@ BSClassID:
32 * represents a class ID for a WarpIN class
33 * derived from BSRoot.
34 *
35 * This class is used for WarpIN run-time
36 * type information (RTTI) since we do not
37 * use the C++ facilities for that (VAC
38 * doesn't support those).
39 *
40 * If you're familiar with SOM, a BSClassID
41 * can be compared to a SOM "class object",
42 * which is an instance of a class's metaclass.
43 *
44 * Each instance of BSRoot contains a reference
45 * to its BSClassID so we can check each
46 * object's class at runtime.
47 * No matter how many instances of a class
48 * exist, there will be only one BSClassID
49 * instance for all instances of the class.
50 *
51 * The BSRoot constructor takes a reference
52 * to the class's BSClassID as its only (and
53 * required) parameter, which is then stored
54 * in the BSRoot instance data. This way, at
55 * any time, each object can query its own
56 * class and climb up the tree of parent
57 * classes, if desired.
58 *
59 * Unless the BSClassID instance represents
60 * BSRoot itself, the pParentClass member
61 * will always point to the parent class,
62 * which may be the BSRoot id if the class
63 * is derived from BSRoot directly.
64 *
65 * This concept doesn't support multiple
66 * inheritance at this point, but that's not
67 * used in WarpIN anyway.
68 */
69
70 class BSClassID
71 {
72 public:
73 const char *_pcszClassName; // clear class name (e.g. "MyClass")
74 BSClassID *_pParentClass; // pointer to parent class ID; if NULL,
75 // this represents BSRoot.
76
77 BSClassID(const char *pcszClassName,
78 BSClassID *pParentClass)
79 {
80 _pcszClassName = pcszClassName;
81 _pParentClass = pParentClass;
82 }
83 };
84
85 /*
86 *@@ BSRoot:
87 * the root class of the WarpIN class hierarchy.
88 *
89 * BSRoot implements the following:
90 *
91 * -- run-time type identification; each object
92 * can inspect its _Class member and always
93 * know which class it is an instance of.
94 *
95 * -- "derived from" queries: invoke IsA() on
96 * an object and find out whether the object
97 * is an instance of a certain class.
98 *
99 * -- list<P> support; while this isn't really
100 * necessary, the debug list implementation
101 * invokes BSRoot methods for logging, so
102 * presently all objects that are supposed
103 * to be stored with a linked list (see
104 * bs_list.h) must be instances of BSRoot
105 * or a class derived from BSRoot.
106 *
107 * BSRoot itself cannot be instantiated because
108 * the constructor is protected. A class that
109 * derives from BSRoot must do three things:
110 *
111 * 1) Declare the class ID in the class's
112 * declaration, like this:
113 *
114 + class MyClass : public BSRoot
115 + {
116 + public: DECLARE_CLASS(MyClass);
117 + }
118 *
119 * DECLARE_CLASS(MyClass) expands to
120 *
121 + static BSClassID tMyClass;
122 *
123 * BSClassID represents a "class object" for
124 * each class. See BSClassID for details.
125 * You can later reference the class's
126 * ID by using MyClass::tMyClass from
127 * anywhere. The "t" prefix is arbitrary,
128 * but if you use the macros, you better
129 * stick with it.
130 *
131 * 2) Define the class ID in your source file.
132 * Since the class ID is just a regular
133 * static class variable, it must be initialized
134 * statically, and once only (in the source
135 * file).
136 *
137 * Another macro was defined for this, which
138 * expects the class's parent class as well:
139 *
140 + DEFINE_CLASS(MyClass, BSRoot); // MyClass is derived from BSRoot
141 *
142 * The parent class better match the class
143 * declaration. This macro expands to:
144 *
145 + BSClassID MyClass::tMyClass("MyClass", // class name string
146 + &BSRoot::tBSRoot) // parent class object
147 *
148 * In other words, the DECLARE_CLASS and DEFINE_CLASS
149 * macros are just a quick way to declare and
150 * implement a static BSClassID class variable.
151 *
152 * 3) Your class's constructors must always call
153 * the BSRoot constructor explicitly in the
154 * initializer list. Give your own class ID to
155 * BSRoot's constructor. This will properly set
156 * BSRoot's _Class member.
157 *
158 * Since BSRoot::BSRoot is protected, the compiler
159 * will properly warn you if you forget this.
160 *
161 * For example:
162 *
163 + MyClass::MyClass(int iDummy)
164 + : BSBase(tMyClass)
165 + {...}
166 *
167 * After all this, BSRoot gives you the following nice
168 * features:
169 *
170 * 1) BSRoot::QueryClassName() returns the
171 * name of the class that the object really
172 * is an instance of.
173 *
174 * 2) BSRoot::IsA() returns true if the object
175 * is an instance of the given class.
176 *
177 *@@changed V0.9.14 (2001-08-03) [umoeller]: overrode new and delete ptrs
178 */
179
180 class BSRoot
181 {
182 // class methods
183 public:
184 static BSClassID tBSRoot;
185
186 public:
187 #ifdef __DEBUG__
188 static void OpenDebugLog(const char *pcszDir);
189 static void WriteToDebugLog(const char *pcszFormat, ...);
190 static void CloseDebugLog();
191 #endif
192
193 // instance methods
194 public:
195 BSClassID &_Class;
196
197 protected:
198 BSRoot(BSClassID &Class);
199
200 BSRoot(const BSRoot &p);
201 BSRoot& operator=(const BSRoot &p);
202
203 public:
204 virtual ~BSRoot();
205
206 bool IsA(BSClassID &Class) const;
207
208 const char* QueryClassName() const;
209
210 /*
211 public:
212 void* operator new(size_t n) { return malloc(n); };
213 void operator delete(void* p) { free(p); };
214 */
215 };
216
217 /*
218 *@@ DECLARE_CLASS:
219 * handy macro to declare class object for
220 * use with BSRoot and BSClassID.
221 *
222 * This should appear in the class declaration.
223 *
224 */
225
226 #define DECLARE_CLASS(cls) static BSClassID t##cls
227
228 /*
229 *@@ DEFINE_CLASS:
230 * handy macro to define a class object with
231 * its parent class object for use with BSRoot
232 * and BSClassID.
233 *
234 * For each class that was declared with DECLARE_CLASS,
235 * a corresponding DEFINE_CLASS must appear in the
236 * source somewhere.
237 */
238
239 #define DEFINE_CLASS(cls, parent) BSClassID cls::t##cls(#cls, &parent::t##parent)
240
241 /*
242 *@@ DYNAMIC_CAST:
243 * freaky macro to simulate a dynamic cast.
244 *
245 * Usage:
246 *
247 + DYNAMIC_CAST(BSDerived, pobj, pSource);
248 *
249 * expands to
250 *
251 + BSDerived *pobj = (pSource->IsA(BSDerived::tBSDerived) ? ((BSDerived*)pSource) : 0;
252 */
253
254 #define DYNAMIC_CAST(cls, pT, p) cls *pT = ((p)->IsA(cls::t##cls)) ? (cls*)(p) : 0
255
256 /* ******************************************************************
257 *
258 * Locks
259 *
260 ********************************************************************/
261
262 /*
263 *@@ BSMutex:
264 * representation of an OS/2 mutex, to
265 * be used within BSLock.
266 *
267 *@@added V0.9.19 (2002-05-07) [umoeller]
268 */
269
270 class BSMutex
271 {
272 unsigned long _hmtx;
273
274 public:
275 BSMutex();
276 ~BSMutex();
277 bool Request() const;
278 bool Release() const;
279 };
280
281 /*
282 *@@ BSLock:
283 * exception-safe mutex implementation.
284 * Creating an instance of this requests
285 * the BSMutex given in the constructor,
286 * and the destructor releases it.
287 *
288 *@@added V0.9.19 (2002-05-07) [umoeller]
289 */
290
291 class BSLock
292 {
293 const BSMutex &_mtx;
294 int _cRequests;
295
296 public:
297 BSLock(const BSMutex &mtx)
298 : _mtx(mtx)
299 {
300 if (mtx.Request())
301 ++_cRequests;
302 }
303
304 ~BSLock()
305 {
306 if ( (_cRequests)
307 && (_mtx.Release())
308 )
309 --_cRequests;
310 }
311 };
312
313#endif
314
Note: See TracBrowser for help on using the repository browser.