1 /*
2 This file is part of "Avanor, the Land of Mystery" roguelike game
3 Home page: http://www.avanor.com/
4 Copyright (C) 2000-2003 Vadim Gaidukevich
5 
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20 
21 #ifndef __XOBJECT_H
22 #define __XOBJECT_H
23 
24 #include <string.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <assert.h>
28 #include "defs.h"
29 #include "xfile.h"
30 
31 
32 enum ITEM_MASK {
33 IM_UNKNOWN     = 0x00000000,
34 IM_HERO        = 0x00000001, //let it's be
35 IM_CREATURE    = 0x00000002,
36 IM_MONSTER     = IM_HERO | IM_CREATURE,
37 IM_WAY         = 0x00000004,
38 IM_DOOR        = 0x00000008,
39 IM_TRAP        = 0x00000010,
40 IM_TELEPORT	   = 0x00000020,
41 IM_ALTAR	   = 0x00000040,
42 IM_MISC		   = 0x00000080,
43 
44 IM_HAT         = 0x00000100,
45 IM_NECK        = 0x00000200,
46 IM_BODY        = 0x00000400,
47 IM_CLOAK       = 0x00000800,
48 IM_WEAPON      = 0x00001000,
49 IM_SHIELD      = 0x00002000,
50 IM_HAND        = IM_WEAPON | IM_SHIELD, //for a bodyparts
51 IM_GLOVES      = 0x00004000,
52 IM_RING        = 0x00008000,
53 IM_BOOTS       = 0x00010000,
54 IM_MISSILEW    = 0x00020000,
55 IM_MISSILE     = 0x00040000,
56 IM_POTION      = 0x00100000,
57 IM_SCROLL      = 0x00200000,
58 IM_BOOK        = 0x00400000,
59 IM_WAND        = 0x00800000,
60 IM_FOOD        = 0x01000000,
61 IM_HERB        = 0x02000000,
62 IM_LIGHTSOURCE = 0x04000000,
63 IM_TOOL        = 0x08000000,
64 IM_GEM         = 0x10000000,
65 IM_MONEY       = 0x20000000,
66 IM_STACKABLE   = 0x40000000, //for spells
67 IM_CHEST	   = 0x80000000,
68 IM_ITEM        = 0x2FFFFF00, //all items!
69 
70 IM_OTHER       = 0x80000000,
71 IM_TOHIT       = IM_HAT | IM_NECK | IM_BODY | IM_CLOAK | IM_GLOVES | IM_SHIELD | IM_BOOTS | IM_RING | IM_WEAPON,
72 IM_ARMOUR      = IM_HAT | IM_BODY | IM_CLOAK | IM_GLOVES | IM_SHIELD | IM_BOOTS,
73 IM_VALUEDICE   = IM_WEAPON | IM_MISSILEW | IM_MISSILE,
74 IM_VALUEDVPV   = IM_HAT | IM_BODY | IM_CLOAK | IM_GLOVES | IM_SHIELD | IM_BOOTS | IM_WEAPON,
75 IM_VALUEHITDMG = IM_HAT | IM_BODY | IM_CLOAK | IM_GLOVES | IM_BOOTS | IM_WEAPON,
76 IM_ALL         = 0xFFFFFFFF
77 };
78 
79 
80 class XObject;
81 //next code is for creating class by it name
82 typedef XObject * (*CLASS_CREATOR)();
83 
84 #define REGISTER_CLASS(__xClass) \
85 	XClassFactory reg##__xClass(#__xClass, (CLASS_CREATOR)__xClass::Creator)
86 
87 struct DUMMY_STRUCT
88 {
89 };
90 
91 #define DECLARE_CREATOR(__xClass, __xBaseClass) \
92 	__xClass(DUMMY_STRUCT * ds) : __xBaseClass(ds) {} \
93 	static __xClass * Creator() {DUMMY_STRUCT ds; return new __xClass(&ds);} \
94 	virtual const char * GetClassName() {return #__xClass;}
95 //	void InvalidateLeave() {__xBaseClass::Invalidate();}
96 
97 //#define INVALIDATE_ENTER() static int inside = 0; assert(!inside); if (!isValid()) return; inside = 1;
98 //#define INVALIDATE_LEAVE() InvalidateLeave(); inside = 0;
99 
100 //virtual XObject * MakeCopy() {return new __xClass(this);}
101 
102 class XClassInfo
103 {
104 public:
XClassInfo(char * _name,CLASS_CREATOR p)105 	XClassInfo(char * _name, CLASS_CREATOR p) {name = _name; pClassCreator = p; next = NULL;}
106 	char * name;
107 	CLASS_CREATOR pClassCreator;
108 	XClassInfo * next;
109 };
110 
111 class XClassFactory
112 {
113 public:
114 	static XClassInfo * first_class;
115 	static int counter;
116 	XClassFactory(char * name, CLASS_CREATOR pClass);
117 	~XClassFactory();
118 	static XObject * Create(char * name);
119 };
120 
121 #define DYNCREATE(x) XClassFactory::Create(x)
122 // end
123 
124 
125 
126 typedef unsigned long XGUID;
127 extern XGUID guid;
128 
129 //this class is a base class for most important part's of cernel
130 class XObject
131 {
132 public:
133 	static long       invalid_count;
134 	static XObject ** table;
135 	static long       count;
136 	static XObject  * root;
137 
138 	XObject         * prev;
139 	XObject         * next;
140 
141 	bool              bAlreadyStored;
142 
AddToList()143 	void AddToList()
144 	{
145 		assert(table == 0);
146 		if (root != 0) root->prev = this;
147 		prev = 0;
148 		next = root;
149 		root = this;
150 		count++;
151 	}
152 
RemoveFromList()153 	void RemoveFromList()
154 	{
155 		assert(table == 0);
156 		if (this == root) root = next;
157 		if (prev != 0) prev->next = next;
158 		if (next != 0) next->prev = prev;
159 		count--;
160 		invalid_count++;
161 	}
162 
163 	int reference; //objects can't be deleted till reference > 0
164 	int is_valid;
165 
Create()166 	void Create()
167 	{
168 		reference = 0;
169 		AddToList();
170 	}
171 
172 public:
173 	static void      StorePointer(XFile * f, XObject * p);
174 	static XObject * RestorePointer(XFile * f, void * owner);
175 	static void      StoreAllObjects(XFile * f);
176 	static void      RestoreAllObjects(XFile * f);
177 	static void      InvalidateAllObjects();
178 	static void      FreeTable();
179 
180 	// DECLARE_CREATOR(XObject);
181 
XObject(DUMMY_STRUCT * ds)182 	XObject(DUMMY_STRUCT * ds) : is_valid(1)
183 	{
184 		Create();
185 	}
186 
XObject()187 	XObject() : xguid(::guid++), quantity(1), im(IM_UNKNOWN), is_valid(1)
188 	{
189 		Create();
190 	}
191 
XObject(XObject * o)192 	XObject(XObject * o) : xguid(::guid++), quantity(o->quantity), im(o->im), is_valid(1), 	ttm(o->ttm), ttmb(o->ttmb)
193 
194 	{
195 		Create();
196 	}
197 
~XObject()198 	virtual ~XObject()
199 	{
200 		assert(!is_valid && reference == 0);
201 		invalid_count--;
202 	}
203 
AddRef()204 	void AddRef()
205 	{
206 		reference++;
207 	}
208 
Release()209 	void Release()
210 	{
211 		assert(reference > 0);
212 		if(--reference == 0 && !is_valid)
213 		{
214 			delete this;
215 		}
216 	}
217 
GetRef()218    int GetRef()
219    {
220       return reference;
221    }
222 
Invalidate()223 	virtual void Invalidate()
224 	{
225 //		assert(is_valid);
226 		if (!is_valid) return;
227   		is_valid = 0;
228 		RemoveFromList();
229 		if (reference == 0)
230 		{
231 			delete this;
232 		}
233 	}
234 
Compare(XObject * o)235 	virtual int Compare(XObject * o) { return 1; }
Concat(XObject * o)236 	virtual void Concat(XObject * o)
237 	{
238 		assert(o->reference == 0);
239 		quantity += o->quantity;
240 		o->Invalidate();
241 	}
242 
GetClassName()243    virtual const char * GetClassName() { return "XObject"; }
244 
245    virtual void Dump(XFile * f);
246    static void DumpAll();
247 
248 	int quantity; //some objects can stacked to a bundle: "bundle of 23 arrow (1d4)"
249 	XGUID xguid; //all objects has global unique inditifer
250              //(it has no sense to store pointers)
251 	ITEM_MASK im; //many years ago it was item mask, now it is mask for all!
252 
isValid()253 	int isValid() { return is_valid; }
254 
255 // interface for store/restore functions
256 	virtual void Store(XFile * f);// = 0;
257 	virtual void Restore(XFile * f);// = 0;
258 
259 // Runable object...
260 // If It returns zero, than object must be removed from scheduler
Run()261 	virtual int Run() { return 1; }
262 	int ttm; //time to move
263 	int ttmb; //basis of time to move
264 
265 };
266 
267 template<class TYPE> class XPtr
268 {
269 	mutable XObject * p;
270 	void operator=(const XPtr<TYPE> &);
271 	XPtr(const XPtr<TYPE> &);
272 	TYPE * get_with_check() const;
273 public:
XPtr()274 	XPtr() : p(NULL) { }
XPtr(TYPE * _p)275 	XPtr(TYPE * _p) : p(_p) { if(p != NULL) p->AddRef(); }
276 	~XPtr();
277 
278 	bool operator==(XPtr<TYPE> & x) const { return operator TYPE * () == x.operator TYPE * (); }
279 
280 	void operator=(TYPE * _p);
281 
282 	operator TYPE * () const { return (p == NULL) ? NULL : get_with_check(); }
283 
get()284 	TYPE * get() const { return static_cast<TYPE *>(p); }
285 	TYPE * operator->() const { return static_cast<TYPE *>(p); }
286 
287 	void Store(XFile * f) const;
288 	void Restore(XFile * f);
289 };
290 
~XPtr()291 template<class TYPE> XPtr<TYPE>::~XPtr()
292 {
293 	if(p != NULL) p->Release();
294 }
295 
296 template<class TYPE> void XPtr<TYPE>::operator=(TYPE * _p)
297 {
298 	if(p == (XObject *)_p) return;
299 	if(p != NULL) p->Release();
300 	p = (XObject *)_p;
301 	if(p != NULL) p->AddRef();
302 }
303 
get_with_check()304 template<class TYPE> TYPE * XPtr<TYPE>::get_with_check() const
305 {
306    if(p->isValid()) return static_cast<TYPE *>(p);
307    p->Release();
308    p = NULL;
309    return NULL;
310 }
311 
Store(XFile * f)312 template<class TYPE> void XPtr<TYPE>::Store(XFile * f) const
313 {
314 	XObject::StorePointer(f, operator TYPE * ());
315 }
316 
Restore(XFile * f)317 template<class TYPE> void XPtr<TYPE>::Restore(XFile * f)
318 {
319    assert(p == NULL);
320    p = XObject::RestorePointer(f, this);
321    if (p != NULL) p->AddRef();
322    assert(p == NULL || dynamic_cast<TYPE *>(p));
323 }
324 
325 #endif
326