- More work on scripting interface
[supertux.git] / src / squirrel / squirrel / sqtable.h
1 /*      see copyright notice in squirrel.h */\r
2 #ifndef _SQTABLE_H_\r
3 #define _SQTABLE_H_\r
4 /*\r
5 * The following code is based on Lua 4.0 (Copyright 1994-2002 Tecgraf, PUC-Rio.)\r
6 * http://www.lua.org/copyright.html#4\r
7 * http://www.lua.org/source/4.0.1/src_ltable.c.html\r
8 */\r
9 \r
10 #include "sqstring.h"\r
11 \r
12 #define hashptr(p)  (((unsigned long)(p)) >> 3)\r
13 \r
14 struct SQTable : public SQDelegable \r
15 {\r
16 private:\r
17         struct _HashNode\r
18         {\r
19                 SQObjectPtr val;\r
20                 SQObjectPtr key;\r
21                 _HashNode *next;\r
22         };\r
23         _HashNode *_firstfree;\r
24         _HashNode *_nodes;\r
25         int _numofnodes;\r
26         int _usednodes;\r
27         \r
28 ///////////////////////////\r
29         void AllocNodes(int nSize);\r
30         void Rehash(bool force);\r
31         SQTable(SQSharedState *ss, int nInitialSize);\r
32 public:\r
33         static SQTable* Create(SQSharedState *ss,int nInitialSize)\r
34         {\r
35                 SQTable *newtable = (SQTable*)SQ_MALLOC(sizeof(SQTable));\r
36                 new (newtable) SQTable(ss, nInitialSize);\r
37                 newtable->_delegate = NULL;\r
38                 return newtable;\r
39         }\r
40         void Finalize();\r
41         SQTable *Clone();\r
42         ~SQTable()\r
43         {\r
44                 SetDelegate(NULL);\r
45                 REMOVE_FROM_CHAIN(&_sharedstate->_gc_chain, this);\r
46                 for (int i = 0; i < _numofnodes; i++) _nodes[i].~_HashNode();\r
47                 SQ_FREE(_nodes, _numofnodes * sizeof(_HashNode));\r
48         }\r
49 #ifndef NO_GARBAGE_COLLECTOR \r
50         void Mark(SQCollectable **chain);\r
51 #endif\r
52         inline unsigned long HashKey(const SQObjectPtr &key)\r
53         {\r
54                 switch(type(key)){\r
55                         case OT_STRING:         return _string(key)->_hash;\r
56                         case OT_FLOAT:          return (unsigned long)((long)_float(key));\r
57                         case OT_INTEGER:        return (unsigned long)((long)_integer(key));\r
58                         default:                        return hashptr(key._unVal.pRefCounted);\r
59                 }\r
60         }\r
61         _HashNode *_Get(const SQObjectPtr &key,unsigned long hash)\r
62         {\r
63                 _HashNode *n = &_nodes[hash];\r
64                 do{\r
65                         if(_rawval(n->key) == _rawval(key) && type(n->key) == type(key)){\r
66                                 return n;\r
67                         }\r
68                 }while(n = n->next);\r
69                 return NULL;\r
70         }\r
71         bool Get(const SQObjectPtr &key,SQObjectPtr &val);\r
72         void Remove(const SQObjectPtr &key);\r
73         bool Set(const SQObjectPtr &key, const SQObjectPtr &val);\r
74         //returns true if a new slot has been created false if it was already present\r
75         bool NewSlot(const SQObjectPtr &key,const SQObjectPtr &val);\r
76         int Next(const SQObjectPtr &refpos, SQObjectPtr &outkey, SQObjectPtr &outval);\r
77         \r
78         int CountUsed();\r
79         void Release()\r
80         {\r
81                 sq_delete(this, SQTable);\r
82         }\r
83         bool SetDelegate(SQTable *mt);\r
84         \r
85 \r
86 };\r
87 \r
88 #endif //_SQTABLE_H_\r