Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a1994ed
@:rpc(checked) first draft
trethaller Jan 6, 2026
d405fe4
Simpler checkSuccess
trethaller Jan 7, 2026
8775c75
fix disconnect during rpc
ncannasse Jan 14, 2026
e8763c1
added missing ArrayProxy2 contains()
ncannasse Jan 26, 2026
6ae6e9d
optimize to prevent some Serializable wrapper alloc
ncannasse Feb 1, 2026
f8042c8
replace setTargetOwner by setTargetClient (fix null owner & improve p…
ncannasse Feb 12, 2026
22182a6
prevent double loop in host.doRPC for single client target
ncannasse Feb 13, 2026
2ec339f
fixed networkAllow was not checked on server when rpc was returning a…
ncannasse Feb 14, 2026
53e02ee
fixed @:rpc(owner) return value handling
ncannasse Feb 16, 2026
a0dc5a6
fixed regression where targetClient was not correctly reset
ncannasse Feb 18, 2026
bb72931
send server data in flush and not after each RPC (if hxbit_visibility)
ncannasse Feb 25, 2026
534eea5
also flush pending clients (custom messages)
ncannasse Feb 25, 2026
e8cc6d0
fixed CANCEL_RPC were not correctly routed to targetClient
ncannasse Feb 25, 2026
44be3df
added auto ping and lower timeout
ncannasse Feb 26, 2026
b444359
add timeout for pending clients as well
ncannasse Feb 27, 2026
81eca02
added NetworkClient.timeout
ncannasse Mar 3, 2026
e196b6a
added NetworkHost.onInvalidSignature
ncannasse Mar 3, 2026
4062f25
fix name collision between obj field and rpc arg
ncannasse Mar 9, 2026
65acc0c
fixed per client auto ping
ncannasse Mar 10, 2026
db7d754
added log of unref objects (check references)
ncannasse Mar 11, 2026
c61a975
fixed default visibility to 0 (security)
ncannasse Mar 11, 2026
d247b85
fix disconnect in flush/rpc
ncannasse Mar 16, 2026
58a89f7
Merge branch 'feat-checked'
trethaller Mar 17, 2026
5339318
fix build
trethaller Mar 17, 2026
2a8d1a8
fix
trethaller Mar 17, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ There are different RPC modes, which can be specified by using `@:rpc(mode)`:
- `server` : When called on the client: will forward the call the server (if networkAllow(RPCServer) allows it), but not execute locally. When called on the server, will execute locally.
- `owner` : When called on the client: will forward the call to the server (if networkAllow(RPC) allows it), but not execute locally. When called on the server: will forward the call to the owners as defined by networkAllow(Ownership).
- `immediate` : Like `all` but executes immediately locally
- `checked` : Like `server`, but also generates `check{Name}` and `can{Name}` helper functions

Return values are possible unless you are in `all` mode, and will add an extra callback to capture the result asynchronously:

Expand Down Expand Up @@ -237,3 +238,43 @@ You can also cancel the change of a property can calling `networkCancelProperty(

The whole set of currently shared network objects can be saved using host.saveState() and loaded using host.loadState(bytes). It uses the versionning decribed previously. Once loaded, call host.makeAlive() to make sure all alive() calls are made to object.


### Checked RPCs and @:do blocks

The `checked` mode is useful when you want to check on the client whether an RPC will succeed before executing it. It generates two additional functions:

- `check{Name}(...)` : Runs the RPC logic without executing `@:do` blocks, returning the result
- `can{Name}(...)` : Like `check`, but returns a `Bool` indicating success

Use `@:do { }` blocks to mark code that should only run when the RPC succeeds:

```haxe
@:rpc(checked)
function buyItem(itemId:Int) : PurchaseResult {
var item = inventory.get(itemId);
if (item == null) return NotFound;
if (player.gold < item.price) return NotEnoughGold;

@:do {
// This only executes when called via buyItem(), not checkBuyItem()
player.gold -= item.price;
player.addItem(item);
}
return Success;
}

// Usage:
if (canBuyItem(itemId)) {
buyItem(itemId);
}

// Or check the specific result:
var result = checkBuyItem(itemId);
if (result != Success)
showError(result);
```

The `can{Name}` function determines success by:
- If return type is `Bool`, returns the value directly
- If return type is an enum with `@:rpcSuccess(Value)`, returns `result == Value`
- Otherwise, returns `result != null` (result considered an error code)
4 changes: 4 additions & 0 deletions hxbit/ArrayProxy.hx
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,10 @@ abstract ArrayProxy2<T:ProxyChild>(ArrayProxyData<T>) to ProxyChild {
return this.array.filter(t);
}

public inline function contains( x : T ) : Bool {
return this.array.contains(x);
}

public inline function indexOf(x:T, ?fromIndex) {
return this.array.indexOf(x, fromIndex);
}
Expand Down
Loading