1 /*
2 AngelCode Scripting Library
3 Copyright (c) 2003-2017 Andreas Jonsson
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any
7 damages arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any
10 purpose, including commercial applications, and to alter it and
11 redistribute it freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you
14 must not claim that you wrote the original software. If you use
15 this software in a product, an acknowledgment in the product
16 documentation would be appreciated but is not required.
17
18 2. Altered source versions must be plainly marked as such, and
19 must not be misrepresented as being the original software.
20
21 3. This notice may not be removed or altered from any source
22 distribution.
23
24 The original version of this library can be located at:
25 http://www.angelcode.com/angelscript/
26
27 Andreas Jonsson
28 andreas@angelcode.com
29 */
30
31
32 //
33 // as_configgroup.cpp
34 //
35 // This class holds configuration groups for the engine
36 //
37
38
39
40 #include "as_config.h"
41 #include "as_configgroup.h"
42 #include "as_scriptengine.h"
43 #include "as_texts.h"
44
45 BEGIN_AS_NAMESPACE
46
asCConfigGroup()47 asCConfigGroup::asCConfigGroup()
48 {
49 refCount = 0;
50 }
51
~asCConfigGroup()52 asCConfigGroup::~asCConfigGroup()
53 {
54 }
55
AddRef()56 int asCConfigGroup::AddRef()
57 {
58 refCount++;
59 return refCount;
60 }
61
Release()62 int asCConfigGroup::Release()
63 {
64 // Don't delete the object here, the engine will delete the object when ready
65 refCount--;
66 return refCount;
67 }
68
FindType(const char * obj)69 asCTypeInfo *asCConfigGroup::FindType(const char *obj)
70 {
71 for( asUINT n = 0; n < types.GetLength(); n++ )
72 if( types[n]->name == obj )
73 return types[n];
74
75 return 0;
76 }
77
RefConfigGroup(asCConfigGroup * group)78 void asCConfigGroup::RefConfigGroup(asCConfigGroup *group)
79 {
80 if( group == this || group == 0 ) return;
81
82 // Verify if the group is already referenced
83 for( asUINT n = 0; n < referencedConfigGroups.GetLength(); n++ )
84 if( referencedConfigGroups[n] == group )
85 return;
86
87 referencedConfigGroups.PushLast(group);
88 group->AddRef();
89 }
90
AddReferencesForFunc(asCScriptEngine * engine,asCScriptFunction * func)91 void asCConfigGroup::AddReferencesForFunc(asCScriptEngine *engine, asCScriptFunction *func)
92 {
93 AddReferencesForType(engine, func->returnType.GetTypeInfo());
94 for( asUINT n = 0; n < func->parameterTypes.GetLength(); n++ )
95 AddReferencesForType(engine, func->parameterTypes[n].GetTypeInfo());
96 }
97
AddReferencesForType(asCScriptEngine * engine,asCTypeInfo * type)98 void asCConfigGroup::AddReferencesForType(asCScriptEngine *engine, asCTypeInfo *type)
99 {
100 if( type == 0 ) return;
101
102 // Keep reference to other groups
103 RefConfigGroup(engine->FindConfigGroupForTypeInfo(type));
104
105 // Keep track of which generated template instances the config group uses
106 if( type->flags & asOBJ_TEMPLATE && engine->generatedTemplateTypes.Exists(CastToObjectType(type)) && !generatedTemplateInstances.Exists(CastToObjectType(type)) )
107 generatedTemplateInstances.PushLast(CastToObjectType(type));
108 }
109
HasLiveObjects()110 bool asCConfigGroup::HasLiveObjects()
111 {
112 for( asUINT n = 0; n < types.GetLength(); n++ )
113 if( types[n]->externalRefCount.get() != 0 )
114 return true;
115
116 return false;
117 }
118
RemoveConfiguration(asCScriptEngine * engine,bool notUsed)119 void asCConfigGroup::RemoveConfiguration(asCScriptEngine *engine, bool notUsed)
120 {
121 asASSERT( refCount == 0 );
122
123 asUINT n;
124
125 // Remove global variables
126 for( n = 0; n < globalProps.GetLength(); n++ )
127 {
128 int index = engine->registeredGlobalProps.GetIndex(globalProps[n]);
129 if( index >= 0 )
130 {
131 globalProps[n]->Release();
132
133 // TODO: global: Should compact the registeredGlobalProps array
134 engine->registeredGlobalProps.Erase(index);
135 }
136 }
137 globalProps.SetLength(0);
138
139 // Remove global functions
140 for( n = 0; n < scriptFunctions.GetLength(); n++ )
141 {
142 int index = engine->registeredGlobalFuncs.GetIndex(scriptFunctions[n]);
143 if( index >= 0 )
144 engine->registeredGlobalFuncs.Erase(index);
145 scriptFunctions[n]->ReleaseInternal();
146 }
147 scriptFunctions.SetLength(0);
148
149 // Remove behaviours and members of object types
150 for( n = 0; n < types.GetLength(); n++ )
151 {
152 asCObjectType *obj = CastToObjectType(types[n]);
153 if( obj )
154 obj->ReleaseAllFunctions();
155 }
156
157 // Remove object types (skip this if it is possible other groups are still using the types)
158 if( !notUsed )
159 {
160 for( n = asUINT(types.GetLength()); n-- > 0; )
161 {
162 asCTypeInfo *t = types[n];
163 asSMapNode<asSNameSpaceNamePair, asCTypeInfo*> *cursor;
164 if( engine->allRegisteredTypes.MoveTo(&cursor, asSNameSpaceNamePair(t->nameSpace, t->name)) &&
165 cursor->value == t )
166 {
167 engine->allRegisteredTypes.Erase(cursor);
168
169 if( engine->defaultArrayObjectType == t )
170 engine->defaultArrayObjectType = 0;
171
172 if( t->flags & asOBJ_TYPEDEF )
173 engine->registeredTypeDefs.RemoveValue(CastToTypedefType(t));
174 else if( t->flags & asOBJ_ENUM )
175 engine->registeredEnums.RemoveValue(CastToEnumType(t));
176 else if (t->flags & asOBJ_TEMPLATE)
177 engine->registeredTemplateTypes.RemoveValue(CastToObjectType(t));
178 else if (t->flags & asOBJ_FUNCDEF)
179 {
180 engine->registeredFuncDefs.RemoveValue(CastToFuncdefType(t));
181 engine->RemoveFuncdef(CastToFuncdefType(t));
182 }
183 else
184 engine->registeredObjTypes.RemoveValue(CastToObjectType(t));
185
186 t->DestroyInternal();
187 t->ReleaseInternal();
188 }
189 else
190 {
191 int idx = engine->templateInstanceTypes.IndexOf(CastToObjectType(t));
192 if( idx >= 0 )
193 {
194 engine->templateInstanceTypes.RemoveIndexUnordered(idx);
195 asCObjectType *ot = CastToObjectType(t);
196 ot->DestroyInternal();
197 ot->ReleaseInternal();
198 }
199 }
200 }
201 types.SetLength(0);
202 }
203
204 // Release other config groups
205 for( n = 0; n < referencedConfigGroups.GetLength(); n++ )
206 referencedConfigGroups[n]->refCount--;
207 referencedConfigGroups.SetLength(0);
208 }
209
210 END_AS_NAMESPACE
211