def _consume_update_tree_code_queue(): edit_tree = getattr(bpy.context.space_data, "edit_tree", None) if _generate_on_game_start not in bpy.app.handlers.game_pre: bpy.app.handlers.game_pre.append(_generate_on_game_start) if edit_tree: # edit_tree = bpy.context.space_data.edit_tree old_name = _tree_to_name_map.get(edit_tree) if not old_name: _tree_to_name_map[edit_tree] = edit_tree.name else: if old_name != edit_tree.name: update_tree_name(edit_tree, old_name) if not _update_queue: return now = time.time() last_event = _update_queue[-1] delta = now - last_event if delta > 0.25: _update_queue.clear() try: bpy.ops.bge_netlogic.generate_logicnetwork() except Exception: if getattr(bpy.context.scene.logic_node_settings, 'use_generate_all', False): utils.warn('Could not update tree, updating all...') bpy.ops.bge_netlogic.generate_logicnetwork_all() else: utils.error('Could not update tree, context incorrect!') return True
def execute(self, context): # ensure that the local "bgelogic" folder exists local_bgelogic_folder = bpy.path.abspath("//bgelogic") if not os.path.exists(local_bgelogic_folder): try: os.mkdir(local_bgelogic_folder) except PermissionError: self.report( {"ERROR"}, "Cannot generate the code because the blender file has " "not been saved or the user has no write permission for " "the containing folder.") utils.set_compile_status(utils.TREE_FAILED) return {"FINISHED"} for tree in bpy.data.node_groups: if tree.bl_idname == bge_netlogic.ui.BGELogicTree.bl_idname: try: tree_code_generator.TreeCodeGenerator( ).write_code_for_tree(tree) except Exception: utils.error(f"Couldn't compile tree {tree.name}!") utils.set_compile_status(utils.TREE_COMPILED_ALL) try: context.region.tag_redraw() except Exception: utils.warn("Couldn't redraw panel, code updated.") return {"FINISHED"}
def _update_all_logic_tree_code(): now = time.time() _update_queue.append(now) now = time.time() last_event = _update_queue[-1] utils.set_compile_status(utils.TREE_MODIFIED) try: bpy.ops.bge_netlogic.generate_logicnetwork_all() except Exception: utils.error("Unknown Error, abort generating Network code")
def execute(self, context): assert self.tree_name is not None assert len(self.tree_name) > 0 blt_groups = [ g for g in bpy.data.node_groups if (g.name == self.tree_name) and ( g.bl_idname == bge_netlogic.ui.BGELogicTree.bl_idname) ] if len(blt_groups) != 1: utils.error("Something went wrong here...") for t in blt_groups: context.space_data.node_tree = t return {'FINISHED'}
def execute(self, context): # ensure that the local "bgelogic" folder exists local_bgelogic_folder = bpy.path.abspath("//bgelogic") if not os.path.exists(local_bgelogic_folder): try: os.mkdir(local_bgelogic_folder) except PermissionError: self.report( {"ERROR"}, "Cannot generate the code because the blender file has " "not been saved or the user has no write permission for " "the containing folder." ) utils.set_compile_status(utils.TREE_FAILED) return {"FINISHED"} # write the current tree in a python module, # in the directory of the current blender file context = bpy.context try: tree = context.space_data.edit_tree tree_code_generator.TreeCodeGenerator().write_code_for_tree(tree) except Exception as e: utils.error(e) utils.warn('Automatic Update failed, attempting hard generation...') if getattr(bpy.context.scene.logic_node_settings, 'use_generate_all', False): self.report( {'ERROR'}, 'Tree to edit not found! Updating All Trees.' ) for tree in bpy.data.node_groups: if tree.bl_idname == bge_netlogic.ui.BGELogicTree.bl_idname: tree_code_generator.TreeCodeGenerator().write_code_for_tree(tree) utils.set_compile_status(utils.TREE_FAILED) return {"FINISHED"} else: self.report( {'ERROR'}, 'Tree to edit not found! Aborting.' ) utils.error('Tree to edit not found! Aborting.') utils.set_compile_status(utils.TREE_FAILED) return {"FINISHED"} utils.set_compile_status(utils.TREE_COMPILED) try: context.region.tag_redraw() except Exception: utils.warn("Couldn't redraw panel, code updated.") return {"FINISHED"}
def execute(self, context): utils.debug('Packing Group...') nodes_to_group = [] tree = context.space_data.edit_tree if tree is None: utils.error('Could not pack group! Aborting...') return {'FINISHED'} for node in tree.nodes: if node.select: nodes_to_group.append(node) if len(nodes_to_group) > 0: name = bpy.context.scene.nl_group_name.name if self.group_make(name, nodes_to_group): bge_netlogic._update_all_logic_tree_code() return {'FINISHED'}
def _sort_cellvarnames(self, node_cellvar_list, uid_map): # sorting is effective only in serial execution context. Because the python vm is basically a serial only # machine, we force a potentially parallel network to work as a serial one. Shame on GIL. available_cells = list(node_cellvar_list) added_cells = [] while available_cells: for cell_name in available_cells: node = uid_map.get_node_for_varname(cell_name) # if all the links of node are either constant or cells in added_cells, then this node can be put in the list if self._test_node_links(node, added_cells, uid_map) == 'GOOD': available_cells.remove(cell_name) added_cells.append(cell_name) elif self._test_node_links(node, added_cells, uid_map) == 'FAULTY': name = node.label if node.label else node.name utils.error(f'A Reroute does not have any input links! Skipping {name}.') available_cells.remove(cell_name) return added_cells
def execute(self, context): current_scene = context.scene tree = context.space_data.edit_tree tree.use_fake_user = True py_module_name = bge_netlogic.utilities.py_module_name_for_tree(tree) selected_objects = [ ob for ob in current_scene.objects if ob.select_get() ] initial_status = bge_netlogic.utilities.compute_initial_status_of_tree( tree.name, selected_objects) try: tree_code_generator.TreeCodeGenerator().write_code_for_tree(tree) except Exception as e: utils.error(f"Couldn't compile tree {tree.name}!") print(e) initial_status = True if initial_status is None else False for obj in selected_objects: utils.success("Applied tree {} to object {}.".format( tree.name, obj.name)) if tree.mode: tree_name = utils.make_valid_name(tree.name) module = f'nl_{tree_name.lower()}' name = f'{module}.{tree_name}' comps = [c.module for c in obj.game.components] if module not in comps: bpy.ops.logic.python_component_register( component_name=name) else: self._setup_logic_bricks_for_object(tree, py_module_name, obj, context) tree_collection = obj.bgelogic_treelist contains = False for t in tree_collection: if t.tree_name == tree.name: contains = True break if not contains: new_entry = tree_collection.add() new_entry.tree_name = tree.name new_entry.tree = tree # this will set both new_entry.tree_initial_status and add a # game property that makes the status usable at runtime bge_netlogic.utilities.set_network_initial_status_key( obj, tree.name, initial_status) return {'FINISHED'}
def invoke(self, context, event): self.socket = context.socket self.node = context.node if (not self.socket) and (not self.node): utils.error("No socket or Node") return {'FINISHED'} if (self.socket): self.socket.value = "Press a key..." else: self.node.value = "Press a key..." try: context.region.tag_redraw() except Exception: utils.warn("Couldn't redraw panel, code updated.") context.window_manager.modal_handler_add(self) return {'RUNNING_MODAL'}
def execute(self, context): utils.debug('Adding template...') tree = context.space_data.edit_tree content = json.load(open(self.get_template_path()))['nodes'] if tree is None: utils.error('Cannot add template! Aborting...') return {'FINISHED'} for node in tree.nodes: node.select = False nodes = [] for c in content: self.add_node( c['x'], c['y'], c['label'], c['node_type'], nodes, values=c['values'] ) i = 0 for c in content: self.link_node(nodes[i], c['links'], nodes) i += 1 for node in nodes: node.select = True if node.label == 'Speed': continue node.hide = True for socket in node.inputs: if not socket.is_linked: socket.hide = True for socket in node.outputs: if not socket.is_linked: socket.hide = True bpy.ops.transform.translate() utils.success('Added 4 Key Template.') return {'FINISHED'}
def group_make(self, group_name, add_nodes): node_tree = bpy.data.node_groups.new(group_name, 'BGELogicTree') group_name = node_tree.name nodes = node_tree.nodes new_nodes = {} parent_tree = bpy.context.space_data.edit_tree locs = [] for node in add_nodes: added_node = nodes.new(node.bl_idname) added_node.location = node.location new_nodes[node] = added_node for old_node in new_nodes: new_node = new_nodes[old_node] for attr in dir(old_node): if attr in NODE_ATTRS: setattr(new_node, attr, getattr(old_node, attr)) for socket in old_node.outputs: for link in socket.links: to_node = link.to_node if to_node not in add_nodes: msg = 'Some linked Nodes are not selected!' self.report({"ERROR"}, msg) utils.error(msg) return None for socket in old_node.inputs: index = self._index_of(socket, old_node.inputs) for attr in dir(socket): if attr in NODE_ATTRS or attr.startswith('slot_'): try: if attr != 'label': setattr(new_node.inputs[index], attr, getattr(socket, attr)) except Exception: utils.warn( 'Attribute {} not writable.'.format(attr)) for link in socket.links: try: output_socket = link.from_socket output_node = new_nodes[output_socket.node] outdex = self._index_of(output_socket, output_socket.node.outputs) node_tree.links.new(new_node.inputs[index], output_node.outputs[outdex]) except Exception: bpy.data.node_groups.remove(node_tree) msg = 'Some linked Nodes are not selected! Aborting...' self.report({"ERROR"}, msg) utils.error(msg) return None locs.append(old_node.location) for old_node in new_nodes: parent_tree.nodes.remove(old_node) redir = parent_tree.nodes.new('NLActionExecuteNetwork') redir.inputs[0].value = True try: redir.inputs[1].value = bpy.context.object except Exception: msg = 'No Object was selected; Set Object in tree {} manually!'.format( parent_tree.name) self.report({"WARNING"}, msg) utils.warn(msg) redir.inputs[2].value = bpy.data.node_groups[group_name] redir.location = self.avg_location(locs) node_tree.use_fake_user = True utils.success(f'Created Node Tree {group_name}.') return node_tree
def update_tree_name(tree, old_name): utils.set_compile_status(utils.TREE_MODIFIED) new_name = tree.name _tree_to_name_map[tree] = new_name old_name_code = utilities.strip_tree_name(old_name) new_name_code = utilities.strip_tree_name(new_name) new_pymodule_name = utilities.py_module_name_for_tree(tree) # old_pymodule_name = ( # utilities.py_module_name_for_stripped_tree_name(old_name_code)) new_py_controller_module_string = ( utilities.py_controller_module_string(new_pymodule_name)) for ob in bpy.data.objects: old_status = None is_tree_applied_to_object = False for tree_item in ob.bgelogic_treelist: if tree_item.tree_name == new_name: st = tree_item.tree_initial_status utils.remove_tree_item_from_object(ob, tree_item.tree_name) new_entry = ob.bgelogic_treelist.add() new_entry.tree_name = tree.name new_entry.tree = tree # this will set both new_entry.tree_initial_status and add a # game property that makes the status usable at runtime utils.set_network_initial_status_key(ob, tree.name, st) tree_item.tree_name = new_name if old_status is not None: raise RuntimeError( "We have two trees with the same name in {}".format( ob.name)) if is_tree_applied_to_object: utilities.rename_initial_status_game_object_property( ob, old_name, new_name) gs = ob.game idx = 0 check_name = utils.make_valid_name(old_name) comp_name = f'nl_{check_name.lower()}' clsname = utils.make_valid_name(new_name) new_comp_name = f'nl_{clsname.lower()}.{clsname}' for c in gs.components: if c.module == comp_name: try: ops.tree_code_generator.TreeCodeGenerator( ).write_code_for_tree(tree) except Exception: utils.error(f"Couldn't compile tree {tree.name}!") text = bpy.data.texts.get(f'{comp_name}.py') if text: bpy.data.texts.remove(text) active_object = bpy.context.object bpy.context.view_layer.objects.active = ob bpy.ops.logic.python_component_remove(index=idx) bpy.ops.logic.python_component_register( component_name=new_comp_name) bpy.context.view_layer.objects.active = active_object idx += 1 for sensor in gs.sensors: if old_name_code in sensor.name: sensor.name = sensor.name.replace(old_name_code, new_name_code) for controller in gs.controllers: if old_name_code in controller.name: controller.name = controller.name.replace( old_name_code, new_name_code) if isinstance(controller, bpy.types.PythonController): controller.module = new_py_controller_module_string for actuator in gs.actuators: if old_name_code in actuator.name: actuator.name = actuator.name.replace( old_name_code, new_name_code) utils.success(f'Renamed Tree {old_name_code} to {new_name_code}')
def group_make(self, group_name, add_nodes): node_tree = bpy.data.node_groups.new(group_name, 'BGELogicTree') group_name = node_tree.name attrs = [ 'value', 'game_object', 'default_value', 'use_toggle', 'true_label', 'false_label', 'value_type', 'bool_editor', 'int_editor', 'float_editor', 'string_editor', 'radians', 'filepath_value', 'sound_value', 'float_field', 'expression_field', 'input_type', 'value_x', 'value_y', 'value_z', 'title', 'local', 'operator', 'formatted', 'pulse', 'hide', 'label', 'use_owner', 'advanced' ] nodes = node_tree.nodes new_nodes = {} parent_tree = bpy.context.space_data.edit_tree locs = [] for node in add_nodes: added_node = nodes.new(node.bl_idname) added_node.location = node.location new_nodes[node] = added_node for old_node in new_nodes: new_node = new_nodes[old_node] for attr in dir(old_node): if attr in attrs: setattr(new_node, attr, getattr(old_node, attr)) for socket in old_node.inputs: index = self._index_of(socket, old_node.inputs) for attr in dir(socket): if attr in attrs: try: if attr != 'label': setattr(new_node.inputs[index], attr, getattr(socket, attr)) except Exception: utils.warn('Attribute {} not writable.'.format(attr)) for link in socket.links: try: output_socket = link.from_socket output_node = new_nodes[output_socket.node] outdex = self._index_of(output_socket, output_socket.node.outputs) node_tree.links.new(new_node.inputs[index], output_node.outputs[outdex]) except Exception: bpy.data.node_groups.remove(node_tree) msg = 'Some linked Nodes are not selected! Aborting...' self.report({"ERROR"}, msg) utils.error(msg) return None locs.append(old_node.location) for old_node in new_nodes: parent_tree.nodes.remove(old_node) redir = parent_tree.nodes.new('NLActionExecuteNetwork') redir.inputs[0].value = True try: redir.inputs[1].value = bpy.context.object except Exception: msg = 'No Object was selected; Set Object in tree {} manually!'.format(parent_tree.name) self.report({"WARNING"}, msg) utils.warn(msg) redir.inputs[2].value = bpy.data.node_groups[group_name] redir.location = self.avg_location(locs) node_tree.use_fake_user = True utils.success(f'Created Node Tree {group_name}.') return node_tree