Gradually migrating to new metagen

This commit is contained in:
Pavel Shevaev 2022-12-07 11:49:34 +03:00
parent 7e8720b387
commit b84c9f5467
2 changed files with 179 additions and 6 deletions

View File

@ -78,6 +78,30 @@ function _add_twig_support(\Twig\Environment $twig)
return var_reset($name, $type, $default);
}
));
$twig->addFunction(new \Twig\TwigFunction('var_sync',
function($name, $type, $buf, $tokens, $opts)
{
return var_sync($name, $type, $buf, $tokens, $opts);
}
));
$twig->addFunction(new \Twig\TwigFunction('get_sync_opts',
function($o, $name)
{
return get_sync_opts($o, $name);
}
));
$twig->addFunction(new \Twig\TwigFunction('fields_count',
function($o)
{
return fields_count($o);
}
));
$twig->addFunction(new \Twig\TwigFunction('is_primary_field',
function($o, $f)
{
return is_primary_field($o, $f);
}
));
}
function cs_type(\mtgType $type)
@ -278,6 +302,112 @@ function var_reset($name, \mtgType $type, $default = null)
return $str;
}
function var_sync($fname, \mtgType $type, $buf, array $tokens, $opts)
{
$optional = array_key_exists('optional', $tokens);
if($optional)
$opts .= " | MetaSyncFieldOpts.SKIP_OPTIONAL";
$str = '';
if($type instanceof \mtgBuiltinType)
{
$str .= "Meta.Sync({$buf}, ref {$fname}, {$opts});\n";
}
else if($type instanceof \mtgMetaStruct)
{
if(array_key_exists('virtual', $tokens))
$str .= "{$fname} = ({$type->getName()})Meta.SyncGeneric({$buf}, {$fname}, {$opts});\n";
else
$str .= "Meta.Sync({$buf}, ref {$fname}, {$opts});\n";
}
else if($type instanceof \mtgMetaEnum)
{
$str .= "int __tmp_{$fname} = (int)$fname;\n";
$str .= "Meta.Sync({$buf}, ref __tmp_{$fname}, {$opts});\n";
$str .= "if($buf.is_read) {$fname} = ({$type->getName()})__tmp_{$fname};\n";
}
else if($type instanceof \mtgArrType)
{
if(array_key_exists('virtual', $tokens))
$str .= "Meta.SyncGeneric({$buf}, {$fname}, {$opts});\n";
else
{
if($type->getValue() instanceof \mtgMetaEnum)
{
$str .= "Meta.tmp_enums_list.Clear(); if(!{$buf}.is_read) { foreach(var _enum_tmp in {$fname}) Meta.tmp_enums_list.Add((int)_enum_tmp); }\n";
$str .= "Meta.Sync({$buf}, Meta.tmp_enums_list, {$opts});\n";
$str .= "if({$buf}.is_read) foreach(var _int_tmp in Meta.tmp_enums_list) { {$fname}.Add(({$type->getValue()->getName()}) _int_tmp); }\n";
}
else
$str .= "Meta.Sync({$buf}, {$fname}, {$opts});\n";
}
}
else
throw new Exception("Unknown type '$type'");
return $str;
}
function get_sync_opts(\mtgMetaStruct $struct, string $bitctx_name)
{
$opts = array();
if($struct->hasToken("bitfields"))
$opts[] = "$bitctx_name.GetNextOpts()";
if(count($opts) == 0)
return "0";
return implode(" | ", $opts);
}
function fields_count(\mtgMetaStruct $struct)
{
//NOTE: why not using fields_count(..) here as well?
// (becase they include i18n fields already?)
$count = count($struct->getFields());
$curr = $struct->getParent();
while($curr)
{
$count += fields_count_self($curr);
$curr = $curr->getParent();
}
return $count;
}
function fields_count_self(\mtgMetaStruct $struct)
{
$fields = $struct->getFields();
$count = 0;
foreach($fields as $field)
{
//TODO: do we still need this
if($field->hasToken('i18n'))
$count += 2;
else
$count += 1;
}
return $count;
}
function is_primary_field(\mtgMetaStruct $struct, $fld)
{
$primary_fields = array();
if($struct->hasToken("id"))
$primary_fields[] = $struct->getToken("id");
if($struct->hasToken("owner"))
$primary_fields[] = $struct->getToken("owner");
if($struct->hasToken("pkey"))
{
foreach(explode(",", $struct->getToken("pkey")) as $name)
$primary_fields[] = $name;
}
return in_array($fld->getName(), $primary_fields);
}
function is_nullable_type(\mtgType $type)
{
return $type instanceof \mtgArrType ||

View File

@ -12,6 +12,9 @@
{% endmacro %}
{% macro decl_struct(o, extra = '') %}
{%- if o.parent and has_token(o, 'POD') -%}
{{Error("@POD structs can't have a parent: " ~ o.name)}}
{%- endif -%}
{%- if o.parent and has_token(o, 'bitfields') -%}
{{Error("@bitfields structs can't have a parent: " ~ o.name)}}
{%- endif -%}
@ -54,6 +57,7 @@ public {{_self.struct_type(o)}} {{o.name}} {{_self.base_class(o)}}
reset();
syncFields(ctx);
ctx.reader.EndContainer();
{{_self.copy_fields(o)}}
}
@ -67,19 +71,27 @@ public {{_self.struct_type(o)}} {{o.name}} {{_self.base_class(o)}}
public {{_self.override(o)}} void syncFields(MetaSyncContext ctx)
{
%bitfields_sync_context%
%sync_buffer%
{{_self.sync_fields(o)}}
}
public {{_self.override(o)}} int getFieldsCount()
{
return %fields_count%;
return {{fields_count(o)}};
}
public {{_self.override(o)}} int getWritableFieldsCount()
{
return %dirty_fields_count%;
{%- if has_token(o, 'bitfields') ~%}
return Meta.GetDirtyFieldsCount(fields_mask, fields_count: {{fields_count(o)}})
+ Meta.MASK_HEADER_FIELDS_COUNT;
{%- else -%}
return {{fields_count(o)}};
{%- endif ~%}
}
{%- if has_token(o, 'bitfields') ~%}
{{_self.bitmask_helpers(o)}}
{%- endif -%}
{{extra}}
}
@ -146,7 +158,7 @@ override
{%- macro comment_POD_begin(o) -%}
{%- if has_token(o, 'POD') -%}
/*
/* commented in POD
{%- endif -%}
{%- endmacro -%}
@ -158,7 +170,7 @@ override
{%- macro comment_non_cloneable_begin(o) -%}
{%- if not has_token(o, 'cloneable') -%}
/*
/* commented in non-cloneable
{%- endif -%}
{%- endmacro -%}
@ -184,6 +196,37 @@ fields_mask = other.fields_mask;
{%- endif -%}
{%- endmacro -%}
{%- macro sync_fields(o) -%}
{%- if has_token(o, 'bitfields') ~%}
var bitctx = new Meta.BitfieldsContext(ctx, fields_mask);
bitctx.SyncMaskHeader();
{%- endif -%}
{%- if o.parent ~%}
base.syncFields(ctx);
{%- endif -%}
{%- for f in o.fields ~%}
{{var_sync(f.name, f.type, 'ctx', f.tokens, get_sync_opts(o, 'bitctx'))}}
{%- endfor -%}
{%- endmacro -%}
{%- macro bitmask_helpers(o) ~%}
public void ResetFieldMask()
{
fields_mask = 0L;
}
public void SetPrimaryFieldsChanged()
{
{%- for f in o.fields ~%}
{%- if is_primary_field(o, f) ~%}
Meta.SetFieldDirty(ref fields_mask, {{loop.index0}});
{%- endif -%}
{%- endfor ~%}
}
{%- endmacro -%}
{% macro decl_enum(o) %}
{% endmacro %}