{ "cells": [ { "cell_type": "code", "execution_count": null, "id": "e63822b3", "metadata": {}, "outputs": [], "source": [ "import ipywidgets as widgets" ] }, { "cell_type": "code", "execution_count": null, "id": "e0a17595", "metadata": {}, "outputs": [], "source": [ "lcc = widgets.Label(value=\"Current c++ class:\")\n", "tcc = widgets.Text()\n", "\n", "l = widgets.Label(value=\"Input:\")\n", "ta = widgets.Textarea(layout=widgets.Layout(width='80%', height='200px'))\n", "b = widgets.Button(description='Convert',tooltip='Convert',icon='check')\n", "\n", "ol = widgets.Label(value=\"Output:\")\n", "\n", "olh = widgets.Label(value=\"Header:\")\n", "otah = widgets.Output(layout={'border': '1px solid black'})\n", "\n", "ols = widgets.Label(value=\"Source:\")\n", "otas = widgets.Output(layout={'border': '1px solid black'})\n", "\n", "ool = widgets.Label(value=\"Output:\")\n", "out = widgets.Output(layout={'border': '1px solid black'})\n", "\n", "vbi = widgets.VBox([ lcc, tcc, l, ta, b])\n", "vbo = widgets.VBox([ol, olh, otah, ols, otas, ool, out])\n" ] }, { "cell_type": "code", "execution_count": null, "id": "ca49ac34", "metadata": { "scrolled": true }, "outputs": [], "source": [ "if 'transform_input' in globals():\n", " b.on_click(transform_input, True)\n", "\n", "class_remaps = {\n", " '': '',\n", " 'void': 'void',\n", " 'Variant': 'pandemonium_variant',\n", " 'bool': 'pandemonium_bool',\n", " 'int': 'pandemonium_int',\n", " 'real_t': 'pandemonium_real',\n", " 'float': 'pandemonium_real',\n", " 'double': 'pandemonium_real',\n", " 'String': 'pandemonium_string',\n", " 'Rect2': 'pandemonium_rect2',\n", " 'Rect2i': 'pandemonium_rect2i',\n", " 'Vector2': 'pandemonium_vector2',\n", " 'Vector2i': 'pandemonium_vector2i',\n", " 'Vector3': 'pandemonium_vector3',\n", " 'Vector3i': 'pandemonium_vector3i',\n", " 'Vector4': 'pandemonium_vector4',\n", " 'Vector4i': 'pandemonium_vector4i',\n", " 'Plane': 'pandemonium_plane',\n", " 'Quaternion': 'pandemonium_quaternion',\n", " 'AABB': 'pandemonium_aabb',\n", " 'Basis': 'pandemonium_basis',\n", " 'Transform': 'pandemonium_transform',\n", " 'Transform2d': 'pandemonium_transform2d',\n", " 'Projection': 'pandemonium_projection',\n", " 'Color': 'pandemonium_color',\n", " 'NodePath': 'pandemonium_node_path',\n", " 'RID': 'pandemonium_rid',\n", " 'Object': 'pandemonium_object',\n", " 'StringName': 'pandemonium_string_name',\n", " 'Dictionary': 'pandemonium_dictionary',\n", " 'Array': 'pandemonium_array',\n", " 'PoolByteArray': 'pandemonium_pool_byte_array',\n", " 'PoolIntArray': 'pandemonium_pool_int_array',\n", " 'PoolRealArray': 'pandemonium_pool_real_array',\n", " 'PoolStringArray': 'pandemonium_pool_string_array',\n", " 'PoolVector2Array': 'pandemonium_pool_vector2_array',\n", " 'PoolVector2iArray': 'pandemonium_pool_vector2i_array',\n", " 'PoolVector3Array': 'pandemonium_pool_vector3_array',\n", " 'PoolVector3iArray': 'pandemonium_pool_vector3i_array',\n", " 'PoolVector4Array': 'pandemonium_pool_vector4_array',\n", " 'PoolVector4iArray': 'pandemonium_pool_vector4i_array',\n", " 'PoolColorArray': 'pandemonium_pool_color_array',\n", "}\n", "\n", "class_c_no_force_ptr = {\n", " 'bool': True,\n", " 'int': True,\n", " 'real_t': True,\n", " 'float': True,\n", " 'double': True,\n", "}\n", "\n", "METHOD_ARG_TYPE_NONE = 0\n", "METHOD_ARG_TYPE_REFERENCE = 1\n", "METHOD_ARG_TYPE_POINTER = 2\n", "\n", "def get_current_cpp_class():\n", " return tcc.value\n", "\n", "def get_current_c_class():\n", " return class_remaps[tcc.value]\n", " \n", "\n", "class PMethodArg:\n", " def __init__(self):\n", " self.is_const = False\n", " self.cpp_type = ''\n", " self.cpp_arg_type = METHOD_ARG_TYPE_NONE\n", " self.cpp_has_default = False\n", " self.arg_name = ''\n", " self.cpp_default_value = ''\n", " \n", " def is_no_force_ptr(self):\n", " return self.cpp_type in class_c_no_force_ptr\n", " \n", " def get_arg_name_local(self):\n", " return self.arg_name[2:]\n", " \n", " def generate_c_arg(self):\n", " s = ', '\n", " \n", " if self.is_const:\n", " s += 'const '\n", " \n", " s += class_remaps[self.cpp_type] + ' '\n", " \n", " is_pointer = self.cpp_arg_type != METHOD_ARG_TYPE_NONE\n", " \n", " if is_pointer and self.cpp_type in class_c_no_force_ptr:\n", " is_pointer = False\n", " \n", " if is_pointer:\n", " s += '*'\n", " \n", " s += self.arg_name\n", " \n", " return s\n", " \n", " def generate_convert_line(self):\n", " s = ''\n", "\n", " if self.is_const:\n", " s += 'const '\n", " \n", " if self.is_no_force_ptr():\n", " s += self.cpp_type + ' ' + self.get_arg_name_local() + ' = ' + self.arg_name + ';'\n", " else:\n", " s += self.cpp_type + ' *' + self.get_arg_name_local() + ' = ('\n", " \n", " if self.is_const:\n", " s += 'const '\n", " \n", " s += self.cpp_type + ' *)' + self.arg_name + ';'\n", " \n", " return s\n", " \n", " def parse_line(self, l):\n", " self.cpp_has_default = False\n", " \n", " if '=' in l:\n", " sl = l.split('=')\n", " \n", " l = sl[0].strip()\n", " self.cpp_has_default = True\n", " self.cpp_default_value = sl[1].strip()\n", " \n", " \n", " self.cpp_arg_type = METHOD_ARG_TYPE_NONE\n", " \n", " if '*' in l:\n", " self.cpp_arg_type = METHOD_ARG_TYPE_POINTER\n", " \n", " if '&' in l:\n", " self.cpp_arg_type = METHOD_ARG_TYPE_REFERENCE\n", " \n", " l = l.replace('*', '')\n", " l = l.replace('&', '')\n", " \n", " spls = l.split(' ')\n", " \n", " self.is_const = spls[0].strip() == 'const'\n", " \n", " if self.is_const:\n", " spls = spls[1:]\n", " \n", " with out:\n", " print(spls)\n", " \n", " self.cpp_type = spls[0]\n", " self.arg_name = spls[1]\n", " \n", " def __str__(self):\n", " s = ' PMethodArg:\\n'\n", " \n", " s += ' is_const: ' + str(self.is_const) + '\\n'\n", " s += ' cpp_type: ' + self.cpp_type + '\\n'\n", " s += ' cpp_arg_type: ' + str(self.cpp_arg_type) + '\\n'\n", " s += ' arg_name: ' + self.arg_name + '\\n'\n", " s += ' cpp_has_default: ' + str(self.cpp_has_default) + '\\n'\n", " s += ' cpp_default_value: ' + self.cpp_default_value + '\\n'\n", " \n", " return s\n", " \n", "\n", "\n", "class PMethod:\n", " def __init__(self):\n", " self.args = []\n", " \n", " self.method_name = ''\n", "\n", " self.cpp_return_type = ''\n", " self.is_const = False\n", " self.is_constructor = False\n", " \n", " def parse_line(self, l):\n", " l = l.replace('//', '').strip()\n", " l = l.replace(';', '').strip()\n", " l = l.replace('inline', '').strip()\n", " l = l.replace('_FORCE_INLINE_', '').strip()\n", " l = l.strip()\n", " \n", " self.is_const = False\n", " \n", " if l.endswith('const'):\n", " self.is_const = True\n", " \n", " #remove it from the string\n", " \n", " l = l[:-5]\n", " \n", " l = l.replace(')', '')\n", " \n", " sps = l.split('(')\n", " \n", " mdeffull = sps[0].strip()\n", " margsfull = sps[1].strip()\n", " \n", " mds = mdeffull.split(' ')\n", " \n", " self.is_constructor = False\n", " \n", " mrettype = ''\n", " mdef = ''\n", " \n", " if len(mds) == 1:\n", " self.is_constructor = True\n", " self.method_name = mds[0].strip()\n", " else:\n", " self.cpp_return_type = mds[0].strip()\n", " self.method_name = mds[1].strip()\n", " \n", " margsspl = margsfull.split(',')\n", " \n", " for ml in margsspl:\n", " ml = ml.strip()\n", " \n", " if ml == '':\n", " continue\n", " \n", " a = PMethodArg()\n", " a.parse_line(ml)\n", " self.args.append(a)\n", " \n", " def get_c_return_type(self):\n", " return class_remaps[self.cpp_return_type]\n", " \n", " def get_c_method_name(self):\n", " return get_current_c_class() + '_' + self.method_name\n", "\n", " def generate_method_string(self):\n", " s = ''\n", " \n", " s += self.get_c_return_type() + ' GDAPI ' + self.get_c_method_name() + '('\n", " \n", " if self.is_const:\n", " s += 'const '\n", " \n", " s += get_current_c_class() + ' *p_self'\n", " \n", " for a in self.args:\n", " s += a.generate_c_arg()\n", " \n", " s += ')'\n", " \n", " return s\n", " \n", " def generate_header_string(self):\n", " return self.generate_method_string() + ';'\n", " \n", " def generate_impl_string(self):\n", " s = self.generate_method_string() + '{\\n'\n", " \n", " # Create dest variable at top if needed\n", " return_needs_conversion = False\n", " \n", " if self.cpp_return_type != 'void':\n", " if not self.cpp_return_type in class_c_no_force_ptr:\n", " return_needs_conversion = True\n", " \n", " if return_needs_conversion:\n", " # it needs to be explicitly converted\n", " # Just Add dest var here\n", " s += '\\t' + self.get_c_return_type() + ' dest;\\n'\n", " \n", " s += '\\t'\n", " \n", " # Create self local\n", " if self.is_const:\n", " s += 'const '\n", " \n", " s += get_current_cpp_class() + '* self = ('\n", " \n", " if self.is_const:\n", " s += 'const '\n", " \n", " s += get_current_cpp_class() + ' *)p_self;\\n'\n", " \n", " # Create param locals\n", " self_call_args = []\n", " \n", " for a in self.args:\n", " if a.is_no_force_ptr():\n", " self_call_args.append(a.arg_name)\n", " else:\n", " self_call_args.append('*' + a.get_arg_name_local())\n", " \n", " s += '\\t' + a.generate_convert_line() + '\\n'\n", " \n", " # Create method call\n", " s += '\\t'\n", "\n", " # We have a return type\n", " if self.cpp_return_type != 'void':\n", " if return_needs_conversion:\n", " s += '*((' + self.cpp_return_type + ' *)&dest) = '\n", " else:\n", " s += 'return '\n", "\n", " s += 'self->' + self.method_name + '('\n", " \n", " first = True\n", " for a in self_call_args:\n", " if first:\n", " first = False\n", " s += a\n", " else:\n", " s += ', ' + a\n", " \n", " s += ');\\n'\n", " \n", " if self.cpp_return_type != 'void':\n", " if return_needs_conversion:\n", " s += '\\treturn dest;\\n'\n", " \n", " s += '}'\n", " \n", " return s\n", " \n", " def __str__(self):\n", " s = 'PMethod:\\n'\n", " \n", " s += ' method_name: ' + self.method_name + '\\n'\n", " s += ' cpp_return_type: ' + self.cpp_return_type + '\\n'\n", " s += ' is_const: ' + str(self.is_const) + '\\n'\n", " s += ' is_constructor: ' + str(self.is_constructor) + '\\n'\n", " \n", " s += ' args: [\\n'\n", " \n", " for a in self.args:\n", " s += str(a)\n", " s += '\\n'\n", " \n", " s += ' ]'\n", " \n", " return s\n", "\n", "def transform_input(b):\n", " with out:\n", " out.clear_output()\n", " \n", " with otah:\n", " otah.clear_output()\n", " \n", " with otas:\n", " otas.clear_output()\n", " \n", " lines = ta.value.split('\\n')\n", " \n", " for l in lines:\n", " if l.strip() == '':\n", " with otah:\n", " print('')\n", " \n", " with otas:\n", " print('')\n", " \n", " continue\n", " \n", " with out:\n", " print('line:')\n", " print(l)\n", " print('')\n", " \n", " method = PMethod()\n", " method.parse_line(l)\n", " \n", " with otah:\n", " print(method.generate_header_string())\n", " \n", " with otas:\n", " print(method.generate_impl_string())\n", " \n", " with out:\n", " print(str(method))\n", "\n", "\n", "b.on_click(transform_input)" ] }, { "cell_type": "markdown", "id": "275dd409", "metadata": {}, "source": [ "# Input" ] }, { "cell_type": "code", "execution_count": null, "id": "4248b0cc", "metadata": { "scrolled": true }, "outputs": [], "source": [ "display(vbi)" ] }, { "cell_type": "markdown", "id": "5613fdfa", "metadata": {}, "source": [ "# Output" ] }, { "cell_type": "code", "execution_count": null, "id": "47e7b581", "metadata": { "scrolled": false }, "outputs": [], "source": [ "display(vbo)" ] }, { "cell_type": "markdown", "id": "3836e292", "metadata": {}, "source": [ " " ] }, { "cell_type": "markdown", "id": "3b7827b4", "metadata": {}, "source": [ " " ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.10" } }, "nbformat": 4, "nbformat_minor": 5 }