From d30a5ed8955e9151021ce57cc5ccebe75f7d86fe Mon Sep 17 00:00:00 2001 From: CodeDoctorDE Date: Wed, 18 Sep 2024 22:01:13 +0200 Subject: [PATCH] Use string for vector definition, use sequential --- api/lib/src/models/table.dart | 28 --------------------------- api/lib/src/models/table.mapper.dart | 2 +- api/lib/src/models/vector.dart | 29 +++++++++++++++++++++++++--- app/lib/bloc/world/bloc.dart | 3 ++- app/pubspec.lock | 8 ++++++++ app/pubspec.yaml | 1 + server/lib/main.dart | 18 ++++++++++++----- server/pubspec.lock | 16 +++++++++++++++ server/pubspec.yaml | 1 + 9 files changed, 68 insertions(+), 38 deletions(-) diff --git a/api/lib/src/models/table.dart b/api/lib/src/models/table.dart index a13cc82..eac1523 100644 --- a/api/lib/src/models/table.dart +++ b/api/lib/src/models/table.dart @@ -3,36 +3,8 @@ import 'vector.dart'; part 'table.mapper.dart'; -class VectorMapHook extends MappingHook { - const VectorMapHook(); - - @override - Object? beforeDecode(Object? value) { - if (value is! List) { - return value; - } - return Map.fromEntries(value.map((entry) => MapEntry(entry, entry))); - } - - @override - Object? afterEncode(Object? value) { - if (value is! Map) { - return value; - } - return value.entries.map((entry) { - final key = entry.key; - final value = entry.value; - return { - if (key is Map) ...key, - if (value is Map) ...value, - }; - }).toList(); - } -} - @MappableClass() class GameTable with GameTableMappable { - @MappableField(hook: VectorMapHook()) final Map cells; final ItemLocation? background; diff --git a/api/lib/src/models/table.mapper.dart b/api/lib/src/models/table.mapper.dart index c743fe4..1e72cac 100644 --- a/api/lib/src/models/table.mapper.dart +++ b/api/lib/src/models/table.mapper.dart @@ -25,7 +25,7 @@ class GameTableMapper extends ClassMapperBase { static Map _$cells(GameTable v) => v.cells; static const Field> _f$cells = - Field('cells', _$cells, opt: true, def: const {}, hook: VectorMapHook()); + Field('cells', _$cells, opt: true, def: const {}); static ItemLocation? _$background(GameTable v) => v.background; static const Field _f$background = Field('background', _$background, opt: true); diff --git a/api/lib/src/models/vector.dart b/api/lib/src/models/vector.dart index a4ea989..ddf857f 100644 --- a/api/lib/src/models/vector.dart +++ b/api/lib/src/models/vector.dart @@ -8,6 +8,18 @@ class VectorDefinition with VectorDefinitionMappable { const VectorDefinition(this.x, this.y); + factory VectorDefinition.fromDisplay(String displayString) { + final parts = displayString + .replaceAll('(', '') + .replaceAll(')', '') + .split(',') + .map((e) => e.trim()) + .toList(); + final x = int.parse(parts[0]); + final y = int.parse(parts[1]); + return VectorDefinition(x, y); + } + static const zero = VectorDefinition(0, 0); static const one = VectorDefinition(1, 1); @@ -22,9 +34,20 @@ class VectorDefinitionHook extends MappingHook { @override Object? beforeDecode(Object? value) { - if (value is List) { - return VectorDefinition(value[0] as int, value[1] as int); + if (value is Iterable) { + return VectorDefinition(value.first as int, value.last as int); + } + if (value is! String) { + return value; + } + return VectorDefinition.fromDisplay(value); + } + + @override + Object? beforeEncode(Object? value) { + if (value is! VectorDefinition) { + return value; } - return value; + return value.toDisplayString(); } } diff --git a/app/lib/bloc/world/bloc.dart b/app/lib/bloc/world/bloc.dart index d8a842e..569172a 100644 --- a/app/lib/bloc/world/bloc.dart +++ b/app/lib/bloc/world/bloc.dart @@ -1,3 +1,4 @@ +import 'package:bloc_concurrency/bloc_concurrency.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart' show ColorScheme; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -61,7 +62,7 @@ class WorldBloc extends Bloc { } on FatalServerEventError catch (e) { state.multiplayer.raiseError(e); } - }); + }, transformer: sequential()); on((event, emit) { emit(state.copyWith(colorScheme: event.colorScheme)); }); diff --git a/app/pubspec.lock b/app/pubspec.lock index 15fd858..984be37 100644 --- a/app/pubspec.lock +++ b/app/pubspec.lock @@ -70,6 +70,14 @@ packages: url: "https://pub.dev" source: hosted version: "8.1.4" + bloc_concurrency: + dependency: "direct main" + description: + name: bloc_concurrency + sha256: "456b7a3616a7c1ceb975c14441b3f198bf57d81cb95b7c6de5cb0c60201afcd8" + url: "https://pub.dev" + source: hosted + version: "0.2.5" boolean_selector: dependency: transitive description: diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 256b887..5246a14 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -89,6 +89,7 @@ dependencies: archive: ^3.4.10 flutter_markdown: ^0.7.3+1 markdown: ^7.2.2 + bloc_concurrency: ^0.2.5 dependency_overrides: flutter_secure_storage_web: git: diff --git a/server/lib/main.dart b/server/lib/main.dart index afbbdee..67e8e0a 100644 --- a/server/lib/main.dart +++ b/server/lib/main.dart @@ -1,7 +1,9 @@ import 'dart:async'; import 'dart:io'; +import 'dart:isolate'; import 'package:bloc/bloc.dart'; +import 'package:bloc_concurrency/bloc_concurrency.dart'; import 'package:consoler/consoler.dart'; import 'package:networker/networker.dart'; import 'package:networker_socket/server.dart'; @@ -13,6 +15,12 @@ import 'package:quokka_server/programs/save.dart'; import 'package:quokka_server/programs/say.dart'; import 'package:quokka_server/programs/stop.dart'; +Future _computeEvent(ServerWorldEvent event, WorldState state, + Map signature) { + return Isolate.run( + () => processServerEvent(event, state, signature: signature)); +} + final class QuokkaServer extends Bloc { final Consoler consoler; final ServerAssetManager assetManager; @@ -30,13 +38,13 @@ final class QuokkaServer extends Bloc { metadata: data.getMetadataOrDefault(), info: data.getInfoOrDefault(), )) { - on((event, emit) { - final newState = processServerEvent(event, state, - signature: assetManager.createSignature()); - if (newState == null) return null; + on((event, emit) async { + final signature = assetManager.createSignature(); + final newState = await _computeEvent(event, state, signature); + if (newState == null) return; emit(newState); return save(); - }); + }, transformer: sequential()); } static Future load({ diff --git a/server/pubspec.lock b/server/pubspec.lock index 7dae07f..bf89a41 100644 --- a/server/pubspec.lock +++ b/server/pubspec.lock @@ -54,6 +54,14 @@ packages: url: "https://pub.dev" source: hosted version: "8.1.4" + bloc_concurrency: + dependency: "direct main" + description: + name: bloc_concurrency + sha256: "456b7a3616a7c1ceb975c14441b3f198bf57d81cb95b7c6de5cb0c60201afcd8" + url: "https://pub.dev" + source: hosted + version: "0.2.5" boolean_selector: dependency: transitive description: @@ -370,6 +378,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" string_scanner: dependency: transitive description: diff --git a/server/pubspec.yaml b/server/pubspec.yaml index 624ddd4..88e8769 100644 --- a/server/pubspec.yaml +++ b/server/pubspec.yaml @@ -28,6 +28,7 @@ dependencies: path: ^1.9.0 quokka_api: path: ../api + bloc_concurrency: ^0.2.5 dev_dependencies: lints: ^4.0.0