Welcome to mirror list, hosted at ThFree Co, Russian Federation.

scriptdictionary.h « scriptdictionary « add_on « angelscript « Scripting « Source - github.com/WolfireGames/overgrowth.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 38649b1a2539086192c3b349ec2dd7e5942eb91f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
#ifndef SCRIPTDICTIONARY_H
#define SCRIPTDICTIONARY_H

// The dictionary class relies on the script string object, thus the script
// string type must be registered with the engine before registering the
// dictionary type

#ifndef ANGELSCRIPT_H
// Avoid having to inform include path if header is already include before
#include <angelscript.h>
#endif

// By default the CScriptDictionary use the std::string for the keys.
// If the application uses a custom string type, then this typedef
// can be changed accordingly. Remember, if the application uses
// a ref counted string type, then further changes will be needed,
// for example in the code for GetKeys() and the constructor that
// takes an initialization list.
#include <string>
typedef std::string dictKey_t;

// Forward declare CScriptDictValue so we can typedef the internal map type
BEGIN_AS_NAMESPACE
class CScriptDictValue;
END_AS_NAMESPACE

// C++11 introduced the std::unordered_map which is a hash map which is
// is generally more performatic for lookups than the std::map which is a
// binary tree.
// TODO: memory: The map allocator should use the asAllocMem and asFreeMem
#if AS_CAN_USE_CPP11
#include <unordered_map>
typedef std::unordered_map<dictKey_t, AS_NAMESPACE_QUALIFIER CScriptDictValue> dictMap_t;
#else
#include <map>
typedef std::map<dictKey_t, AS_NAMESPACE_QUALIFIER CScriptDictValue> dictMap_t;
#endif

#ifdef _MSC_VER
// Turn off annoying warnings about truncated symbol names
#pragma warning(disable : 4786)
#endif

// Sometimes it may be desired to use the same method names as used by C++ STL.
// This may for example reduce time when converting code from script to C++ or
// back.
//
//  0 = off
//  1 = on

#ifndef AS_USE_STLNAMES
#define AS_USE_STLNAMES 0
#endif

BEGIN_AS_NAMESPACE

class CScriptArray;
class CScriptDictionary;

class CScriptDictValue {
   public:
    // This class must not be declared as local variable in C++, because it needs
    // to receive the script engine pointer in all operations. The engine pointer
    // is not kept as member in order to keep the size down
    CScriptDictValue();
    CScriptDictValue(asIScriptEngine *engine, void *value, int typeId);

    // Destructor must not be called without first calling FreeValue, otherwise a memory leak will occur
    ~CScriptDictValue();

    // Replace the stored value
    void Set(asIScriptEngine *engine, void *value, int typeId);
    void Set(asIScriptEngine *engine, const asINT64 &value);
    void Set(asIScriptEngine *engine, const double &value);
    void Set(asIScriptEngine *engine, CScriptDictValue &value);

    // Gets the stored value. Returns false if the value isn't compatible with the informed typeId
    bool Get(asIScriptEngine *engine, void *value, int typeId) const;
    bool Get(asIScriptEngine *engine, asINT64 &value) const;
    bool Get(asIScriptEngine *engine, double &value) const;

    // Returns the address of the stored value for inspection
    const void *GetAddressOfValue() const;

    // Returns the type id of the stored value
    int GetTypeId() const;

    // Free the stored value
    void FreeValue(asIScriptEngine *engine);

   protected:
    friend class CScriptDictionary;

    union {
        asINT64 m_valueInt;
        double m_valueFlt;
        void *m_valueObj;
    };
    int m_typeId;
};

class CScriptDictionary {
   public:
    // Factory functions
    static CScriptDictionary *Create(asIScriptEngine *engine);

    // Called from the script to instantiate a dictionary from an initialization list
    static CScriptDictionary *Create(asBYTE *buffer);

    // Reference counting
    void AddRef() const;
    void Release() const;

    // Reassign the dictionary
    CScriptDictionary &operator=(const CScriptDictionary &other);

    // Sets a key/value pair
    void Set(const dictKey_t &key, void *value, int typeId);
    void Set(const dictKey_t &key, const asINT64 &value);
    void Set(const dictKey_t &key, const double &value);

    // Gets the stored value. Returns false if the value isn't compatible with the informed typeId
    bool Get(const dictKey_t &key, void *value, int typeId) const;
    bool Get(const dictKey_t &key, asINT64 &value) const;
    bool Get(const dictKey_t &key, double &value) const;

    // Index accessors. If the dictionary is not const it inserts the value if it doesn't already exist
    // If the dictionary is const then a script exception is set if it doesn't exist and a null pointer is returned
    CScriptDictValue *operator[](const dictKey_t &key);
    const CScriptDictValue *operator[](const dictKey_t &key) const;

    // Returns the type id of the stored value, or negative if it doesn't exist
    int GetTypeId(const dictKey_t &key) const;

    // Returns true if the key is set
    bool Exists(const dictKey_t &key) const;

    // Returns true if there are no key/value pairs in the dictionary
    bool IsEmpty() const;

    // Returns the number of key/value pairs in the dictionary
    asUINT GetSize() const;

    // Deletes the key
    bool Delete(const dictKey_t &key);

    // Deletes all keys
    void DeleteAll();

    // Get an array of all keys
    CScriptArray *GetKeys() const;

    // STL style iterator
    class CIterator {
       public:
        void operator++();     // Pre-increment
        void operator++(int);  // Post-increment

        // This is needed to support C++11 range-for
        CIterator &operator*();

        bool operator==(const CIterator &other) const;
        bool operator!=(const CIterator &other) const;

        // Accessors
        const dictKey_t &GetKey() const;
        int GetTypeId() const;
        bool GetValue(asINT64 &value) const;
        bool GetValue(double &value) const;
        bool GetValue(void *value, int typeId) const;
        const void *GetAddressOfValue() const;

       protected:
        friend class CScriptDictionary;

        CIterator();
        CIterator(const CScriptDictionary &dict,
                  dictMap_t::const_iterator it);

        CIterator &operator=(const CIterator &) { return *this; }  // Not used

        dictMap_t::const_iterator m_it;
        const CScriptDictionary &m_dict;
    };

    CIterator begin() const;
    CIterator end() const;
    CIterator find(const dictKey_t &key) const;

    // Garbage collections behaviours
    int GetRefCount();
    void SetGCFlag();
    bool GetGCFlag();
    void EnumReferences(asIScriptEngine *engine);
    void ReleaseAllReferences(asIScriptEngine *engine);

   protected:
    // Since the dictionary uses the asAllocMem and asFreeMem functions to allocate memory
    // the constructors are made protected so that the application cannot allocate it
    // manually in a different way
    CScriptDictionary(asIScriptEngine *engine);
    CScriptDictionary(asBYTE *buffer);

    // We don't want anyone to call the destructor directly, it should be called through the Release method
    virtual ~CScriptDictionary();

    // Cache the object types needed
    void Init(asIScriptEngine *engine);

    // Our properties
    asIScriptEngine *engine;
    mutable int refCount;
    mutable bool gcFlag;
    dictMap_t dict;
};

// This function will determine the configuration of the engine
// and use one of the two functions below to register the dictionary object
void RegisterScriptDictionary(asIScriptEngine *engine);

// Call this function to register the math functions
// using native calling conventions
void RegisterScriptDictionary_Native(asIScriptEngine *engine);

// Use this one instead if native calling conventions
// are not supported on the target platform
void RegisterScriptDictionary_Generic(asIScriptEngine *engine);

END_AS_NAMESPACE

#endif