Skip to content

Commit

Permalink
Also generate code for widget classes
Browse files Browse the repository at this point in the history
  • Loading branch information
texus committed May 5, 2024
1 parent 22aaa13 commit f9c713e
Show file tree
Hide file tree
Showing 220 changed files with 7,033 additions and 6,957 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ jobs:
- name: Lookup TGUI version for cache
id: find-dependencies
shell: bash
run: |
echo "tgui-revision=$(git ls-remote $TGUI_GITHUB_URL HEAD | cut -f1)" >> $GITHUB_OUTPUT
Expand Down Expand Up @@ -233,6 +234,7 @@ jobs:
- name: Lookup TGUI version for cache
id: find-dependencies
shell: bash
run: |
echo "tgui-revision=$(git ls-remote $TGUI_GITHUB_URL HEAD | cut -f1)" >> $GITHUB_OUTPUT
Expand Down
90 changes: 89 additions & 1 deletion code-generator/FileParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ class Segment:
def __init__(self):
self.documentation = None

class SegmentAbstractClass:
pass

class SegmentInherits(Segment):
def __init__(self, parentName):
self.parentName = parentName
Expand All @@ -39,12 +42,26 @@ class SegmentProperty(Segment):
def __init__(self, propertyType, propertyName):
self.type = propertyType
self.name = propertyName
self.getterUsesIsPrefix = False

class SegmentPropertyWidgetRenderer(Segment):
def __init__(self, rendererType, namePrefix = ''):
self.type = rendererType
self.prefix = namePrefix

class SegmentFunction(Segment):
def __init__(self, nameC, name, returnType, params, const):
self.nameC = nameC
self.name = name
self.returnType = returnType
self.params = params # List of tuples containing type and name
self.const = const

class SegmentEnum(Segment):
def __init__(self, enumName, enumValues):
self.name = enumName
self.values = enumValues


def parseDescriptionFile(descFileName):
descFile = open(descFileName, 'r')
Expand Down Expand Up @@ -98,11 +115,17 @@ def parseDescriptionFile(descFileName):
else:
raise RuntimeError('"inherits" instruction should be followed by parent class name')

elif parts[0] == 'abstract-class':
if len(parts) == 1:
segments.append(SegmentAbstractClass())
else:
raise RuntimeError('"abstract-class" instruction should not have anything behind it')

elif parts[0] == 'property-widget-renderer':
if len(parts) == 2:
segments.append(SegmentPropertyWidgetRenderer(parts[1]))
elif len(parts) == 3:
segments.append(SegmentPropertyWidgetRenderer(parts[2]))
segments.append(SegmentPropertyWidgetRenderer(parts[1], parts[2]))
else:
raise RuntimeError('"property-widget-renderer" instruction should be followed renderer type (and optional name prefix)')

Expand All @@ -112,6 +135,71 @@ def parseDescriptionFile(descFileName):
else:
raise RuntimeError('"property" instruction should be followed by type and name')

elif parts[0] == 'property-bool-is':
if len(parts) == 2:
boolProperty = SegmentProperty("bool", parts[1])
boolProperty.getterUsesIsPrefix = True
segments.append(boolProperty)
else:
raise RuntimeError('"property-bool-is" instruction should be followed by a name')

elif parts[0] == 'function':
if len(parts) >= 2:
openBracketPos = line.find('(')
closeBracketPos = line.find(')')
if openBracketPos == -1:
raise RuntimeError('Opening bracket missing in "function" instruction')
if closeBracketPos == -1:
raise RuntimeError('Closing bracket missing in "function" instruction')
if closeBracketPos <= openBracketPos:
raise RuntimeError('"function" instruction had closing bracket before opening one')

const = False
if parts[-2] == '->':
returnType = parts[-1]
if parts[-3] == 'const':
const = True
else:
returnType = 'void'
if parts[-1] == 'const':
const = True

if closeBracketPos == openBracketPos+1 or line[openBracketPos+1:closeBracketPos] == 'void':
params = []
else:
params = [tuple(param.strip().split(' ')) for param in line[openBracketPos+1:closeBracketPos].split(',')]
for param in params:
if len(param) != 2:
raise RuntimeError('Parameter "' + ' '.join(param) + '" does not consist of exactly 2 parts (type and name)')

name = line[9:openBracketPos].strip()
if ' ' in name:
nameParts = name.split(' ')
if len(nameParts) != 2:
raise RuntimeError('Name in "function" should not consists of many parts')
nameC = nameParts[0]
name = nameParts[1]
else:
nameC = name

segments.append(SegmentFunction(nameC, name, returnType, params, const))
else:
raise RuntimeError('"function" instruction should have format "function name(params)", with " -> returnType" behind it for non-void functions')

elif parts[0] == 'enum':
openBracePos = line.find('{')
closeBracePos = line.find('}')
if openBracePos == -1:
raise RuntimeError('Opening brace missing in "enum" instruction')
if closeBracePos == -1:
raise RuntimeError('Closing brace missing in "enum" instruction')
if closeBracePos <= openBracePos:
raise RuntimeError('"enum" instruction had closing brace before opening one')

enumName = line[5:openBracePos].strip()
enumValues = [value.strip() for value in line[openBracePos+1:closeBracePos].split(',')]
segments.append(SegmentEnum(enumName, enumValues))

else:
raise RuntimeError('Instruction "' + parts[0] + '" not recognised')

Expand Down
Loading

0 comments on commit f9c713e

Please sign in to comment.