Skip to content

Commit 554d092

Browse files
committed
Fix event system in lua
1 parent 3907ff1 commit 554d092

File tree

17 files changed

+268
-1330
lines changed

17 files changed

+268
-1330
lines changed

app/lib/bloc/world/bloc.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,18 @@ class _WorldServerInterfaceImpl implements ServerInterface {
2323
_WorldServerInterfaceImpl(this.bloc);
2424

2525
@override
26-
void process(WorldEvent event, {bool force = false, required String plugin}) {
27-
bloc.process(event);
28-
}
26+
Future<void> process(
27+
WorldEvent event, {
28+
bool force = false,
29+
required String plugin,
30+
}) => bloc.process(event);
2931

3032
@override
31-
void sendEvent(
33+
Future<void> sendEvent(
3234
PlayableWorldEvent event, {
3335
Channel target = kAnyChannel,
3436
required String plugin,
35-
}) {
36-
bloc._processEvent(NetworkerPacket(event, target));
37-
}
37+
}) => bloc._processEvent(NetworkerPacket(event, target));
3838

3939
@override
4040
void print(String message, [String? plugin]) {

app/pack/scripts/blackjack.luau

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,56 @@ local StackPosition = {
1010
}
1111
local CurrentPlayer = 1
1212
local PlayerScores : {[number]: number} = {}
13+
local Colors = {
14+
"heart",
15+
"diamond",
16+
"club",
17+
"spade"
18+
}
19+
local Values = {
20+
"1",
21+
"2",
22+
"3",
23+
"4",
24+
"5",
25+
"6",
26+
"7",
27+
"8",
28+
"9",
29+
"10",
30+
"jack",
31+
"queen",
32+
"king",
33+
"ace"
34+
}
35+
function GetVariations() : {string}
36+
local variations = {}
37+
for _, color in ipairs(Colors) do
38+
for _, value in ipairs(Values) do
39+
table.insert(variations, color.."-"..value)
40+
end
41+
end
42+
return variations
43+
end
44+
function SpawnDeck(cell)
45+
local variations = GetVariations()
46+
local tableName = cell.table
47+
local vector = "("..cell.x..", "..cell.y..")"
48+
local objects = {}
49+
for _, variation in ipairs(variations) do
50+
table.insert(objects, {
51+
asset=State.Namespace..":cards",
52+
variation=variation,
53+
})
54+
end
55+
Server:Process({
56+
type="ObjectsSpawned",
57+
table=tableName,
58+
objects={
59+
[vector]=objects
60+
}
61+
}, true)
62+
end
1363
function Reset()
1464
ResetWorld()
1565
PlayerScores = {}
@@ -18,19 +68,15 @@ function Reset()
1868
end
1969
function Setup()
2070
print("setup")
21-
print(State.PluginId)
71+
print(State.Namespace)
2272
Server:Process({
23-
type="CellVisibilityChanged",
73+
type="CellHideChanged",
2474
cell=DeckPosition,
25-
visibility=false
75+
hide=true
2676
}, true)
77+
SpawnDeck(DeckPosition)
2778
Server:Process({
28-
type="DeckSpawned",
29-
cell=DeckPosition,
30-
deck=State.PluginId..":cards"
31-
}, true)
32-
Server:Process({
33-
type="CellShuffleRequest",
79+
type="ShuffleCellRequest",
3480
cell=DeckPosition
3581
}, true)
3682
end
@@ -59,7 +105,7 @@ local VariationsScores : {[string]: {number}} = {
59105
local MaxScore = 21
60106
function CalculateCard(identifier) : {number}
61107
local splitted = string.split(identifier, ":")
62-
if #splitted ~= 2 or splitted[1] ~= State.PluginId then
108+
if #splitted ~= 2 or splitted[1] ~= State.Namespace then
63109
return {0}
64110
end
65111
splitted = string.split(splitted[2], "-")
@@ -181,6 +227,10 @@ Events.ObjectsSpawned.Connect(function(event, details)
181227
details.cancelled = true
182228
print("Spawning objects is not allowed.")
183229
end)
230+
Events.BoardsSpawnRequest.Connect(function(event, details)
231+
details.cancelled = true
232+
print("Spawning boards is not allowed.")
233+
end)
184234
Events.ObjectMoved.Connect(function(event, details)
185235
local isFromDeck = event.from.table == DeckPosition.table and event.from.x == DeckPosition.x and event.from.y == DeckPosition.y
186236
local isToStack = event.to.table == StackPosition.table and event.to.x == StackPosition.x and event.to.y == StackPosition.y

plugin/definitions/setonix.d.luau

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ declare State: {
2323
Info: JsonObject,
2424
Players: { number },
2525
PluginId: string,
26+
Namespace: string,
27+
Game: string,
2628
Table: JsonObject,
2729
GetTable: (self: any, name: string) -> JsonObject?
2830
}

plugin/example/lua.dart

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import 'dart:async';
2+
13
import 'package:flutter_rust_bridge/flutter_rust_bridge.dart';
24
import 'package:setonix_plugin/setonix_plugin.dart';
35

@@ -13,15 +15,22 @@ end)
1315
''';
1416
Future<void> main() async {
1517
await initPluginSystem();
16-
final callback = await PluginCallback.default_();
17-
callback.changeOnPrint(
18+
final callback = PluginCallback(
1819
onPrint: (p0) {
19-
print("SANDBOX: ${p0}");
20+
print("PLUGIN: ${p0}");
2021
},
21-
);
22-
callback.changeStateFieldAccess(
2322
stateFieldAccess: (p0) {
24-
print("FIELD: ${p0}");
23+
print("FIELD ACCESS: ${p0}");
24+
return '{"key": "value"}';
25+
},
26+
processEvent: (p0, p1) {
27+
print("PROCESS EVENT: ${p0}, force: ${p1}");
28+
},
29+
sendEvent: (p0, p1) {
30+
print("SEND EVENT: ${p0}, target: ${p1}");
31+
},
32+
tableAccess: (p0) {
33+
print("TABLE ACCESS: ${p0}");
2534
return '{"key": "value"}';
2635
},
2736
);

plugin/lib/src/plugin.dart

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import 'dart:async';
12
import 'dart:convert';
23
import 'dart:io';
34

@@ -15,8 +16,12 @@ typedef PluginSendEventCallback =
1516
);
1617

1718
mixin ServerInterface {
18-
void process(WorldEvent event, {bool force = false, required String plugin});
19-
void sendEvent(
19+
Future<void> process(
20+
WorldEvent event, {
21+
bool force = false,
22+
required String plugin,
23+
});
24+
Future<void> sendEvent(
2025
PlayableWorldEvent event, {
2126
Channel target = kAnyChannel,
2227
required String plugin,
@@ -52,7 +57,7 @@ final class PluginSystem {
5257
(c) => LuauPlugin(code: code, callback: c),
5358
pluginServer,
5459
onPrint: (e) => server.print(e, name),
55-
pluginId: () => name,
60+
location: ItemLocation.fromString(name),
5661
),
5762
);
5863
}
@@ -108,8 +113,11 @@ final class PluginSystem {
108113
}
109114

110115
abstract class PluginServerInterface {
111-
void process(WorldEvent event, {bool force = false});
112-
void sendEvent(PlayableWorldEvent event, {Channel target = kAnyChannel});
116+
Future<void> process(WorldEvent event, {bool force = false});
117+
Future<void> sendEvent(
118+
PlayableWorldEvent event, {
119+
Channel target = kAnyChannel,
120+
});
113121
WorldState get state;
114122
List<int> get players;
115123
}
@@ -121,14 +129,14 @@ class _PluginServerInterfaceImpl implements PluginServerInterface {
121129
_PluginServerInterfaceImpl(this.server, this.pluginName);
122130

123131
@override
124-
void process(WorldEvent event, {bool force = false}) {
125-
server.process(event, force: force, plugin: pluginName);
126-
}
132+
Future<void> process(WorldEvent event, {bool force = false}) =>
133+
server.process(event, force: force, plugin: pluginName);
127134

128135
@override
129-
void sendEvent(PlayableWorldEvent event, {Channel target = kAnyChannel}) {
130-
server.sendEvent(event, target: target, plugin: pluginName);
131-
}
136+
Future<void> sendEvent(
137+
PlayableWorldEvent event, {
138+
Channel target = kAnyChannel,
139+
}) => server.sendEvent(event, target: target, plugin: pluginName);
132140

133141
@override
134142
WorldState get state => server.state;
@@ -164,25 +172,23 @@ final class RustSetonixPlugin extends SetonixPlugin {
164172
RustPlugin Function(PluginCallback) builder,
165173
PluginServerInterface server, {
166174
void Function(String)? onPrint,
167-
String Function()? pluginId,
175+
ItemLocation? location,
168176
}) async {
169-
final callback = PluginCallback.default_();
170-
if (onPrint != null) {
171-
callback.changeOnPrint(onPrint: onPrint);
172-
}
173-
callback.changeProcessEvent(
174-
processEvent: (eventSerizalized, force) {
175-
final event = WorldEventMapper.fromJson(eventSerizalized);
176-
server.process(event, force: force ?? false);
177+
final processEventController = StreamController<(String, bool?)>();
178+
179+
final callback = PluginCallback(
180+
onPrint: onPrint ?? (s) {},
181+
processEvent: (eventSerizalized, force) async {
182+
processEventController.add((eventSerizalized, force));
177183
},
178-
);
179-
callback.changeSendEvent(
180184
sendEvent: (eventSerizalized, target) {
181-
final event = PlayableWorldEventMapper.fromJson(eventSerizalized);
182-
server.sendEvent(event, target: target ?? kAnyChannel);
185+
try {
186+
final event = PlayableWorldEventMapper.fromJson(eventSerizalized);
187+
server.sendEvent(event, target: target ?? kAnyChannel);
188+
} catch (e) {
189+
print("Error sending event from plugin: $e");
190+
}
183191
},
184-
);
185-
callback.changeStateFieldAccess(
186192
stateFieldAccess: (field) {
187193
final state = server.state;
188194
return switch (field) {
@@ -193,18 +199,30 @@ final class RustSetonixPlugin extends SetonixPlugin {
193199
StateFieldAccess.tableName => jsonEncode(state.tableName),
194200
StateFieldAccess.players => jsonEncode(server.players),
195201
StateFieldAccess.teamMembers => jsonEncode(state.teamMembers),
196-
StateFieldAccess.pluginId => jsonEncode(
197-
pluginId?.call() ?? 'unknown',
202+
StateFieldAccess.game => jsonEncode(location?.namespace ?? 'unknown'),
203+
StateFieldAccess.namespace => jsonEncode(
204+
location?.namespace ?? 'unknown',
198205
),
199206
};
200207
},
201-
);
202-
callback.changeTableAccess(
203208
tableAccess: (tableName) {
204209
final table = server.state.data.getTable(tableName ?? '');
205210
return table?.toJson() ?? "{}";
206211
},
207212
);
213+
processEventController.stream.listen((message) async {
214+
final (eventSerizalized, force) = message;
215+
final smallMsg = eventSerizalized.substring(0, 20);
216+
try {
217+
onPrint?.call("Process event called from plugin: $smallMsg");
218+
final event = WorldEventMapper.fromJson(eventSerizalized);
219+
await server.process(event, force: force ?? false);
220+
} catch (e) {
221+
onPrint?.call("Error processing event from plugin: $e");
222+
} finally {
223+
onPrint?.call("Finished processing event from plugin $smallMsg");
224+
}
225+
});
208226
final plugin = builder(callback);
209227
final instance = RustSetonixPlugin._(server, plugin);
210228
instance.eventSystem.on<WorldEvent>((e) async {

plugin/lib/src/rust/api/plugin.dart

Lines changed: 13 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,35 +6,25 @@
66
import '../frb_generated.dart';
77
import 'package:flutter_rust_bridge/flutter_rust_bridge_for_generated.dart';
88

9-
// These functions are ignored because they are not marked as `pub`: `get`, `new`
10-
// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `StateFieldAccessIter`
9+
// These functions are ignored because they are not marked as `pub`: `build`, `get`, `new`
10+
// These types are ignored because they are neither used by any `pub` functions nor (for structs and enums) marked `#[frb(unignore)]`: `EventDetails`, `StateFieldAccessIter`
1111
// These function are ignored because they are on traits that is not defined in current crate (put an empty `#[frb]` on it to unignore): `clone`, `clone`, `clone`, `fmt`, `fmt`, `iter`, `len`, `next_back`, `next`, `nth`, `size_hint`
1212

13-
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<EventDetails>>
14-
abstract class EventDetails implements RustOpaqueInterface {}
15-
1613
// Rust type: RustOpaqueMoi<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<PluginCallback>>
1714
abstract class PluginCallback implements RustOpaqueInterface {
18-
void changeOnPrint({required FutureOr<void> Function(String) onPrint});
19-
20-
void changeProcessEvent({
15+
factory PluginCallback({
16+
required FutureOr<void> Function(String) onPrint,
2117
required FutureOr<void> Function(String, bool?) processEvent,
22-
});
23-
24-
void changeSendEvent({
2518
required FutureOr<void> Function(String, int?) sendEvent,
26-
});
27-
28-
void changeStateFieldAccess({
2919
required FutureOr<String> Function(StateFieldAccess) stateFieldAccess,
30-
});
31-
32-
void changeTableAccess({
3320
required FutureOr<String> Function(String?) tableAccess,
34-
});
35-
36-
static PluginCallback default_() =>
37-
RustLib.instance.api.crateApiPluginPluginCallbackDefault();
21+
}) => RustLib.instance.api.crateApiPluginPluginCallbackNew(
22+
onPrint: onPrint,
23+
processEvent: processEvent,
24+
sendEvent: sendEvent,
25+
stateFieldAccess: stateFieldAccess,
26+
tableAccess: tableAccess,
27+
);
3828
}
3929

4030
abstract class RustPlugin {
@@ -63,14 +53,6 @@ class EventResult {
6353
required this.cancelled,
6454
});
6555

66-
static Future<EventResult> build({
67-
required EventDetails details,
68-
EventDetails? previous,
69-
}) => RustLib.instance.api.crateApiPluginEventResultBuild(
70-
details: details,
71-
previous: previous,
72-
);
73-
7456
@override
7557
int get hashCode =>
7658
target.hashCode ^
@@ -95,5 +77,6 @@ enum StateFieldAccess {
9577
info,
9678
players,
9779
teamMembers,
98-
pluginId,
80+
namespace,
81+
game,
9982
}

0 commit comments

Comments
 (0)