commit 477f2439c227854cf6e6bf0c4e2cf06c71283006 Author: wrenge Date: Wed Jan 25 14:20:34 2023 +0300 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6e92f57 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +tags diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..a9e7c9e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,9 @@ + +# Change Log +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/) +and this project adheres to [Semantic Versioning](http://semver.org/). + +## [1.0.0] - 2023-01-25 +Release \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..56132fe --- /dev/null +++ b/README.md @@ -0,0 +1,21 @@ +This package is used for code generation of C# meta structs for LeoECS using Twig templates + +# Example: +ecs.meta +``` +struct TestComponent + @bhl_ecs_component @ecs_gen_component @ecs_gen_authoring @ecs_serializable + pos : Vector3 + fwd : Vector3 + width : float + length : float +end +``` +This will automatically generate serializable TestComponent struct and TestComponentAuthoringComponent monobehaviour class +to be added on game object. + +# Tags: +@ecs_gen_component - generates C# component +@ecs_gen_authoring - generates authoring monobehaviour to be added on game object +@ecs_serializable - makes component editable in inspector +@ecs_tag - marks component tag \ No newline at end of file diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..96878bd --- /dev/null +++ b/composer.json @@ -0,0 +1,17 @@ +{ + "name": "bit/metagen_cs_ecs", + "description": "C# Leo ECS codgen support from meta descriptions", + "homepage": "https://git.bit5.ru/bit/metagen_cs_ecs", + "require": { + "php": ">=7.4", + "twig/twig" : "v3.4.3", + "bit/metagen" : "^v2.0.2", + "bit/metagen_cs" : "^v1.0.5", + "bit/taskman_helpers" : "^v1.0.6" + }, + "autoload": { + "files": [ + "src/codegen.inc.php" + ] + } +} diff --git a/src/codegen.inc.php b/src/codegen.inc.php new file mode 100644 index 0000000..d05f303 --- /dev/null +++ b/src/codegen.inc.php @@ -0,0 +1,99 @@ +setCache($GAME_ROOT . "/build/twig/metagen_cs_ecs"); + $gen_components = new \mtgMetaInfo(); + $lock_file = "$GAME_ROOT/unity/Packages/metagen_autogen/Runtime/code/ecs/ecs.lock"; + + foreach ($meta->getUnits() as $unit) + { + if(!$unit->object->hasToken('ecs_gen_component') || !($unit->object instanceof \mtgUserType)) + continue; + $gen_components->addUnit($unit); + } + + if(!\taskman\need_to_regen($lock_file, get_meta_units_files($gen_components))) + { + return; + } + \taskman\rrmdir("$GAME_ROOT/unity/Packages/metagen_autogen/Runtime/code/ecs/"); + \taskman\ensure_write($lock_file, ""); + touch($lock_file); + + foreach ($gen_components->getUnits() as $unit) + { + $unit_name = $unit->object->getName(); + $filePath = str_replace(".", "/", $unit_name); + $file = "$GAME_ROOT/unity/Packages/metagen_autogen/Runtime/code/ecs/$filePath.cs"; + $name_components = explode('.', $unit_name); + $class_name = end($name_components); + if($class_name != $unit_name) + $namespace = str_replace(".$class_name", "", $unit_name); + else + $namespace = ""; + + // Костыль. Убрать, когда будет поддержка namespace в bhl_bind + if(empty($namespace)) + $namespace = "ecs"; + + \taskman\ensure_write_if_differs( + $file, + $twig->render('codegen_ecs_component.twig', [ + 'namespace' => $namespace, + 'class_name' => $class_name, + 'obj' => $unit->object, + 'imports' => [ + 'System.Collections', + 'System.Collections.Generic', + 'System', + 'BitGames', + 'BitGames.Autogen', + 'UnityEngine', + 'bhl', + 'Leopotam.Ecs' + ], + ]) + ); + + $file_authoring = "$GAME_ROOT/unity/Packages/metagen_autogen/Runtime/code/ecs/{$filePath}AuthoringComponent.cs"; + if($unit->object->hasToken('ecs_gen_authoring')) + { + \taskman\ensure_write_if_differs( + $file_authoring, + $twig->render('codegen_ecs_authoring.twig', [ + 'namespace' => $namespace, + 'class_name' => $class_name, + 'obj' => $unit->object + ]) + ); + } + } +} + +function get_meta_units_files(\mtgMetaInfo $meta) +{ + $files = array(); + foreach($meta->getUnits() as $u) + $files[$u->file] = true; + return array_keys($files); +} \ No newline at end of file diff --git a/tpl/codegen_ecs_authoring.twig b/tpl/codegen_ecs_authoring.twig new file mode 100644 index 0000000..5f81aad --- /dev/null +++ b/tpl/codegen_ecs_authoring.twig @@ -0,0 +1,13 @@ +{% if namespace != "" ~%} +namespace {{namespace}} +{ +{% endif %} + + public partial class {{class_name}}AuthoringComponent : BitGames.RND.EntityConversion.EntityAuthoringComponent<{{obj.name}}> + { + + } // {{obj.name}} + +{% if namespace != "" ~%} +} // namespace {{namespace}} +{% endif %} \ No newline at end of file diff --git a/tpl/codegen_ecs_component.twig b/tpl/codegen_ecs_component.twig new file mode 100644 index 0000000..204c50e --- /dev/null +++ b/tpl/codegen_ecs_component.twig @@ -0,0 +1,27 @@ +{%- for imp in imports ~%} +using {{imp}}; +{%- endfor ~%} + +{%- import "macro_ecs.twig" as macro_ecs -%} + +{% if namespace != "" ~%} +namespace {{namespace}} +{ +{% endif %} +{% if has_token(obj, 'ecs_serializable') %} + [System.Serializable] +{% endif %} +{% apply trim('\n:, ', 'right') %} + public partial struct {{class_name}} : +{% if has_token(obj, 'ecs_tag') %} Leopotam.Ecs.IEcsIgnoreInFilter,{% endif %} +{% endapply %} + + { + {% for field in obj.getfields %} + {{macro_ecs.ecs_component_field(obj, field)}} + {% endfor %} +} // {{obj.name}} + +{% if namespace != "" ~%} +} // namespace {{namespace}} +{% endif %} \ No newline at end of file diff --git a/tpl/macro_ecs.twig b/tpl/macro_ecs.twig new file mode 100644 index 0000000..072c8fd --- /dev/null +++ b/tpl/macro_ecs.twig @@ -0,0 +1,3 @@ +{%- macro ecs_component_field(obj, field) -%} + public {{field.type}} {{field.name}}; +{%- endmacro -%} \ No newline at end of file