diff --git a/tpl/macro.twig b/tpl/macro.twig index d4eab1c..34a5da4 100644 --- a/tpl/macro.twig +++ b/tpl/macro.twig @@ -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 -%} @@ -81,10 +85,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 -%} @@ -97,6 +115,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) -%} @@ -314,10 +353,12 @@ public class {{o.name}} : IRpc {%- macro diffable_support(o) -%} - public bool GetDiff({{o.name}} old, {{o.name}} diff = null, List 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 %} @@ -336,52 +377,22 @@ public class {{o.name}} : IRpc {{_self.diff_methods_for(u)}} {% endfor %} - static public List GetClassRemovedIds(List 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(); - removed_ids.Add(res); - } - return res.ids; - } - - static bool FindClassRemovedIds(List removed_ids, uint class_id, out DataClassIds res) - { - for(int i=0;i items, List<{{u.name}}> old_items, List<{{u.name}}> changed, List 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; @@ -390,15 +401,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) @@ -433,9 +442,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; } @@ -447,25 +454,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; @@ -564,7 +552,7 @@ 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;