Fixing nested diffable POD structs being incorrectly marked as clean in GetDiff
Publish PHP Package / docker (push) Successful in 7s Details

This commit is contained in:
Alexey Chubar 2024-06-18 17:23:26 +03:00
parent 5b2a889ae9
commit e8ce1df2ad
2 changed files with 60 additions and 18 deletions

View File

@ -1,4 +1,4 @@
## v4.9.0
## v4.9.1
- Fixing nested diffable POD structs being incorrectly marked as clean in GetDiff
## v4.8.2

View File

@ -459,7 +459,7 @@ public class {{o.name}} : IRpc
}
else if(old > item)
{
item.SetDirtyMask();
item.SetDirtyMaskDeep();
if(changed != null)
changed.Add(item);
i++;
@ -483,7 +483,7 @@ public class {{o.name}} : IRpc
for(; i < items.Count; i++)
{
var item = items[i];
item.SetDirtyMask();
item.SetDirtyMaskDeep();
if(changed != null)
changed.Add(item);
has_diff = true;
@ -532,26 +532,54 @@ public class {{o.name}} : IRpc
{{has_token(o, 'bitfields')?'CompareAndMarkFields':'IsEqual'}}
{%- endmacro %}
{%- macro field_compare(o, f, field_idx) -%}
{% macro field_compare_array_bitfields_nested_diffable(o, f, field_idx) %}
{
int {{f.name}}_count_a = a.{{f.name}} == null ? 0 : a.{{f.name}}.Count;
int {{f.name}}_count_b = b.{{f.name}} == null ? 0 : b.{{f.name}}.Count;
{% if f.type is instanceof('\\mtgArrType') ~%}
{% if has_token(o, 'bitfields') ~%}
//For NESTED arrays of DIFFABLE structs:
//for DB compatibility we must add the WHOLE ARRAY to the diff if ANY ELEMENT of the array has changed.
//That means marking each element's fields_mask as dirty
//Changed size means the array has changed, no furhter checks required.
bool {{f.name}}_equal = {{f.name}}_count_a == {{f.name}}_count_b;
//For same size arrays - check contents for changes.
if({{f.name}}_equal)
{
for(int i=0;i<{{f.name}}_count_a && i<{{f.name}}_count_b;++i)
{
var tmp_{{f.name}} = a.{{f.name}}[i];
if(!CompareAndMarkFields(ref tmp_{{f.name}}, b.{{f.name}}[i]))
{
{{f.name}}_equal = false;
break;
}
}
}
//If change detected - mark top-level field as changed and add the whole array to the diff
if(!{{f.name}}_equal)
{
MetaIO.SetFieldDirty(ref a.fields_mask, {{field_idx}});
for(int i=0; i<{{f.name}}_count_a;++i)
{
var tmp_{{f.name}} = a.{{f.name}}[i];
tmp_{{f.name}}.SetDirtyMaskDeep();
a.{{f.name}}[i] = tmp_{{f.name}};
is_equal = false;
}
}
}
{%- endmacro %}
{% macro field_compare_array_bitfields_nested_plain(o, f, field_idx) %}
if(a.{{f.name}} == null ||
b.{{f.name}} == null ||
a.{{f.name}}.Count != b.{{f.name}}.Count)
{
MetaIO.SetFieldDirty(ref a.fields_mask, {{field_idx}});
is_equal = false;
{% if has_token(f.type.value, 'bitfields') ~%}
//TODO: inefficient but reliable: marking the WHOLE collection as dirty when size changes
for(int i=0;i<a.{{f.name}}.Count;++i)
{
var tmp_{{f.name}} = a.{{f.name}}[i];
tmp_{{f.name}}.fields_mask = FieldsMask.MakeDirty(tmp_{{f.name}}.GetFieldsCount());
a.{{f.name}}[i] = tmp_{{f.name}};
}
{% endif ~%}
}
else
{
@ -575,7 +603,9 @@ public class {{o.name}} : IRpc
{%- endif -%}
}
}
{% else ~%}
{%- endmacro %}
{% macro field_compare_array_plain(o, f, field_idx) %}
if(a.{{f.name}} == null ||
b.{{f.name}} == null ||
a.{{f.name}}.Count != b.{{f.name}}.Count)
@ -591,6 +621,19 @@ public class {{o.name}} : IRpc
return false;
{%- endif -%}
}
{%- endmacro %}
{%- macro field_compare(o, f, field_idx) -%}
{% if f.type is instanceof('\\mtgArrType') ~%}
{% if has_token(o, 'bitfields') ~%}
{% if has_token(f.type.value, 'bitfields') ~%}
{{_self.field_compare_array_bitfields_nested_diffable(o, f, field_idx)}}
{% else ~%}
{{_self.field_compare_array_bitfields_nested_plain(o, f, field_idx)}}
{% endif ~%}
{% else ~%}
{{_self.field_compare_array_plain(o, f, field_idx)}}
{% endif ~%}
{% elseif f.type is instanceof('\\mtgMetaStruct') ~%}
@ -730,4 +773,3 @@ public interface {{ai.interfacename}}
{% endfor %}
{%- endfor ~%}
{% endmacro %}