class_name Deck var nodes: Dictionary enum Types{ ERROR = -1, BOOL, NUMERIC, STRING, ARRAY, DICTIONARY, } static var type_assoc: Dictionary = { Types.ERROR: DeckType.DeckTypeError, Types.BOOL: DeckType.DeckTypeBool, Types.NUMERIC: DeckType.DeckTypeNumeric, Types.STRING: DeckType.DeckTypeString, Types.ARRAY: DeckType.DeckTypeArray, Types.DICTIONARY: DeckType.DeckTypeDictionary, } var variable_stack: Dictionary = {} func add_node(node: GDScript, meta: Dictionary = {}) -> DeckNode: # TODO: accept instances of DeckNode instead of instancing here? var uuid := UUID.v4() var node_inst: DeckNode = node.new() as DeckNode nodes[uuid] = node_inst node_inst._belonging_to = self node_inst._id = uuid if !meta.is_empty(): for k in meta: node_inst.set_meta(k, meta[k]) return node_inst func add_node_inst(node: DeckNode, assign_id: String = "", assign_to_self: bool = true) -> DeckNode: if assign_to_self: node._belonging_to = self if assign_id == "": var uuid := UUID.v4() nodes[uuid] = node node._id = uuid else: nodes[assign_id] = node # if !meta.is_empty(): # for k in meta: # node.set_meta(k, meta[k]) return node func get_node(uuid: String) -> DeckNode: return nodes.get(uuid) func connect_nodes(from_node: DeckNode, to_node: DeckNode, from_port: int, to_port: int) -> bool: # first, check that we can do the type conversion. var type_a: Types = from_node.ports[from_port].type var type_b: Types = to_node.ports[to_port].type var err: DeckType = (type_assoc[type_b]).from(type_assoc[type_a].new()) if err is DeckType.DeckTypeError: print(err.error_message) return false # TODO: prevent duplicate connections from_node.add_outgoing_connection(from_port, to_node._id, to_port) return true func disconnect_nodes(from_node: DeckNode, to_node: DeckNode, from_port: int, to_port: int) -> void: var hash = {to_node._id: to_port}.hash() from_node.remove_outgoing_connection(from_port, hash) func to_json(with_meta: bool = true) -> String: var inner := {"nodes": {}, "variable_stack": variable_stack} for id in nodes.keys(): inner["nodes"][id] = nodes[id].to_dict(with_meta) var d := {"deck": inner} if with_meta: d["meta"] = {} for meta in get_meta_list(): d["meta"][meta] = get_meta(meta) return JSON.stringify(d, "\t", false) static func from_json(json: String) -> Deck: var data: Dictionary = JSON.parse_string(json) as Dictionary var deck := Deck.new() deck.variable_stack = data.deck.variable_stack for key in data.meta: deck.set_meta(key, data.meta[key]) var nodes_data: Dictionary = data.deck.nodes as Dictionary for node_id in nodes_data: var node := deck.add_node_inst(NodeDB.instance_node(nodes_data[node_id].node_type), node_id, false) node._id = node_id node.name = nodes_data[node_id].name node._belonging_to = deck # node.outgoing_connections = nodes_data[node_id].outgoing_connections # node.incoming_connections = nodes_data[node_id].incoming_connections for connection_id in nodes_data[node_id].outgoing_connections: var connection_data = nodes_data[node_id].outgoing_connections[connection_id] node.outgoing_connections[int(connection_id)] = connection_data for connection_id in nodes_data[node_id].incoming_connections: var connection_data = nodes_data[node_id].incoming_connections[connection_id] node.incoming_connections[int(connection_id)] = connection_data for key in nodes_data[node_id].meta: node.set_meta(key, nodes_data[node_id].meta[key]) for prop in nodes_data[node_id].props: node.set(prop, nodes_data[node_id].props[prop]) return deck