# cython: c_string_type=unicode, c_string_encoding=utf8 from libc.stddef cimport wchar_t from pandemonium._hazmat.gdnative_api_struct cimport ( pandemonium_pluginscript_language_data, pandemonium_string, pandemonium_bool, pandemonium_array, pandemonium_pool_string_array, pandemonium_object, pandemonium_variant, pandemonium_error, pandemonium_dictionary ) from pandemonium._hazmat.gdapi cimport pythonscript_gdapi10 as gdapi10 from pandemonium._hazmat.conversion cimport ( pandemonium_string_to_pyobj, pyobj_to_pandemonium_string, pandemonium_variant_to_pyobj, ) cdef api pandemonium_string pythonscript_get_template_source_code( pandemonium_pluginscript_language_data *p_data, const pandemonium_string *p_class_name, const pandemonium_string *p_base_class_name ) with gil: cdef str class_name if p_class_name == NULL: class_name = "MyExportedCls" else: class_name = pandemonium_string_to_pyobj(p_class_name) cdef str base_class_name = pandemonium_string_to_pyobj(p_base_class_name) cdef str src = f"""from pandemonium import exposed, export from pandemonium import * @exposed class {class_name}({base_class_name}): # member variables here, example: a = export(int) b = export(str, default='foo') def _ready(self): \"\"\" Called every time the node is added to the scene. Initialization here. \"\"\" pass """ cdef pandemonium_string ret pyobj_to_pandemonium_string(src, &ret) return ret cdef api pandemonium_bool pythonscript_validate( pandemonium_pluginscript_language_data *p_data, const pandemonium_string *p_script, int *r_line_error, int *r_col_error, pandemonium_string *r_test_error, const pandemonium_string *p_path, pandemonium_pool_string_array *r_functions ) with gil: return True cdef api int pythonscript_find_function( pandemonium_pluginscript_language_data *p_data, const pandemonium_string *p_function, const pandemonium_string *p_code ) with gil: return 0 cdef api pandemonium_string pythonscript_make_function( pandemonium_pluginscript_language_data *p_data, const pandemonium_string *p_class, const pandemonium_string *p_name, const pandemonium_pool_string_array *p_args ) with gil: cdef str name = pandemonium_string_to_pyobj(p_name) # TODO: replace this with PoolStringArray binding once implemented cdef int i cdef pandemonium_string gdarg cdef list args_names = [] for i in range(gdapi10.pandemonium_pool_string_array_size(p_args)): gdarg = gdapi10.pandemonium_pool_string_array_get(p_args, i) arg = pandemonium_string_to_pyobj(&gdarg) gdapi10.pandemonium_string_destroy(&gdarg) args_names.append(arg.split(":", 1)[0]) cdef str src = """\ def {name}(self, { ','.join(args_names) }): pass """ cdef pandemonium_string ret pyobj_to_pandemonium_string(src, &ret) return ret cdef api pandemonium_error pythonscript_complete_code( pandemonium_pluginscript_language_data *p_data, const pandemonium_string *p_code, const pandemonium_string *p_base_path, pandemonium_object *p_owner, pandemonium_array *r_options, pandemonium_bool *r_force, pandemonium_string *r_call_hint ) with gil: return pandemonium_error.PANDEMONIUM_OK cdef api void pythonscript_auto_indent_code( pandemonium_pluginscript_language_data *p_data, pandemonium_string *p_code, int p_from_line, int p_to_line ) with gil: # TODO: use black for this job # try: # import autopep8 # except ImportError: # print( # "[Pythonscript] Auto indent requires module `autopep8`, " # "install it with `pip install autopep8`" # ) # pycode = pandemonium_string_to_pyobj(code).splitlines() # before = "\n".join(pycode[:from_line]) # to_fix = "\n".join(pycode[from_line:to_line]) # after = "\n".join(pycode[to_line:]) # fixed = autopep8.fix_code(to_fix) # final_code = "\n".join((before, fixed, after)) # # TODO: modify code instead of replace it when binding on pandemonium_string # # operation is available # lib.pandemonium_string_destroy(code) # lib.pandemonium_string_new_unicode_data(code, final_code, len(final_code)) pass __global_constants = {} cdef api void pythonscript_add_global_constant( pandemonium_pluginscript_language_data *p_data, const pandemonium_string *p_variable, const pandemonium_variant *p_value ) with gil: # However, Pandemonium add global constants very early (first as an empty variant # placeholder before any script is loaded, then as a proper loaded script). # So it's possible this function get called before `pythonscript_script_init` # (which is supposed to do the lazy `_initialize_bindings`). _initialize_bindings() name = pandemonium_string_to_pyobj(p_variable) value = pandemonium_variant_to_pyobj(p_value) __global_constants[name] = value cdef api pandemonium_string pythonscript_debug_get_error( pandemonium_pluginscript_language_data *p_data ) with gil: cdef pandemonium_string ret pyobj_to_pandemonium_string("Nothing", &ret) return ret cdef api int pythonscript_debug_get_stack_level_count( pandemonium_pluginscript_language_data *p_data ) with gil: return 1 cdef api int pythonscript_debug_get_stack_level_line( pandemonium_pluginscript_language_data *p_data, int p_level ) with gil: return 1 cdef api pandemonium_string pythonscript_debug_get_stack_level_function( pandemonium_pluginscript_language_data *p_data, int p_level ) with gil: cdef pandemonium_string ret pyobj_to_pandemonium_string("Nothing", &ret) return ret cdef api pandemonium_string pythonscript_debug_get_stack_level_source( pandemonium_pluginscript_language_data *p_data, int p_level ) with gil: cdef pandemonium_string ret pyobj_to_pandemonium_string("Nothing", &ret) return ret cdef api void pythonscript_debug_get_stack_level_locals( pandemonium_pluginscript_language_data *p_data, int p_level, pandemonium_pool_string_array *p_locals, pandemonium_array *p_values, int p_max_subitems, int p_max_depth ) with gil: pass cdef api void pythonscript_debug_get_stack_level_members( pandemonium_pluginscript_language_data *p_data, int p_level, pandemonium_pool_string_array *p_members, pandemonium_array *p_values, int p_max_subitems, int p_max_depth ) with gil: pass cdef api void pythonscript_debug_get_globals( pandemonium_pluginscript_language_data *p_data, pandemonium_pool_string_array *p_locals, pandemonium_array *p_values, int p_max_subitems, int p_max_depth ) with gil: pass cdef api pandemonium_string pythonscript_debug_parse_stack_level_expression( pandemonium_pluginscript_language_data *p_data, int p_level, const pandemonium_string *p_expression, int p_max_subitems, int p_max_depth ) with gil: cdef pandemonium_string ret pyobj_to_pandemonium_string("Nothing", &ret) return ret cdef api void pythonscript_get_public_functions( pandemonium_pluginscript_language_data *p_data, pandemonium_array *r_functions ) with gil: pass cdef api void pythonscript_get_public_constants( pandemonium_pluginscript_language_data *p_data, pandemonium_dictionary *r_constants ) with gil: pass