Compare commits

..

18 Commits

Author SHA1 Message Date
Alexey Chubar 5c8760ed45 Streamline generated code
Publish PHP Package / docker (push) Successful in 6s Details
2025-04-14 17:37:16 +03:00
Pavel Shevaev ce24672649 For now using Val.New(..) instead of Val.NewNoReset() since the latter introduces some ownership related bug
Publish PHP Package / docker (push) Successful in 8s Details
2025-01-04 12:48:52 +03:00
Pavel Shevaev 66e9451e4a Migrating to more robust bhl_custom_rw semantics. Struct methods can affect the caller now, same applies to bhl_blob now
Publish PHP Package / docker (push) Successful in 6s Details
2024-12-28 15:20:09 +03:00
Pavel Shevaev 5144fe0e9a Обновить README.md 2024-12-18 18:36:26 +03:00
Pavel Shevaev b8aaaeb141 Обновить CHANGELOG.md 2024-12-18 18:34:50 +03:00
Pavel Shevaev b96b3996ba A bit minimizing codegen output for types setup
Publish PHP Package / docker (push) Successful in 6s Details
2024-12-17 22:27:09 +03:00
Pavel Shevaev eb85f63437 Splitting one huge output autobind file to many files presumed to be stored under non VCS directory
Publish PHP Package / docker (push) Successful in 7s Details
2024-12-17 20:00:45 +03:00
Pavel Shevaev 169cd07aaf Migrating to IList from ValList for []any bindings since it is more generic
Publish PHP Package / docker (push) Successful in 7s Details
2024-12-05 19:37:19 +03:00
Pavel Shevaev dd83313a7e Обновить CHANGELOG.md 2024-12-03 19:02:06 +03:00
Pavel Shevaev 8871e94a1b Proper retain for any Val in args
Publish PHP Package / docker (push) Successful in 6s Details
2024-12-03 18:37:09 +03:00
Pavel Shevaev d5e8a9fe58 A bit optimizing setters/getters codegen
Publish PHP Package / docker (push) Successful in 5s Details
2024-11-22 18:15:14 +03:00
Pavel Shevaev 2c87ea219b Adding @bhl_blob support
Publish PHP Package / docker (push) Successful in 6s Details
2024-11-22 17:45:29 +03:00
Pavel Shevaev 635095c3fb Обновить CHANGELOG.md 2024-11-21 14:36:19 +03:00
Pavel Shevaev 386fb3e773 Обновить CHANGELOG.md 2024-11-21 14:34:17 +03:00
Pavel Shevaev 8009edc026 Обновить CHANGELOG.md 2024-11-21 14:33:59 +03:00
Pavel Shevaev 31a431e69a Обновить CHANGELOG.md 2024-11-21 14:32:16 +03:00
Pavel Shevaev fb0c309947 Обновить README.md 2024-11-21 14:30:41 +03:00
Pavel Shevaev d7bdfa5cf0 Обновить README.md 2024-11-21 14:30:12 +03:00
9 changed files with 416 additions and 169 deletions

View File

@ -1,2 +1,30 @@
## v19.0.0
- Streamline generated code:
- Less inlining in enum bindings
- Functions returning a single value will share code for `ReturnValue` in common cases
- `IDisposable` boilerplate code will be generated only when `Args` actually need disposing
## v17.1.0
- Splitting one huge codegenerated file into multiple ones
## v16.0.0
- Migrating to IList from ValList for []any bindings since it is more generic
## v15.5.2
- Proper retain for any Val in args
- A bit optimizing setters/getters codegen
- Adding @bhl_blob support
## v15.4.2
- Using local static functions instead of lambdas for better stack traces
## v15.0.0
- Migrating to IList<T> instead of HList<T> for arguments as it is more versatile
- Adding codegen for disposal of arguments
## v14.0.0
- Making it possible to specify custom code
- Always adding `using bhl` directive to generated code
## v13.0.0
- Migrating to new BHL2-beta123 efficient native array wrappers
- Migrating to new BHL2-beta123 efficient native array wrappers

View File

@ -1,4 +1,4 @@
This package is used for code generation of bhl2 bindings for C# using Twig templates
This package is used for code generation of BHL bindings for C# using Twig templates
Here the example of bindings declaration:
@ -36,16 +36,14 @@ Here the example of bindings declaration:
Usage example:
$twig = \bhl_bind\get_twig();
$meta = \bhl_bind\prepare_meta($meta);
file_put_contents('autobind.cs',
$twig->render("codegen_autobind.twig",
$output = \bhl_bind\codegen(null, $meta,
[
'imports' => ['UnityEngine'],
'register_class' => 'BHL_AutoBindings',
'meta' => $meta
]
)
);
);
foreach($output as $name => $text)
file_put_contents($name, $text);

View File

@ -20,7 +20,9 @@ function supported_tokens()
'bhl_get',
'bhl_set',
'bhl_ref_arg',
'bhl_bin_op'
'bhl_bin_op',
'bhl_blob',
'bhl_refc',
];
}
@ -28,7 +30,7 @@ function codegen(
$tpl_cache_dir,
\mtgMetaInfo $meta,
array $options = array()
)
) : array
{
validate_meta($meta);
@ -56,14 +58,30 @@ function codegen(
$twig->addGlobal('plugins', $options['plugins']);
$str = $twig->render('codegen_autobind.twig', $options);
$sliced_units = slice_units($meta->getUnits(), 20);
$options['sliced_units'] = $sliced_units;
$output = array();
$output['types.cs'] = $twig->render('codegen_types.twig', $options);
$output['decl_units.cs'] = $twig->render('codegen_decl_units.twig', $options);
foreach($sliced_units as $slice_idx => $slice_units)
{
$slice_options = $options;
$slice_options['slice_idx'] = $slice_idx;
$slice_options['slice_units'] = $slice_units;
$output['register_'.$slice_idx.'.cs'] = $twig->render('codegen_register_slice.twig', $slice_options);
}
$output['register.cs'] = $twig->render('codegen_register.twig', $options);
print_warnings();
return $str;
return $output;
}
function get_twig(array $inc_path = [])
function get_twig(array $inc_path = []) : \Twig\Environment
{
array_unshift($inc_path, __DIR__ . "/../tpl/");
$loader = new \Twig\Loader\FilesystemLoader($inc_path);
@ -223,6 +241,14 @@ function add_twig_support(\Twig\Environment $twig)
return native_type($type);
}
));
$twig->addFilter(new \Twig\TwigFilter('native_class_name',
function($type)
{
if($type->hasToken('bhl_native_class'))
return $type->getToken('bhl_native_class');
return $type->getName();
}
));
$twig->addFilter(new \Twig\TwigFilter('norm_name',
function($name)
{
@ -257,7 +283,7 @@ function add_twig_support(\Twig\Environment $twig)
$twig->addFunction(new \Twig\TwigFunction('has_token',
function($o, $token)
{
return $o->hasToken($token);
return method_exists($o, 'hasToken') && $o->hasToken($token);
}
));
$twig->addFunction(new \Twig\TwigFunction('token',
@ -344,6 +370,26 @@ function add_twig_support(\Twig\Environment $twig)
return "Module".module_name($m).".ns";
}
));
$twig->addFunction(new \Twig\TwigFunction('has_disposable_args',
function(\mtgMetaFunc $fn)
{
foreach($fn->getArgs() as $arg)
{
$type = $arg->getType();
if(
$type instanceof \mtgArrType ||
$type instanceof \mtgMetaFunc ||
$type->getName() == "any"
)
{
return true;
}
}
return false;;
}
));
}
function Warn($msg)
@ -526,7 +572,7 @@ function native_type(\mtgType $type)
if($type instanceof \mtgArrType)
{
if($type->getValue()->getName() == "any")
return "bhl.ValList";
return "IList";
else
return "IList<".native_type($type->getValue()).">";
}

View File

@ -14,13 +14,27 @@
#if !BHL_FRONT
static bhl.Coroutine {{local_fn_name}}(VM.Frame frm, ValStack stack, FuncArgsInfo args_info, ref BHS status) {
{{ _self.read_args2natives(o, '__', this_type) }}
{{ _self.read_args2natives(o, '__') }}
{%- if this_type and not has_token(o, 'bhl_static') ~%}
var dv_self = stack.Pop();
{%if has_token(this_type, 'bhl_blob')%}ref{%endif%} var {{ _self.val2native(this_type, 'dv_self', '__self', true, has_token(this_type, 'bhl_blob')) }};
{%- endif ~%}
{%~ if o.returntype %}
var return_val =
{%- endif ~%}
{{this_prefix}}{{ _self.call_native_prefix_func(o, '__') }}
{%- if this_type and not has_token(o, 'bhl_static') ~%}
{%if has_token(this_type, 'bhl_custom_rw')%}
dv_self.Encode(__self);
{%- endif ~%}
dv_self.Release();
{%- endif ~%}
{# pass back and release ref args #}
{%- for arg in o.args -%}
{%- if has_token(arg, 'bhl_ref_arg') ~%}
@ -79,7 +93,9 @@
{%- if o.args -%}
var args = Script_{{o.name|norm_name}}.ReadArgs(frm, stack, args_info);
Script_{{o.name|norm_name}}.Exec(frm, args {{_self.out_results(o)}});
{% if has_disposable_args(o) ~%}
args.Dispose();
{%- endif ~%}
{%- else ~%}
Script_{{o.name|norm_name}}.Exec(frm {{_self.out_results(o)}});
{%- endif ~%}
@ -115,24 +131,60 @@
{%- endif -%}
{%- endmacro -%}
{%- macro return_out_results_single_common(type, var_name = 'result0') -%}
{%- if type == 'any' -%}
FuncRetValUtil.FuncReturnSingleValueRaw(frm, stack, {{ var_name }});
{%- else -%}
{%- if type is instanceof('\\mtgBuiltinType') -%}
{%- if type.isfloat -%}
FuncRetValUtil.FuncReturnSingleValueFloat(frm, stack, (double){{ var_name }});
{%- elseif type.isdouble -%}
FuncRetValUtil.FuncReturnSingleValueFloat(frm, stack, (double){{ var_name }});
{%- elseif type.isuint8 -%}
FuncRetValUtil.FuncReturnSingleValueInt(frm, stack, (double){{ var_name }});
{%- elseif type.isuint16 or type.isuint32 -%}
FuncRetValUtil.FuncReturnSingleValueInt(frm, stack, (double){{ var_name }});
{%- elseif type.isuint64 -%}
FuncRetValUtil.FuncReturnSingleValueInt(frm, stack, (double){{ var_name }});
{%- elseif type.isstring -%}
FuncRetValUtil.FuncReturnSingleValueString(frm, stack, (string){{ var_name }});
{%- elseif type.isbool -%}
FuncRetValUtil.FuncReturnSingleValueBool(frm, stack, (bool){{ var_name }});
{%- else -%}
FuncRetValUtil.FuncReturnSingleValueInt(frm, stack, (double){{ var_name }});
{%- endif -%}
{%- else -%}
{{Error('Unexpected type for single-value return optimization: ' ~ type)}}
{%- endif -%}
{%- endif -%}
{%- endmacro -%}
{%- macro return_out_results(o) -%}
{%- if o.returntype -%}
{%if not has_token(o, 'bhl_coroutine') and (o.returntype == 'any' or o.returntype is instanceof('\\mtgBuiltinType')) %}
{{ _self.return_out_results_single_common(o.returntype) }}
{%- else ~%}
Script_{{o.name|norm_name}}.ReturnValue(frm, stack
{%- for idx, type_item in types_array(o.returntype) -%}
, result{{idx}}
{%- endfor -%}
);
{%- endif -%}
{%- endif -%}
{%- endmacro -%}
{%- macro return_method_out_results(o, m) -%}
{%- if m.returntype -%}
{%if not has_token(m, 'bhl_coroutine') and (m.returntype == 'any' or m.returntype is instanceof('\\mtgBuiltinType')) %}
{{ _self.return_out_results_single_common(m.returntype) }}
{%- else ~%}
Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- for idx, type_item in types_array(m.returntype) -%}
, result{{idx}}
{%- endfor -%}
);
{%- endif -%}
{%- endif -%}
{%- endmacro -%}
{%- macro decl_func_partial_class(o, prefix, this_type = null) ~%}
@ -175,7 +227,9 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- else ~%}
var args = Script_{{o.name|norm_name}}.Method_{{m.name}}.ReadArgs(frm, stack, args_info);
Script_{{o.name|norm_name}}.Method_{{m.name}}.Exec(frm, args {{_self.out_results(m)}});
{% if has_disposable_args(m) ~%}
args.Dispose();
{%- endif ~%}
{{_self.return_method_out_results(o, m)}}
return null;
{%- endif ~%}
@ -211,7 +265,9 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
var args = Script_{{o.name|norm_name}}.Method_{{m.name}}.ReadArgs(frm, stack, args_info);
Script_{{o.name|norm_name}}.Method_{{m.name}}.Exec(frm, args {{_self.out_results(m)}});
{% if has_disposable_args(m) ~%}
args.Dispose();
{% endif ~%}
{{_self.return_method_out_results(o, m)}}
return null;
@ -257,7 +313,9 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
public override void Cleanup(VM.Frame frm, bhl.VM.ExecState exec) {
Cleanup(frm);
{% if o.args or this_type ~%}
{% if has_disposable_args(o) ~%}
args.Dispose();
{% endif %}
args = default;
{% endif %}
}
@ -265,7 +323,11 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- endmacro -%}
{%- macro Args(o, this_type) ~%}
public struct Args : IDisposable {
public struct Args
{% if has_disposable_args(o) ~%}
: IDisposable
{% endif %}
{
{% if this_type and not has_token(o, 'bhl_static') ~%}
public {{this_type|native_type}} self;
{% endif %}
@ -275,10 +337,12 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{% endfor %}
{% if has_disposable_args(o) ~%}
public void Dispose()
{
{{ _self.dispose_args(o) }}
}
{% endif %}
}
{%- endmacro -%}
@ -291,10 +355,8 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- endmacro -%}
{%- macro ReturnValue(o) -%}
{%if o.returntype == 'any' %}
static public void ReturnValue(VM.Frame frm, ValStack stack, bhl.Val dv) {
stack.Push(dv);
}
{%if not has_token(o, 'bhl_coroutine') and (o.returntype == 'any' or o.returntype is instanceof('\\mtgBuiltinType')) %}
//Will use shared return function {{_self.return_out_results_single_common(o.returntype)}}
{% else ~%}
static public void ReturnValue(VM.Frame frm, ValStack stack,
{%- for idx, type_item in types_array(o.returntype) -%}
@ -320,7 +382,6 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- if this_type ~%}
{{this_type|native_type}} {{prefix}}self = default;
{%- endif -%}
{%- for v in vars -%}
{%- if has_token(v, 'bhl_ref_arg') -%}
bhl.Val {{prefix}}{{v.name}} = default;
@ -350,11 +411,12 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- set default_counter = default_counter + 1 -%}
if(!args_info.IsDefaultArgUsed({{o.args|length - count_required_args(o) - default_counter}}))
{%- endif ~%}
{
{%- if has_token(arg, 'bhl_ref_arg') ~%}
var dv = stack.Pop();
{{arg_prefix}}{{arg.name}} = dv;
{%- if not has_token(arg.type, 'bhl_custom_rw') -%}
{%- if not has_token(arg.type, 'bhl_custom_rw') and not has_token(arg.type, 'bhl_blob') -%}
{{ _self.val2native(arg.type, 'dv', arg_prefix ~ 'ref_' ~ arg.name, true) }};
{%- endif ~%}
{%- else ~%}
@ -363,6 +425,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
dv.Release();
{%- endif ~%}
}
{#-default arg value-#}
{%- if has_token(arg, 'default') ~%}
else
@ -384,16 +447,11 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- macro dispose_args(o, arg_prefix = '') -%}
{%- for arg in o.args -%}
{% if arg.type is instanceof('\\mtgArrType') %}
{% if arg.type.value.name == 'any' %}
{{arg_prefix}}{{arg.name}}?.Release();
{{arg_prefix}}{{arg.name}} = default;
{% else %}
{
if({{arg_prefix}}{{arg.name}} is IValRefcounted rfc)
rfc.Release();
{{arg_prefix}}{{arg.name}} = default;
}
{% endif %}
{% endif %}
{% if arg.type.name == 'any' %}
@ -445,10 +503,11 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- endfor -%}
{%- endmacro -%}
{%- macro val2native(type, value, native, is_arg = false) -%}
{%- macro val2native(type, value, native, is_arg = false, is_ref = false) -%}
{# any special case #}
{%- if type == 'any' -%}
{{native}} = {{value}}
{{native}} = {{value}};
{{native}}.Retain();
{%- else -%}
{%~ if type is instanceof('\\mtgMetaFunc') -%}
@ -462,7 +521,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%~ if type == 'any[]'-%}
{{native}} = (ValList){{value}}._obj;
{{native}} = (IList){{value}}._obj;
{%~ else ~%}
@ -496,8 +555,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
for(int i=0;i<_src_arr_count;++i)
{
var _arr_item = _src_arr_type.ArrGetAt({{value}}, i);
{#TODO: get rid of replace hack below#}
{{('var ' ~ _self.val2native(type.value, '_arr_item', 'tmp'))|replace({'tmp = tmp' : '', 'var var' : 'var'})}};
var {{_self.val2native(type.value, '_arr_item', 'tmp')}};
if(i < _dst_before_count)
{{native}}[i] = tmp;
else
@ -533,12 +591,14 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- if type is instanceof('\\mtgUserType') -%}
{%- if type is instanceof('\\mtgMetaEnum') -%}
{{native}} = ({{token_or(type, 'bhl_native_class', type.name)}})((int){{value}}._num)
{{native}} = ({{type|native_class_name}})((int){{value}}._num)
{%- else -%}
{%- if has_token(type, 'bhl_custom_rw') -%}
var tmp = new {{token_or(type, 'bhl_native_class', type.name)}}(); {{value}}.Decode(ref tmp); {{native}} = tmp
{{native}} = {{value}}.Decode(new {{type|native_class_name}}())
{%- elseif has_token(type, 'bhl_blob') -%}
{{native}} = {%if is_ref%}ref{%endif%} {{value}}.GetBlob<{{type|native_class_name}}>()
{%- else -%}
{{native}} = ({{token_or(type, 'bhl_native_class', type.name)}}){{value}}._obj
{{native}} = ({{type|native_class_name}}){{value}}._obj
{%- endif -%}
{%- endif -%}
{%- endif -%}
@ -553,7 +613,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- else -%}
{%- if type is instanceof('\\mtgMetaFunc') -%}
{{value}}.SetObj({{native}}, Types.Any)
{{value}}.SetObj({{native}}, Types.Any/*TODO: use real type?*/)
{%- endif -%}
{%- if type is instanceof('\\mtgArrType') -%}
@ -593,8 +653,12 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- else -%}
{%- if has_token(type, 'bhl_custom_rw') -%}
{{value}}.Encode({{native}})
{%- else -%}
{%- elseif has_token(type, 'bhl_blob') -%}
{{value}}.SetBlob({{native}}, Types_{{type.name|norm_name}}.Value)
{%- elseif has_token(type, 'bhl_refc') -%}
{{value}}.SetObj({{native}}, Types_{{type.name|norm_name}}.Value)
{%- else -%}
{{value}}.SetObjNoRefc({{native}}, Types_{{type.name|norm_name}}.Value)
{%- endif -%}
{%- endif -%}
{%- endif -%}
@ -616,8 +680,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
"{{o.name}}",
(v) => {
#if !BHL_FRONT
{#TODO: get rid of replace hack below#}
{{('var ' ~ _self.val2native(token(o, 'bhl_native_arr_proxy'), 'v', 'tmp'))|replace({'tmp = tmp' : '', 'var var' : 'var'})}};
var {{_self.val2native(token(o, 'bhl_native_arr_proxy'), 'v', 'tmp')}};
return tmp;
#else
return null;
@ -642,25 +705,25 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- macro reg_enum(o, scope = 'types.ns') ~%}
{
var en = new EnumSymbolNative(new Origin(), "{{o.name|ns_last}}"
const string enumName = "{{o.name|ns_last}}";
var en = new EnumSymbolNative(new Origin(), enumName
#if !BHL_FRONT
, typeof({{token_or(o, 'bhl_native_class', o.name)}})
, typeof({{o|native_class_name}})
#else
, null
#endif
);
System.Type nativeType = null;
#if !BHL_FRONT
nativeType = en.GetNativeType();
#endif
{{scope}}.{{o.name|ns_prefix}}Define(en);
{%- for fname,v in o.values ~%}
{
#if !BHL_FRONT
if(Enum.GetName(en.GetNativeType(), {{v}}) != "{{fname}}")
throw new Exception("Enum '{{o.name}}' names don't match at value " + {{v}});
#endif
en.Define(new EnumItemSymbol(new Origin(), "{{fname}}", (int){{v}}));
}
RegisterEnumValue(en, nativeType, enumName, "{{fname}}", (int){{v}});
{%~ endfor -%}
}
@ -677,15 +740,19 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{% if not has_token(o, 'bhl_no_new') ~%}
static void ctor_{{o.name|norm_name}}(VM.Frame frm, ref Val v, IType type) {
#if !BHL_FRONT
var o = new {{token_or(o, 'bhl_native_class', o.name)}}({{token_or(o, 'bhl_native_class_params', '')}});
{%if has_token(o, 'bhl_custom_rw') %}
v.Encode(o);
{% else %}
var o = new {{o|native_class_name}}({{token_or(o, 'bhl_native_class_params', '')}});
{% if has_token(o, 'POD') %}
o.Reset();
o.Reset(); //resetting POD
{% endif %}
{% if has_token(o, 'bhl_custom_rw') %}
v.Encode(o);
{% elseif has_token(o, 'bhl_blob') %}
v.SetBlob(ref o, type);
{% elseif has_token(o, 'bhl_refc') %}
v.SetObj(o, type);
{% else %}
v.SetObjNoRefc(o, type);
{% endif %}
#endif
}
@ -713,20 +780,22 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
creator: ctor_{{o.name|norm_name}}
{% endif ~%}
#if !BHL_FRONT
, native_type: typeof({{token_or(o, 'bhl_native_class', o.name)}})
, native_type: typeof({{o|native_class_name}})
{% if has_token(o, 'bhl_custom_rw') %}
, native_object_getter: (v) => {
var tmp = new {{token_or(o, 'bhl_native_class', o.name)}}();
v.Decode(ref tmp);
return tmp;
return v.Decode(new {{o|native_class_name}}());
}
{% elseif has_token(o, 'bhl_blob') %}
, native_object_getter: (v) => {
return v.GetBlob<{{o|native_class_name}}>();
}
{% endif %}
#endif
);
{{scope}}.{{o.name|ns_prefix}}Define(cl);
{% if has_token(o, 'POD') and not has_token(o, 'bhl_custom_rw') %}
{{Warn("POD boxing '" ~ o.name ~ "'")}}
{% if has_token(o, 'POD') and not has_token(o, 'bhl_custom_rw') and not has_token(o, 'bhl_blob') %}
{{Warn("POD boxing '" ~ o.name ~ " (use @bhl_custom_rw or @bhl_blob)'")}}
{% endif %}
{% for f in o.getfields %}
@ -754,17 +823,18 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%- macro class_field(o, f) -%}
{% set class = token_or(o, 'bhl_native_class', o.name) %}
{% set class = o|native_class_name %}
{
{% if token_or(f, 'bhl_get', 1) != 0 ~%}
static void get_{{o.name|norm_name}}_{{f.name}}(VM.Frame frm, Val ctx, ref Val v, FieldSymbol fld) {
#if !BHL_FRONT
{%~ if has_token(o, 'bhl_custom_rw') ~%}
{{class}} f = new {{class}}();
ctx.Decode(ref f);
{{class}} f = ctx.Decode(new {{class}}());
{%- elseif has_token(o, 'bhl_blob') ~%}
ref var f = ref ctx.GetBlob<{{class}}>();
{%- else ~%}
var f = ({{class}})ctx.obj;
var f = ({{class}})ctx._obj;
{%- endif ~%}
{% if token(f, 'bhl_get') == 2 %}
@ -785,14 +855,15 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
static void set_{{o.name|norm_name}}_{{f.name}}(VM.Frame frm, ref Val ctx, Val v, FieldSymbol fld) {
#if !BHL_FRONT
{%~ if has_token(o, 'bhl_custom_rw') ~%}
{{class}} f = new {{class}}();
ctx.Decode(ref f);
{{class}} f = ctx.Decode(new {{class}}());
{%- elseif has_token(o, 'bhl_blob') ~%}
ref var f = ref ctx.GetBlob<{{class}}>();
{%- else ~%}
var f = ({{class}})ctx.obj;
var f = ({{class}})ctx._obj;
{%- endif ~%}
{% if token(f, 'bhl_set') == 2 %}
{{_self.val2native(f.type, 'v', 'var nv')}};
var {{_self.val2native(f.type, 'v', 'nv')}};
Script_{{o.name|norm_name}}.Set_{{f.name}}(ref f, nv);
{% else %}
{%- if has_token(f, 'bhl_native_prefix') -%}
@ -804,8 +875,10 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{%~ if has_token(o, 'bhl_custom_rw') ~%}
ctx.Encode(f);
{%~ elseif has_token(o, 'bhl_blob') ~%}
//nothing for blob
{%- else ~%}
ctx.SetObj(f, ctx.type);
ctx._obj = f;
{%- endif ~%}
#endif
}
@ -843,7 +916,7 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
var ifs = new InterfaceSymbolNative(new Origin(), "{{o.name|ns_last}}", proxy_inherits: null
#if !BHL_FRONT
, native_type: typeof({{token_or(o, 'bhl_native_class', o.name)}})
, native_type: typeof({{o|native_class_name}})
#else
, native_type: null
#endif
@ -864,11 +937,15 @@ Script_{{o.name|norm_name}}.Method_{{m.name}}.ReturnValue(frm, stack
{{Error('Not implemented for multipled returns')}}
{%- endif ~%}
{%if not has_token(f, 'bhl_coroutine') and (f.returntype == 'any' or f.returntype is instanceof('\\mtgBuiltinType')) %}
{{ _self.return_out_results_single_common(f.returntype, 'return_val') }};
{%- else -%}
{
var dv = bhl.Val.New(frm.vm);
{{ _self.native2val(f.returntype, return_var, 'dv') }};
stack.Push(dv);
}
{%- endif ~%}
{%- endif ~%}
{%- endmacro -%}
@ -905,21 +982,6 @@ public partial class Script_{{u.object.name}} {
{%- endmacro -%}
{%- macro call_reg_units(sliced_units) ~%}
{%- for idx,units in sliced_units -%}
Register_{{idx}}(types);
{%~ endfor -%}
{%- endmacro -%}
{%- macro decl_reg_units(sliced_units) ~%}
{%- for idx,units in sliced_units -%}
public static void Register_{{idx}}(Types types)
{
{{ _self.reg_units(units) }}
}
{%~ endfor -%}
{%- endmacro -%}
{%- macro reg_units(units) ~%}
{%- for u in units -%}
@ -959,18 +1021,7 @@ public partial class Script_{{u.object.name}} {
//assign global static types
{%- for u in units -%}
{%- if u.object is instanceof('\\mtgMetaStruct') or u.object is instanceof('\\mtgMetaInterface') ~%}
{
var tmp = types.T("{{u.object.name}}").Get();
if(tmp == null)
throw new System.Exception("Type '{{u.object.name}}' not resolved");
{%- if u.object is instanceof('\\mtgMetaStruct') ~%}
(tmp as ClassSymbolNative)?.Setup();
{%- endif ~%}
{%- if u.object is instanceof('\\mtgMetaInterface') ~%}
(tmp as InterfaceSymbolNative)?.Setup();
{%- endif ~%}
Types_{{u.object.name|norm_name}}.Value = tmp;
}
Types_{{u.object.name|norm_name}}.Value = SetupType(types, "{{u.object.name}}");
{%- endif -%}
{%- endfor -%}

View File

@ -1,70 +0,0 @@
#pragma warning disable CS0162
using System;
using System.Collections;
using System.Collections.Generic;
using bhl;
#if !BHL_FRONT
{%- for imp in imports ~%}
using {{imp}};
{%- endfor ~%}
#endif
{{custom_code}}
{% import "bhl_bind_macro.twig" as macro %}
namespace {{namespace}} {
{%- for u in meta.units ~%}
{%- if u.object is instanceof('\\mtgMetaStruct') or u.object is instanceof('\\mtgMetaInterface') ~%}
static public class Types_{{u.object.name|norm_name}} {
static public IType Value;
}
{%- endif ~%}
{%- endfor ~%}
#if !BHL_FRONT
{{ macro.decl_units(meta.units) }}
{{ plugins_codegen_decls() }}
#endif
static public class {{register_class}} {
{%- for mk,mv in get_modules(meta) ~%}
static public Module Module{{mv}};
{%- endfor ~%}
{{ plugins_register_decls() }}
public static void Register(Types types)
{
RegisterBegin(types);
RegisterEnd(types);
{{ plugins_codegen_register() }}
}
public static void RegisterBegin(Types types)
{
{%- for mk,mv in get_modules(meta) ~%}
Module{{mv}} = new Module(types, "{{mk}}");
types.RegisterModule(Module{{mv}});
{%- endfor ~%}
{{ macro.call_reg_units(slice_units(meta.units, 20)) }}
}
public static void RegisterEnd(Types types)
{
{{ macro.setup_global_types(meta.units) }}
}
{{ macro.decl_reg_units(slice_units(meta.units, 20)) }}
}
}

View File

@ -0,0 +1,26 @@
#pragma warning disable CS0162
using System;
using System.Collections;
using System.Collections.Generic;
using bhl;
#if !BHL_FRONT
{%- for imp in imports ~%}
using {{imp}};
{%- endfor ~%}
#endif
using Types = bhl.Types;
{% import "bhl_bind_macro.twig" as macro %}
namespace {{namespace}} {
#if !BHL_FRONT
{{ macro.decl_units(meta.units) }}
{{ plugins_codegen_decls() }}
#endif
}

118
tpl/codegen_register.twig Normal file
View File

@ -0,0 +1,118 @@
#pragma warning disable CS0162
using System;
using System.Collections;
using System.Collections.Generic;
using bhl;
#if !BHL_FRONT
{%- for imp in imports ~%}
using {{imp}};
{%- endfor ~%}
#endif
using Types = bhl.Types;
{{custom_code}}
{% import "bhl_bind_macro.twig" as macro %}
namespace {{namespace}} {
static public partial class {{register_class}} {
{%- for mk,mv in get_modules(meta) ~%}
static public Module Module{{mv}};
{%- endfor ~%}
{{ plugins_register_decls() }}
public static void Register(Types types)
{
RegisterBegin(types);
RegisterEnd(types);
{{ plugins_codegen_register() }}
}
public static void RegisterBegin(Types types)
{
{%- for mk,mv in get_modules(meta) ~%}
Module{{mv}} = new Module(types, "{{mk}}");
types.RegisterModule(Module{{mv}});
{%- endfor ~%}
{%- for idx,units in sliced_units -%}
Register_{{idx}}(types);
{%~ endfor -%}
}
static IType SetupType(Types types, string name)
{
var tmp = types.T(name).Get();
if(tmp == null)
throw new System.Exception("Type '" + name + "' not resolved");
if(tmp is ClassSymbolNative csn)
csn.Setup();
else if(tmp is InterfaceSymbolNative isn)
isn.Setup();
return tmp;
}
public static void RegisterEnd(Types types)
{
{{ macro.setup_global_types(meta.units) }}
}
static void RegisterEnumValue(EnumSymbolNative en, System.Type nativeType, string enumName, string valName, int val)
{
{
#if !BHL_FRONT
if(Enum.GetName(nativeType, val) != valName)
throw new Exception($"Enum '{enumName}' names don't match at value {val}");
#endif
en.Define(new EnumItemSymbol(new Origin(), valName, val));
}
}
}
static public class FuncRetValUtil {
public static void FuncReturnSingleValueInt(VM.Frame frm, ValStack stack, double v0)
{
var dv0 = bhl.Val.New(frm.vm);
dv0.SetInt(v0);
stack.Push(dv0);
}
public static void FuncReturnSingleValueBool(VM.Frame frm, ValStack stack, bool v0)
{
var dv0 = bhl.Val.New(frm.vm);
dv0.SetBool(v0);
stack.Push(dv0);
}
public static void FuncReturnSingleValueFloat(VM.Frame frm, ValStack stack, double v0)
{
var dv0 = bhl.Val.New(frm.vm);
dv0.SetFlt(v0);
stack.Push(dv0);
}
public static void FuncReturnSingleValueString(VM.Frame frm, ValStack stack, string v0)
{
var dv0 = bhl.Val.New(frm.vm);
dv0.SetStr(v0);
stack.Push(dv0);
}
public static void FuncReturnSingleValueRaw(VM.Frame frm, ValStack stack, bhl.Val dv0)
{
stack.Push(dv0);
}
}
}

View File

@ -0,0 +1,26 @@
#pragma warning disable CS0162
using System;
using System.Collections;
using System.Collections.Generic;
using bhl;
#if !BHL_FRONT
{%- for imp in imports ~%}
using {{imp}};
{%- endfor ~%}
#endif
using Types = bhl.Types;
{% import "bhl_bind_macro.twig" as macro %}
namespace {{namespace}} {
static public partial class {{register_class}} {
public static void Register_{{slice_idx}}(Types types)
{
{{ macro.reg_units(slice_units) }}
}
}
}

24
tpl/codegen_types.twig Normal file
View File

@ -0,0 +1,24 @@
#pragma warning disable CS0162
using System;
using System.Collections;
using System.Collections.Generic;
using bhl;
#if !BHL_FRONT
{%- for imp in imports ~%}
using {{imp}};
{%- endfor ~%}
#endif
using Types = bhl.Types;
namespace {{namespace}} {
{%- for u in meta.units ~%}
{%- if u.object is instanceof('\\mtgMetaStruct') or u.object is instanceof('\\mtgMetaInterface') ~%}
static public class Types_{{u.object.name|norm_name}} {
static public IType Value;
}
{%- endif ~%}
{%- endfor ~%}
}