-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgenerate_lua_gui_element_wrappers.py
More file actions
612 lines (542 loc) · 25.5 KB
/
Copy pathgenerate_lua_gui_element_wrappers.py
File metadata and controls
612 lines (542 loc) · 25.5 KB
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
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
import os
import urllib.request, json
from pathlib import Path
API_JSON_URL = 'https://lua-api.factorio.com/latest/runtime-api.json'
API_JSON_PATH = Path('runtime-api.json')
WRAPPER_PATH = Path('src/GUI/Factorio/')
def get_named_array_element(json_array, name):
element = None
for api_class in json_array:
if api_class['name'] == name:
element = api_class
break
if element is None:
raise ValueError(f'{name} not found in array')
return element
def definition_getter(camel_case_subclass, attribute, delayed, read_only=False):
attribute_name = attribute['name']
return f'''function {camel_case_subclass}:get_{attribute_name}()
if self:get_state() == Component.State.Created then
return {'Helper.read_only(' if read_only else ''}self.lua_gui_element.{attribute_name}{')' if read_only else ''}
else
return {'Helper.read_only(' if read_only else ''}self.{'lua_gui_element_delayed_parameters' if delayed else 'lua_gui_element_parameters'}.{attribute_name}{')' if read_only else ''}
end
end'''
def definition_setter(camel_case_subclass, attribute, delayed):
attribute_name = attribute['name']
return f'''function {camel_case_subclass}:set_{attribute_name}({attribute_name})
if self:get_state() == Component.State.Created then
self.lua_gui_element.{attribute_name} = {attribute_name}
end
self.{'lua_gui_element_delayed_parameters' if delayed else 'lua_gui_element_parameters'}.{attribute_name} = {attribute_name}
end'''
def definition_method(camel_case_subclass, method):
method_name = method['name']
return f'''function {camel_case_subclass}:{method_name}(...)
assert(self:get_state() == Component.State.Created, 'LuaGuiElement methods can only be called after the component has been created')
{'return ' if len(method['return_values']) > 0 else ''}self.lua_gui_element.{method_name}(...)
end'''
def create_wrapper(camel_case_subclass, snake_case_subclass, dashed_snake_case_subclass,
parameters, attributes, methods,
application_version, api_version):
delayed_parameter_names = []
for attribute in attributes:
if attribute['write']:
delayed_parameter_names.append(attribute['name'])
for parameter in parameters:
if parameter['name'] in delayed_parameter_names:
delayed_parameter_names.remove(parameter['name'])
def requires():
return '''local Class = require('__poly__.Class')
local Component = require('__poly__.GUI.Component')
local FactorioComponent = require('__poly__.GUI.Factorio.FactorioComponent')'''
def declaration():
return f'''local {camel_case_subclass} = Class:new('Poly.GUI.{camel_case_subclass}', FactorioComponent)'''
def definition_new():
new = f'''function {camel_case_subclass}:new(args)
local {snake_case_subclass} = FactorioComponent:new(args)
{snake_case_subclass}.lua_gui_element_parameters.type = '{dashed_snake_case_subclass}'
'''
for parameter in parameters:
new += f'\n {snake_case_subclass}.lua_gui_element_parameters.{parameter["name"]} = args.{parameter["name"]}'
for parameter in delayed_parameter_names:
new += f'\n {snake_case_subclass}.lua_gui_element_delayed_parameters.{parameter} = args.{parameter}'
new += f'''
return {snake_case_subclass}
end'''
return new
def definition():
definition = definition_new()
for attribute in attributes:
first = True
if attribute['read'] and not attribute['name'] == 'style':
# style should not be read to be able to keep track of modifications
definition += ('\n\n' if first else '\n') + definition_getter(
camel_case_subclass, attribute, attribute['name'] in delayed_parameter_names
)
first = False
if attribute['write'] and not attribute['name'] == 'name':
# name cannot be changed after instantiation
definition += ('\n\n' if first else '\n') + definition_setter(
camel_case_subclass, attribute, attribute['name'] in delayed_parameter_names
)
first = False
for method in methods:
definition += '\n\n' + definition_method(camel_case_subclass, method)
return definition
return f'''-- Poly: generated for Factorio {application_version} runtime API {api_version}
{requires()}
{declaration()}
{definition()}
return {camel_case_subclass}
'''
# load API json
if not API_JSON_PATH.exists():
# download if not exists
with urllib.request.urlopen(API_JSON_URL) as url:
api_json = json.loads(url.read().decode())
# == fix inconsistencies ==
lua_gui_element_class = get_named_array_element(api_json['classes'], 'LuaGuiElement')
# -- camel case radiobutton subclass --
state_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'state')
assert 'RadioButton' in state_attribute['subclasses']
state_attribute['subclasses'].remove('RadioButton')
state_attribute['subclasses'].append('radiobutton')
# -- camel case checkbox subclass --
state_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'state')
assert 'CheckBox' in state_attribute['subclasses']
state_attribute['subclasses'].remove('CheckBox')
state_attribute['subclasses'].append('checkbox')
# -- missing subclasses for mouse_button_filter --
mouse_button_filter_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'mouse_button_filter')
assert 'subclasses' not in mouse_button_filter_attribute
mouse_button_filter_attribute['subclasses'] = ['button', 'sprite-button']
# -- missing subclasses for clicked_sprite --
clicked_sprite_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'clicked_sprite')
assert 'subclasses' not in clicked_sprite_attribute
clicked_sprite_attribute['subclasses'] = ['sprite-button']
# -- missing subclasses for entity --
entity_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'entity')
assert 'subclasses' not in entity_attribute
entity_attribute['subclasses'] = ['entity-preview', 'camera', 'minimap']
# -- missing subclasses for force --
force_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'force')
assert 'subclasses' not in force_attribute
force_attribute['subclasses'] = ['minimap']
# -- missing subclasses for items --
items_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'items')
assert 'subclasses' not in items_attribute
items_attribute['subclasses'] = ['drop-down', 'list-box']
# -- missing subclasses for number --
number_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'number')
assert 'subclasses' not in number_attribute
number_attribute['subclasses'] = ['sprite-button']
# -- missing subclasses for position --
position_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'position')
assert 'subclasses' not in position_attribute
position_attribute['subclasses'] = ['minimap']
# -- missing subclasses for resize_to_sprite --
resize_to_sprite_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'resize_to_sprite')
assert 'subclasses' not in resize_to_sprite_attribute
resize_to_sprite_attribute['subclasses'] = ['sprite']
# -- missing subclasses for selected_index --
selected_index_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'selected_index')
assert 'subclasses' not in selected_index_attribute
selected_index_attribute['subclasses'] = ['drop-down', 'list-box']
# -- missing subclasses for show_percent_for_small_numbers --
show_percent_for_small_numbers_attribute = get_named_array_element(lua_gui_element_class['attributes'],
'show_percent_for_small_numbers')
assert 'subclasses' not in show_percent_for_small_numbers_attribute
show_percent_for_small_numbers_attribute['subclasses'] = ['sprite-button']
# -- missing subclasses for sprite --
sprite_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'sprite')
assert 'subclasses' not in sprite_attribute
sprite_attribute['subclasses'] = ['sprite-button', 'sprite']
# -- missing subclasses for surface_index --
surface_index_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'surface_index')
assert 'subclasses' not in surface_index_attribute
surface_index_attribute['subclasses'] = ['camera', 'minimap']
# -- missing subclasses for tabs --
tabs_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'tabs')
assert 'subclasses' not in tabs_attribute
tabs_attribute['subclasses'] = ['tabbed-pane']
# -- missing subclasses for zoom --
zoom_attribute = get_named_array_element(lua_gui_element_class['attributes'], 'zoom')
assert 'subclasses' not in zoom_attribute
zoom_attribute['subclasses'] = ['camera', 'minimap']
# -- missing subclasses for add_item --
add_item_method = get_named_array_element(lua_gui_element_class['methods'], 'add_item')
assert 'subclasses' not in add_item_method
add_item_method['subclasses'] = ['drop-down', 'list-box']
# -- missing subclasses for clear_items --
clear_items_method = get_named_array_element(lua_gui_element_class['methods'], 'clear_items')
assert 'subclasses' not in clear_items_method
clear_items_method['subclasses'] = ['drop-down', 'list-box']
# -- missing subclasses for get_item --
get_item_method = get_named_array_element(lua_gui_element_class['methods'], 'get_item')
assert 'subclasses' not in get_item_method
get_item_method['subclasses'] = ['drop-down', 'list-box']
# -- missing subclasses for remove_item --
remove_item_method = get_named_array_element(lua_gui_element_class['methods'], 'remove_item')
assert 'subclasses' not in remove_item_method
remove_item_method['subclasses'] = ['drop-down', 'list-box']
# -- missing subclasses for set_item --
set_item_method = get_named_array_element(lua_gui_element_class['methods'], 'set_item')
assert 'subclasses' not in set_item_method
set_item_method['subclasses'] = ['drop-down', 'list-box']
# other inconsistencies:
# subclass 'sprite' is incorrectly called 'image' in resize_to_sprite's description
# cache API json in file
with open(API_JSON_PATH, 'w') as api_json_file:
json.dump(api_json, api_json_file)
else:
# load from file
with open(API_JSON_PATH, 'r') as api_json_file:
api_json = json.load(api_json_file)
# clear previous wrappers
for file in os.scandir(os.fspath(WRAPPER_PATH)):
if file.name != 'util.lua':
os.remove(os.fspath(file))
# get LuaGuiElement class
lua_gui_element_class = get_named_array_element(api_json['classes'], 'LuaGuiElement')
# parse wrapper relevant data
wrapper_data = {}
# get attributes
default_attribute_names = [
'anchor', 'caption', 'enabled', 'gui', 'ignored_by_interaction', 'index', 'location', 'object_name', 'parent',
'player_index', 'style', 'tags', 'tooltip', 'type', 'valid', 'visible'
]
default_attributes = []
for attribute in lua_gui_element_class['attributes']:
# parse subclasses
if 'subclasses' in attribute:
for subclass in attribute['subclasses']:
if subclass not in wrapper_data.keys():
wrapper_data[subclass] = {
'attributes': [],
'methods': [],
'parameters': []
}
wrapper_data[subclass]['attributes'].append(attribute)
elif attribute['name'] in default_attribute_names:
default_attributes.append(attribute)
else:
print(f'ignored attribute {str(attribute)}')
# get parameters
default_parameters = []
default_delayed_parameter_names = []
for attribute in default_attributes:
if attribute['write']:
default_delayed_parameter_names.append(attribute['name'])
for parameter in get_named_array_element(lua_gui_element_class['methods'], 'add')['parameters']:
if parameter['name'] in default_delayed_parameter_names:
default_delayed_parameter_names.remove(parameter['name'])
if parameter['name'] not in ['index', 'style', 'type']:
default_parameters.append(parameter)
for parameter_group in get_named_array_element(lua_gui_element_class['methods'], 'add')['variant_parameter_groups']:
subclass = parameter_group['name']
if subclass not in wrapper_data.keys():
wrapper_data[subclass] = {
'attributes': [],
'methods': [],
'parameters': []
}
for parameter in parameter_group['parameters']:
wrapper_data[subclass]['parameters'].append(parameter)
# get methods
default_method_names = ['bring_to_front', 'focus', 'get_mod', 'help']
default_methods = []
for method in lua_gui_element_class['methods']:
if 'subclasses' in method:
for subclass in method['subclasses']:
if subclass not in wrapper_data.keys():
wrapper_data[subclass] = {
'attributes': [],
'methods': [],
'parameters': []
}
wrapper_data[subclass]['methods'].append(method)
elif method['name'] in default_method_names:
default_methods.append(method)
else:
print(f'ignored method {str(method)}')
# TODO: fix implementation for add_item? Add items to state?
# TODO: fix slider attributes: get/set_slider_discrete_slider etc.
# create FactorioComponent
with open(WRAPPER_PATH / 'FactorioComponent.lua', 'w') as wrapper_file:
wrapper_file.write(f'''local Class = require('__poly__.Class')
local Helper = require('__poly__.Helper')
local Component = require('__poly__.GUI.Component')
local EventHandler = require('__poly__.GUI.EventHandler')
local FactorioComponent = Class:new('FactorioComponent', Component)
function FactorioComponent:new(args)
local factorio_component = Component:new(args)
factorio_component.lua_gui_element = nil
factorio_component.lua_gui_element_parameters = {{
{f',{chr(10)} '.join([f'{p["name"]} = args.{p["name"]}' for p in default_parameters])}
}}
factorio_component.lua_gui_element_delayed_parameters = {{
{f',{chr(10)} '.join([f'{p} = args.{p}' for p in default_delayed_parameter_names])}
}}
factorio_component.style = args.style
factorio_component.event_handler_ids = {{}}
factorio_component.delete_event_handler = args.delete_event_handler
if factorio_component.delete_event_handler == nil then
factorio_component.delete_event_handler = true
end
for _, event in ipairs {{ 'on_gui_checked_state_changed', 'on_gui_click', 'on_gui_closed', 'on_gui_confirmed',
'on_gui_elem_changed', 'on_gui_location_changed', 'on_gui_opened',
'on_gui_selected_tab_changed', 'on_gui_selection_state_changed',
'on_gui_switch_state_changed', 'on_gui_text_changed', 'on_gui_value_changed' }} do
local handler = args[event]
if handler ~= nil then
if factorio_component.lua_gui_element_parameters.tags == nil then
factorio_component.lua_gui_element_parameters.tags = {{}}
end
if factorio_component.lua_gui_element_parameters.tags.Poly == nil then
factorio_component.lua_gui_element_parameters.tags.Poly = {{}}
end
if type(handler) == 'string' then
factorio_component.lua_gui_element_parameters.tags.Poly[event] = handler
if factorio_component.delete_event_handler then
factorio_component.event_handler_ids[handler] = true
end
else
factorio_component.lua_gui_element_parameters.tags.Poly[event] = {{}}
for idx, id in ipairs(handler) do
factorio_component.lua_gui_element_parameters.tags.Poly[event][idx] = id
if factorio_component.delete_event_handler then
factorio_component.event_handler_ids[id] = true
end
end
end
end
end
return factorio_component
end
function FactorioComponent:create(parent)
self.lua_gui_element = parent.add(self.lua_gui_element_parameters)
if self.style ~= nil then
Helper.apply_style(self.lua_gui_element, self.style)
end
for k, v in pairs(self.lua_gui_element_delayed_parameters) do
self.lua_gui_element[k] = v
end
Component.create(self, self.lua_gui_element)
end
function FactorioComponent:destroy()
self.lua_gui_element.destroy()
Component.destroy(self)
end
function FactorioComponent:delete()
if self.delete_event_handler then
for event_handler_id, _ in ipairs(self.event_handler_ids) do
EventHandler:delete(event_handler_id)
end
end
Component.delete(self)
end
function FactorioComponent:set_style(style)
if self:get_state() == Component.State.Created then
Helper.apply_style(self.lua_gui_element, style)
end
if type(style) == 'string' then
self.style = style
elseif type(style) == 'table' then
if style[1] ~= nil then
self.style = style
else
if self.style == nil then
self.style = {{}}
elseif type(self.style) == 'string' then
self.style = {{ [1] = self.style }}
end
for k, v in pairs(style) do
if k ~= 1 then
self.style[k] = v
end
end
end
end
end
function FactorioComponent:get_tags()
if self:get_state() == Component.State.Created then
return Helper.deep_copy(self.lua_gui_element.tags)
else
return Helper.deep_copy(self.lua_gui_element_parameters.tags)
end
end
function FactorioComponent:set_tags(tags)
if #self.event_handler_ids > 0 then
if tags.Poly == nil then
tags.Poly = {{}}
end
for event, handlers in pairs(self.lua_gui_element_parameters.tags.Poly) do
if type(handlers) == 'string' then
handlers = {{ handlers }}
end
for _, handler in ipairs(handlers) do
if self.event_handler_ids[handler] then
if tags.Poly[event] == nil then
tags.Poly[event] = handler
elseif type(tags.Poly[event]) == 'string' then
tags.Poly[event] = {{ tags.Poly[event], handler }}
else
tags.Poly[event][#tags.Poly[event] + 1] = handler
end
end
end
end
end
if self:get_state() == Component.State.Created then
self.lua_gui_element.tags = tags
end
self.lua_gui_element_parameters.tags = tags
end
function FactorioComponent:update_tags(tags)
if tags == nil then
return
end
if self.lua_gui_element_parameters.tags == nil then
self:set_tags(tags)
end
local function merge(orig_tags, new_tags)
for k, v in pairs(new_tags) do
if orig_tags[k] == nil then
orig_tags[k] = v
elseif type(orig_tags[k]) == 'table' then
merge(orig_tags[k], v)
else
orig_tags[k] = v
end
end
end
merge(self.lua_gui_element_parameters.tags, tags)
if self:get_state() == Component.State.Created then
self.lua_gui_element.tags = self.lua_gui_element_parameters.tags
end
end
function FactorioComponent:delete_tags(tags)
if tags == nil or self.lua_gui_element_parameters.tags == nil then
return
end
local function delete(orig_tags, delete_tags)
for k, v in pairs(delete_tags) do
if orig_tags[k] ~= nil then
if type(orig_tags[k]) == 'table' then
delete(orig_tags[k], v)
if next(orig_tags[k]) == nil then
orig_tags[k] = nil
end
else
orig_tags[k] = nil
end
end
end
end
delete(self.lua_gui_element_parameters.tags, tags)
if next(self.lua_gui_element_parameters.tags) == nil then
self.lua_gui_element_parameters.tags = nil
end
if self:get_state() == Component.State.Created then
self.lua_gui_element.tags = self.lua_gui_element_parameters.tags
end
end
local function add_event_handler(self, event, event_handler)
if self.lua_gui_element_parameters.tags == nil then
self.lua_gui_element_parameters.tags = {{}}
end
if self.lua_gui_element_parameters.tags.Poly == nil then
self.lua_gui_element_parameters.tags.Poly = {{}}
end
if type(event_handler) == 'string' then
if self.lua_gui_element_parameters.tags.Poly[event] == nil then
self.lua_gui_element_parameters.tags.Poly[event] = event_handler
elseif type(self.lua_gui_element_parameters.tags.Poly[event]) == 'string' then
self.lua_gui_element_parameters.tags.Poly[event] = {{
self.lua_gui_element_parameters.tags.Poly[event],
event_handler
}}
else
self.lua_gui_element_parameters.tags.Poly[event][#self.lua_gui_element_parameters.tags.Poly[event] + 1] = event_handler
end
if self.delete_event_handler then
self.event_handler_ids[event_handler] = true
end
else
if self.lua_gui_element_parameters.tags.Poly[event] == nil then
self.lua_gui_element_parameters.tags.Poly[event] = {{}}
elseif type(self.lua_gui_element_parameters.tags.Poly[event]) == 'string' then
self.lua_gui_element_parameters.tags.Poly[event] = {{ self.lua_gui_element_parameters.tags.Poly[event] }}
end
local num_handlers = #self.lua_gui_element_parameters.tags.Poly[event]
for idx, id in ipairs(event_handler) do
self.lua_gui_element_parameters.tags.Poly[event][num_handlers + idx] = id
if self.delete_event_handler then
self.event_handler_ids[id] = true
end
end
end
if self:get_state() == Component.State.Created then
self.lua_gui_element.tags = self.lua_gui_element_parameters.tags
end
end
''')
for event in ['on_gui_checked_state_changed', 'on_gui_click', 'on_gui_closed', 'on_gui_confirmed',
'on_gui_elem_changed', 'on_gui_location_changed', 'on_gui_opened', 'on_gui_selected_tab_changed',
'on_gui_selection_state_changed', 'on_gui_switch_state_changed', 'on_gui_text_changed',
'on_gui_value_changed']:
wrapper_file.write(f'''
function FactorioComponent:add_{event}(event_handler)
add_event_handler(self, '{event}', event_handler)
end''')
for attribute in default_attributes:
first = True
if attribute['read']:
if attribute['name'] in ['style']:
# skip some getters
continue
wrapper_file.write(('\n\n' if first else '\n') + definition_getter(
'FactorioComponent', attribute, attribute['name'] in default_delayed_parameter_names
))
first = False
if attribute['write']:
if attribute['name'] in ['name', 'style', 'tags']:
# skip some setters
continue
wrapper_file.write(('\n\n' if first else '\n') + definition_setter(
'FactorioComponent', attribute, attribute['name'] in default_delayed_parameter_names
))
first = False
for method in default_methods:
wrapper_file.write('\n\n' + definition_method('FactorioComponent', method))
wrapper_file.write('\n\nreturn FactorioComponent')
# create type wrappers
for subclass, data in wrapper_data.items():
# format subclass name
camel_case_subclass = subclass
if subclass[0] == subclass[0].lower():
# capitalize first letter
camel_case_subclass = camel_case_subclass[0].upper() + camel_case_subclass[1:]
# remove dashes and capitalize following letters
for i in range(len(camel_case_subclass) - 1, -1, -1):
if camel_case_subclass[i] == '-':
camel_case_subclass = camel_case_subclass[:i] + camel_case_subclass[
i + 1].upper() + camel_case_subclass[i + 2:]
snake_case_subclass = camel_case_subclass[0].lower() + camel_case_subclass[1:]
# insert underscore before uppercase letters and make them lowercase
i = 1
while i < len(snake_case_subclass):
if snake_case_subclass[i] == snake_case_subclass[i].upper():
snake_case_subclass = snake_case_subclass[:i] + '_' + snake_case_subclass[i].lower() + snake_case_subclass[
i + 1:]
i += 1 # skip inserted underscore
i += 1
dashed_snake_case_subclass = snake_case_subclass.replace('_', '-')
# create wrapper file
with open(WRAPPER_PATH / (camel_case_subclass + '.lua'), 'w') as wrapper_file:
wrapper_file.write(create_wrapper(camel_case_subclass, snake_case_subclass, dashed_snake_case_subclass,
data['parameters'],
data['attributes'],
data['methods'],
api_json['application_version'], api_json['api_version']))