-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #147 from endlessm/decouple-ui-from-codegen
Decouple UI from Code Generation
- Loading branch information
Showing
45 changed files
with
1,512 additions
and
1,593 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
extends RefCounted | ||
|
||
const Types = preload("res://addons/block_code/types/types.gd") | ||
const BlockAST = preload("res://addons/block_code/code_generation/block_ast.gd") | ||
|
||
var array: Array[ASTPair] | ||
|
||
|
||
class ASTPair: | ||
var ast: BlockAST | ||
var canvas_position: Vector2 | ||
|
||
func _init(p_ast: BlockAST, p_canvas_position: Vector2): | ||
ast = p_ast | ||
canvas_position = p_canvas_position | ||
|
||
|
||
func _init(): | ||
array = [] | ||
|
||
|
||
func append(ast: BlockAST, canvas_position: Vector2): | ||
array.append(ASTPair.new(ast, canvas_position)) | ||
|
||
|
||
func clear(): | ||
array.clear() | ||
|
||
|
||
func get_top_level_nodes_of_type(block_type: Types.BlockType) -> Array[BlockAST]: | ||
var asts: Array[BlockAST] = [] | ||
|
||
for ast_pair in array: | ||
if ast_pair.ast.root.data.type == block_type: | ||
asts.append(ast_pair.ast) | ||
|
||
return asts |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
extends RefCounted | ||
|
||
const BlockAST = preload("res://addons/block_code/code_generation/block_ast.gd") | ||
const OptionData = preload("res://addons/block_code/code_generation/option_data.gd") | ||
const Types = preload("res://addons/block_code/types/types.gd") | ||
|
||
var root: ASTNode | ||
|
||
|
||
class IDHandler: | ||
static var counts: Dictionary = {} | ||
|
||
static func reset(): | ||
counts = {} | ||
|
||
static func get_unique_id(str: String) -> int: | ||
if not counts.has(str): | ||
counts[str] = 0 | ||
|
||
counts[str] += 1 | ||
|
||
return counts[str] | ||
|
||
static func make_unique(formatted_string: String) -> String: | ||
var unique_string = formatted_string | ||
var regex = RegEx.new() | ||
regex.compile("\\b__[^\\s]+") | ||
var ids: Dictionary = {} | ||
for result in regex.search_all(formatted_string): | ||
var result_string = result.get_string() | ||
if not ids.has(result_string): | ||
ids[result_string] = get_unique_id(result_string) | ||
unique_string = unique_string.replace(result_string, result_string + "_%d" % ids[result_string]) | ||
|
||
return unique_string | ||
|
||
|
||
class ASTNode: | ||
var data #: BlockDefinition | ||
var children: Array[ASTNode] | ||
var arguments: Dictionary # String, ASTValueNode | ||
|
||
func _init(): | ||
children = [] | ||
arguments = {} | ||
|
||
func get_code_block() -> String: | ||
var code_block: String = data.code_template # get multiline code_template from block definition | ||
|
||
# insert args | ||
|
||
# check if args match an overload in the resource | ||
|
||
for arg_name in arguments: | ||
# Use parentheses to be safe | ||
var argument = arguments[arg_name] | ||
var code_string: String | ||
if argument is ASTValueNode: | ||
code_string = argument.get_code() | ||
else: | ||
code_string = BlockAST.raw_input_to_code_string(argument) | ||
|
||
code_block = code_block.replace("{%s}" % arg_name, code_string) | ||
|
||
return IDHandler.make_unique(code_block) | ||
|
||
func get_code(depth: int) -> String: | ||
var code: String = "" | ||
|
||
# append code block | ||
var code_block := get_code_block() | ||
code_block = code_block.indent("\t".repeat(depth)) | ||
|
||
code += code_block + "\n" | ||
|
||
# fill empty entry and control blocks with pass | ||
if children.is_empty() and (data.type == Types.BlockType.ENTRY || data.type == Types.BlockType.CONTROL): | ||
code += "pass\n".indent("\t".repeat(depth + 1)) | ||
|
||
for child in children: | ||
code += child.get_code(depth + 1) | ||
|
||
return code | ||
|
||
|
||
class ASTValueNode: | ||
var data #: BlockDefinition | ||
var arguments: Dictionary # String, ASTValueNode | ||
|
||
func _init(): | ||
arguments = {} | ||
|
||
func get_code() -> String: | ||
var code: String = data.code_template # get code_template from block definition | ||
|
||
# check if args match an overload in the resource | ||
|
||
for arg_name in arguments: | ||
# Use parentheses to be safe | ||
var argument = arguments[arg_name] | ||
var code_string: String | ||
if argument is ASTValueNode: | ||
code_string = argument.get_code() | ||
else: | ||
code_string = BlockAST.raw_input_to_code_string(argument) | ||
|
||
code = code.replace("{%s}" % arg_name, code_string) | ||
|
||
return IDHandler.make_unique("(%s)" % code) | ||
|
||
|
||
func get_code() -> String: | ||
IDHandler.reset() | ||
return root.get_code(0) | ||
|
||
|
||
func _to_string(): | ||
return to_string_recursive(root, 0) | ||
|
||
|
||
func to_string_recursive(node: ASTNode, depth: int) -> String: | ||
var string: String = "%s %s\n" % ["-".repeat(depth), node.data.display_template] | ||
|
||
for c in node.children: | ||
string += to_string_recursive(c, depth + 1) | ||
|
||
return string | ||
|
||
|
||
static func raw_input_to_code_string(input) -> String: | ||
match typeof(input): | ||
TYPE_STRING: | ||
return "'%s'" % input.replace("\\", "\\\\").replace("'", "\\'") | ||
TYPE_VECTOR2: | ||
return "Vector2%s" % str(input) | ||
TYPE_COLOR: | ||
return "Color%s" % str(input) | ||
TYPE_OBJECT: | ||
if input is OptionData: | ||
var option_data := input as OptionData | ||
return option_data.items[option_data.selected] | ||
_: | ||
return "%s" % input | ||
|
||
return "" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
1 change: 0 additions & 1 deletion
1
...block_code/ui/block_canvas/option_data.gd → ...block_code/code_generation/option_data.gd
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
class_name OptionData | ||
extends Resource | ||
|
||
@export var selected: int | ||
|
Oops, something went wrong.