From 8216e41bbeda3f67f0eb7bfaafe59bcefa7fdf96 Mon Sep 17 00:00:00 2001 From: Leonardo Date: Mon, 2 Sep 2024 14:09:07 +0200 Subject: [PATCH] Fix @:condSend() when used with Proxy types (#77) --- hxbit/Macros.hx | 39 ++++++++++++++++++++++++++++++------ hxbit/NetworkSerializable.hx | 7 ++++--- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/hxbit/Macros.hx b/hxbit/Macros.hx index 773e0cc..cfb451b 100644 --- a/hxbit/Macros.hx +++ b/hxbit/Macros.hx @@ -1825,6 +1825,7 @@ class Macros { var flushExpr = []; var syncExpr = []; var initExpr = []; + var condMarkCases: Array = []; var noComplete : Metadata = [ { name : ":noCompletion", pos : pos } ]; var saveMask : haxe.Int64 = 0; for( f in toSerialize ) { @@ -1887,8 +1888,9 @@ class Macros { f.f.kind = FProp(getter,"set", ftype.t, einit); var bitID = startFID++; - var markExpr = macro networkSetBit($v{ bitID }); - markExpr = makeMarkExpr(fields, fname, ftype, markExpr); + var baseMarkExpr = macro networkSetBit($v{ bitID }); + var markExpr = makeMarkExpr(fields, fname, ftype, baseMarkExpr); + var condMarkExpr = makeMarkExpr(fields, fname, ftype, baseMarkExpr, false); var compExpr : Expr = macro this.$fname != v; if(ftype.d.match(PEnum(_))) @@ -1965,6 +1967,31 @@ class Macros { }), access : [AInline], }); + condMarkCases.push({ + values : [macro $v{bitID}], + expr : condMarkExpr, + }); + } + + if( toSerialize.length != 0 || !isSubSer ) { + var access = [APublic]; + if( isSubSer ) + access.push(AOverride); + var defaultCase = macro networkSetBit(b); + if( isSubSer ) + defaultCase = macro super.networkSetBitCond(b); + var swExpr = { expr : ESwitch( { expr : EConst(CIdent("b")), pos : pos }, condMarkCases, defaultCase), pos : pos }; + fields.push({ + name : "networkSetBitCond", + pos : pos, + access : access, + meta : noComplete, + kind : FFun({ + args : [ { name : "b", type : macro : Int } ], + ret : macro : Void, + expr : swExpr, + }), + }); } // BUILD RPC @@ -2532,10 +2559,10 @@ class Macros { return null; } - static function makeMarkExpr( fields : Array, fname : String, t : PropType, mark : Expr ) { + static function makeMarkExpr( fields : Array, fname : String, t : PropType, mark : Expr, forSetter=true ) { var rname = "__ref_" + fname; var needRef = false; - if( t.increment != null ) { + if( t.increment != null && forSetter ) { needRef = true; mark = macro if( Math.floor(v / $v{t.increment}) != this.$rname ) { this.$rname = Math.floor(v / $v{t.increment}); $mark; }; } @@ -2638,8 +2665,8 @@ class Macros { var bit : Int; @:noCompletion public var __value(get, never) : $pt; inline function get___value() : $pt return cast this; - inline function mark() if( obj != null ) obj.networkSetBit(bit); - @:noCompletion public function networkSetBit(_) mark(); + public inline function mark() if( obj != null ) obj.networkSetBitCond(bit); + @:noCompletion public inline function networkSetBitCond(_) mark(); @:noCompletion public function bindHost(obj, bit) { this.obj = obj; this.bit = bit; } @:noCompletion public function unbindHost() this.obj = null; @:noCompletion public function toString() return hxbit.NetworkSerializable.BaseProxy.objToString(this); diff --git a/hxbit/NetworkSerializable.hx b/hxbit/NetworkSerializable.hx index 75718d4..32d1eda 100644 --- a/hxbit/NetworkSerializable.hx +++ b/hxbit/NetworkSerializable.hx @@ -22,7 +22,7 @@ package hxbit; interface ProxyHost { - public function networkSetBit( bit : Int ) : Void; + public function networkSetBitCond( bit : Int ) : Void; } interface ProxyChild { @@ -81,6 +81,7 @@ interface NetworkSerializable extends Serializable extends ProxyHost { public function networkRPC( ctx : NetworkSerializer, rpcID : Int, clientResult : NetworkHost.NetworkClient ) : Bool; public function networkAllow( op : Operation, propId : Int, client : NetworkSerializable ) : Bool; public function networkGetName( propId : Int, isRPC : Bool = false ) : String; + public function networkSetBit( bit : Int ) : Void; #if hxbit_visibility public var __cachedVisibility : Map; @@ -95,11 +96,11 @@ interface NetworkSerializable extends Serializable extends ProxyHost { class BaseProxy implements ProxyHost implements ProxyChild { public var obj : ProxyHost; public var bit : Int; - public inline function networkSetBit(_) { + @:noCompletion public inline function networkSetBitCond(_) { mark(); } public inline function mark() { - if( obj != null ) obj.networkSetBit(bit); + if( obj != null ) obj.networkSetBitCond(bit); } public inline function bindHost(o, bit) { if( obj != null && (o != this.obj || bit != this.bit) )