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