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