generating id structs, using generated structs during diff computation

This commit is contained in:
Pavel Merzlyakov 2023-06-06 14:48:42 +03:00
parent 5816f3cf7f
commit 85ed3d9b79
1 changed files with 56 additions and 66 deletions

View File

@ -18,6 +18,10 @@
{% endmacro %}
{% macro decl_struct(o, extra = '') %}
{% set pkey_fields = token(o, 'table_pkey')|split(',') %}
{% set pkey = o.fields|filter(f => f.name in pkey_fields ) %}
{%- if o.parent and has_token(o, 'POD') -%}
{{Error("@POD structs can't have a parent: " ~ o.name)}}
{%- endif -%}
@ -99,10 +103,24 @@ public {{_self.struct_type(o)}} {{o.name}} {{_self.base_struct_class(o)}}
{{_self.bitmask_helpers(o)}}
{%- endif -%}
{%- if has_token(o, 'id') ~%}
public ulong getPrimaryId()
{%- if has_token(o, 'table') ~%}
public static bool operator <({{o.name}} o1, {{o.name}} o2)
{
return (ulong){{token(o, 'id')}};
return {{o.name}}Comparer.self.Compare(o1, o2) < 0;
}
public static bool operator >({{o.name}} o1, {{o.name}} o2)
{
return {{o.name}}Comparer.self.Compare(o1, o2) > 0;
}
public {{o.name}}Id MakeId()
{
return new {{o.name}}Id{
{% for f in pkey %}
{{f.name}} = {{f.name}},
{% endfor %}
};
}
{%- endif -%}
@ -115,6 +133,27 @@ public {{_self.struct_type(o)}} {{o.name}} {{_self.base_struct_class(o)}}
{{extra}}
}
{%- if has_token(o, 'table') ~%}
public class {{o.name}}Comparer : IComparer<{{o.name}}>
{
public readonly static {{o.name}}Comparer self = new {{o.name}}Comparer();
public int Compare({{o.name}} o1, {{o.name}} o2)
{
int result;
{% for f in pkey %}
{% if not loop.first %}
if(result == 0)
{% endif %}
result = o1.{{f.name}}.CompareTo(o2.{{f.name}});
{% endfor %}
return result;
}
}
{%- endif ~%}
{% endmacro %}
{%- macro decl_struct_fields(o) -%}
@ -332,10 +371,12 @@ public class {{o.name}} : IRpc
{%- macro diffable_support(o) -%}
public bool GetDiff({{o.name}} old, {{o.name}} diff = null, List<DataClassIds> removed = null)
public bool GetDiff({{o.name}} old, {{o.name}} diff = null, {{o.name}}RemovedIds removed = null)
{
if(diff != null)
diff.reset();
if(removed != null)
removed.reset();
bool no_changes = true;
{% set field_idx = -1 %}
@ -354,52 +395,22 @@ public class {{o.name}} : IRpc
{{_self.diff_methods_for(u)}}
{% endfor %}
static public List<ulong> GetClassRemovedIds(List<DataClassIds> removed_ids, uint class_id)
{
if(removed_ids == null)
return null;
DataClassIds res;
if(!FindClassRemovedIds(removed_ids, class_id, out res))
{
res = new DataClassIds();
res.class_id = class_id;
res.ids = new List<ulong>();
removed_ids.Add(res);
}
return res.ids;
}
static bool FindClassRemovedIds(List<DataClassIds> removed_ids, uint class_id, out DataClassIds res)
{
for(int i=0;i<removed_ids.Count;++i)
{
if(removed_ids[i].class_id == class_id)
{
res = removed_ids[i];
return true;
}
}
res = default(DataClassIds);
return false;
}
{% endmacro %}
{%- macro diff_methods_for(u) -%}
static public bool DiffOne(ref {{u.name}} curr, {{u.name}} old)
{
return !{{_self.compare_func_name(u)}}(ref curr, old);
}
static public bool DiffCollection(List<{{u.name}}> items, List<{{u.name}}> old_items, List<{{u.name}}> changed, List<DataClassIds> removed)
static public bool DiffCollection(List<{{u.name}}> items, List<{{u.name}}> old_items, List<{{u.name}}> changed, List<{{u.name}}Id> removed)
{
bool has_diff = false;
if(changed != null)
changed.Clear();
SortByPrimaryId(ref items);
SortByPrimaryId(ref old_items);
items.Sort({{u.name}}Comparer.self);
old_items.Sort({{u.name}}Comparer.self);
int i = 0;
int old_i = 0;
@ -408,15 +419,13 @@ public class {{o.name}} : IRpc
var old = old_items[old_i];
var item = items[i];
if(old.getPrimaryId() < item.getPrimaryId())
if(old < item)
{
var removed_ids = GetClassRemovedIds(removed, {{u.name}}.STATIC_CLASS_ID);
if(removed_ids != null)
removed_ids.Add(old.getPrimaryId());
removed.Add(old.MakeId());
old_i++;
has_diff = true;
}
else if(old.getPrimaryId() > item.getPrimaryId())
else if(old > item)
{
item.SetDirtyMask();
if(changed != null)
@ -451,9 +460,7 @@ public class {{o.name}} : IRpc
//old items leftovers are considered removed
for(; old_i < old_items.Count; old_i++)
{
var removed_ids = GetClassRemovedIds(removed, {{u.name}}.STATIC_CLASS_ID);
if(removed_ids != null)
removed_ids.Add(old_items[old_i].getPrimaryId());
removed.Add(old_items[old_i].MakeId());
has_diff = true;
}
@ -465,25 +472,6 @@ public class {{o.name}} : IRpc
return has_diff;
}
class {{u.name}}Compare : IComparer<{{u.name}}>
{
public int Compare({{u.name}} o1, {{u.name}} o2)
{
var id1 = o1.getPrimaryId();
var id2 = o2.getPrimaryId();
if(id1 == id2)
return 0;
return id1 > id2 ? 1 : -1;
}
}
static {{u.name}}Compare {{u.name}}_compare = new {{u.name}}Compare();
static void SortByPrimaryId(ref List<{{u.name}}> list)
{
list.Sort({{u.name}}_compare);
}
public static bool {{_self.compare_func_name(u)}}(ref {{u.name}} a, {{u.name}} b)
{
bool is_equal = true;
@ -582,12 +570,14 @@ public class {{o.name}} : IRpc
if(DiffCollection({{f.name}}, old.{{f.name}},
diff == null ? null : diff.{{f.name}},
removed
removed == null ? null : removed.{{f.name}}
))
{
no_changes &= false;
if(diff != null)
Meta.SetFieldDirty(ref diff.fields_mask, {{field_idx}});
Meta.SetFieldDirty(ref diff.fields_mask, {{field_idx}});
if(removed != null && removed.{{f.name}}.Count > 0)
Meta.SetFieldDirty(ref removed.fields_mask, {{field_idx}});
}
{% elseif f.type is instanceof('\\mtgBuiltinType') %}
if(diff != null)