200 | function TypeManager:addSpecialization(typeName, specName) |
201 | local typeEntry = self.types[typeName] |
202 | if typeEntry ~= nil then |
203 | if typeEntry.specializationsByName[specName] == nil then |
204 | local spec = self.specializationManager:getSpecializationObjectByName(specName) |
205 | if spec == nil then |
206 | Logging.error("%s type '%s' has unknown specialization '%s!", self.typeName, tostring(typeName), tostring(specName)) |
207 | return false |
208 | end |
209 | |
210 | table.insert(typeEntry.specializations, spec) |
211 | table.insert(typeEntry.specializationNames, specName) |
212 | typeEntry.specializationsByName[specName] = spec |
213 | else |
214 | Logging.error("Specialization '%s' already exists for %s type '%s'!", specName, self.typeName, typeName) |
215 | end |
216 | else |
217 | Logging.error("%s type '%s' is not defined!", self.typeName, typeName) |
218 | end |
219 | end |
73 | function TypeManager:addType(typeName, className, filename, customEnvironment, parent) |
74 | |
75 | if self.types[typeName] ~= nil then |
76 | Logging.error("Multiple specifications of %s type '%s'", self.typeName, typeName) |
77 | return false |
78 | elseif className == nil then |
79 | Logging.error("No className specified for %s type '%s'", self.typeName, typeName) |
80 | return false |
81 | elseif filename == nil then |
82 | Logging.error("No filename specified for %s type '%s'", self.typeName, typeName) |
83 | return false |
84 | else |
85 | customEnvironment = customEnvironment or "" |
86 | source(filename, customEnvironment) |
87 | |
88 | local typeEntry = {} |
89 | typeEntry.name = typeName |
90 | typeEntry.className = className |
91 | typeEntry.filename = filename |
92 | typeEntry.specializations = {} |
93 | typeEntry.specializationNames = {} |
94 | typeEntry.specializationsByName = {} |
95 | typeEntry.functions = {} |
96 | typeEntry.events = {} |
97 | typeEntry.eventListeners = {} |
98 | typeEntry.customEnvironment = customEnvironment |
99 | typeEntry.parent = parent |
100 | |
101 | self.types[typeName] = typeEntry |
102 | end |
103 | |
104 | return true |
105 | end |
239 | function TypeManager:finalizeTypes() |
240 | for typeName, typeEntry in pairs(self.types) do |
241 | g_asyncTaskManager:addSubtask(function() |
242 | local classObject = ClassUtil.getClassObject(typeEntry.className) |
243 | if classObject.registerEvents ~= nil then |
244 | classObject.registerEvents(typeEntry) |
245 | end |
246 | |
247 | if classObject.registerFunctions ~= nil then |
248 | classObject.registerFunctions(typeEntry) |
249 | end |
250 | |
251 | -- register events, functions, and overwritten functions for all specializations |
252 | for _,specialization in ipairs(typeEntry.specializations) do |
253 | if specialization.registerEvents ~= nil then |
254 | specialization.registerEvents(typeEntry) |
255 | end |
256 | end |
257 | |
258 | for _,specialization in ipairs(typeEntry.specializations) do |
259 | if specialization.registerFunctions ~= nil then |
260 | specialization.registerFunctions(typeEntry) |
261 | end |
262 | end |
263 | |
264 | for _,specialization in ipairs(typeEntry.specializations) do |
265 | if specialization.registerOverwrittenFunctions ~= nil then |
266 | specialization.registerOverwrittenFunctions(typeEntry) |
267 | end |
268 | end |
269 | |
270 | for _,specialization in ipairs(typeEntry.specializations) do |
271 | if specialization.registerEventListeners ~= nil then |
272 | specialization.registerEventListeners(typeEntry) |
273 | end |
274 | end |
275 | |
276 | if typeEntry.customEnvironment ~= "" then |
277 | print(string.format(" Register %s type: %s", self.typeName, typeName)) |
278 | end |
279 | end) |
280 | end |
281 | |
282 | return true |
283 | end |
32 | function TypeManager:loadMapData() |
33 | local xmlFile = loadXMLFile("typesXML", self.xmlFilename) |
34 | |
35 | local i = 0 |
36 | while true do |
37 | local key = string.format("%s.type(%d)", self.rootElementName, i) |
38 | if not hasXMLProperty(xmlFile, key) then |
39 | break |
40 | end |
41 | |
42 | g_asyncTaskManager:addSubtask(function() |
43 | self:loadTypeFromXML(xmlFile, key, nil, nil, nil) |
44 | end) |
45 | |
46 | i = i + 1 |
47 | end |
48 | |
49 | g_asyncTaskManager:addSubtask(function() |
50 | delete(xmlFile) |
51 | end) |
52 | |
53 | g_asyncTaskManager:addSubtask(function() |
54 | print(" Loaded " .. self.typeName .. " types") |
55 | end) |
56 | |
57 | return true |
58 | end |
109 | function TypeManager:loadTypeFromXML(xmlFile, key, isDLC, modDir, modName) |
110 | local typeName = getXMLString(xmlFile, key.. "#name") |
111 | local parentName = getXMLString(xmlFile, key.. "#parent") |
112 | |
113 | if typeName == nil and parentName == nil then |
114 | Logging.error("Missing name or parent for placeableType '%s'", key) |
115 | return false |
116 | end |
117 | |
118 | local parent |
119 | if parentName ~= nil then |
120 | parent = self.types[parentName] |
121 | if parent == nil then |
122 | Logging.error("Parent %s type '%s' is not defined!", self.typeName, parentName) |
123 | return false |
124 | end |
125 | end |
126 | |
127 | local className = getXMLString(xmlFile, key.. "#className") |
128 | local filename = getXMLString(xmlFile, key.. "#filename") |
129 | if parent ~= nil then |
130 | className = className or parent.className |
131 | filename = filename or parent.filename |
132 | end |
133 | |
134 | if modName ~= nil and modName ~= "" then |
135 | typeName = modName.."."..typeName |
136 | end |
137 | |
138 | if className ~= nil and filename ~= nil then |
139 | local customEnvironment = nil |
140 | if modDir ~= nil then |
141 | local useModDirectory |
142 | filename, useModDirectory = Utils.getFilename(filename, modDir) |
143 | if useModDirectory then |
144 | customEnvironment = modName |
145 | className = modName.."."..className |
146 | end |
147 | end |
148 | |
149 | if Platform.allowsScriptMods or isDLC or customEnvironment == nil then |
150 | self:addType(typeName, className, filename, customEnvironment, parent) |
151 | |
152 | -- add parent specializations |
153 | if parent ~= nil then |
154 | for _, specName in ipairs(parent.specializationNames) do |
155 | self:addSpecialization(typeName, specName) |
156 | end |
157 | end |
158 | |
159 | -- add type specializations |
160 | local j = 0 |
161 | while true do |
162 | local specKey = string.format("%s.specialization(%d)", key, j) |
163 | if not hasXMLProperty(xmlFile, specKey) then |
164 | break |
165 | end |
166 | |
167 | local specName = getXMLString(xmlFile, specKey.. "#name") |
168 | local entry = self.specializationManager:getSpecializationByName(specName) |
169 | if entry == nil then |
170 | if modName ~= nil then |
171 | specName = modName.."."..specName |
172 | end |
173 | |
174 | entry = self.specializationManager:getSpecializationByName(specName) |
175 | if entry == nil then |
176 | Logging.error("Could not find specialization '%s' for %s type '%s'.", specName, self.typeName, typeName) |
177 | specName = nil |
178 | end |
179 | end |
180 | |
181 | if specName ~= nil then |
182 | self:addSpecialization(typeName, specName) |
183 | end |
184 | |
185 | j = j + 1 |
186 | end |
187 | |
188 | return true |
189 | |
190 | else |
191 | Logging.error("Can't register %s type '%s' with scripts on consoles.", self.typeName, typeName) |
192 | end |
193 | end |
194 | |
195 | return false |
196 | end |
223 | function TypeManager:validateTypes() |
224 | for typeName, typeEntry in pairs(self.types) do |
225 | g_asyncTaskManager:addSubtask(function() |
226 | for _, specName in ipairs(typeEntry.specializationNames) do |
227 | local spec = typeEntry.specializationsByName[specName] |
228 | if not spec.prerequisitesPresent(typeEntry.specializations) then |
229 | Logging.error("Not all prerequisites of specialization '%s' in %s type '%s' are fulfilled", specName, self.typeName, typeName) |
230 | self:removeType(typeName) |
231 | end |
232 | end |
233 | end) |
234 | end |
235 | end |