Skip to content

Commit

Permalink
Fix performance issues again
Browse files Browse the repository at this point in the history
  • Loading branch information
CodeDoctorDE committed Oct 1, 2024
1 parent 69f189d commit b6f9f7e
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 51 deletions.
74 changes: 43 additions & 31 deletions api/lib/src/event/process/server.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,9 +112,13 @@ WorldState? processServerEvent(
final cell = table.cells[event.cell.position] ?? TableCell();
final newCell = cell.copyWith(objects: event.objects);
if (newCell.isEmpty) {
return table.copyWith.cells.remove(event.cell.position);
return table.copyWith.cellsBox(
content: Map<VectorDefinition, TableCell>.from(table.cells)
..remove(event.cell.position));
}
return table.copyWith.cells.replace(event.cell.position, newCell);
return table.copyWith.cellsBox(
content: Map<VectorDefinition, TableCell>.from(table.cells)
..[event.cell.position] = newCell);
});
case CellShuffled(positions: final positions):
return state.mapTableOrDefault(event.cell.table, (table) {
Expand All @@ -124,11 +128,9 @@ WorldState? processServerEvent(
for (var i = 0; i < positions.length; i++) {
newObjects[positions[i]] = objects[i];
}
return table.copyWith.cells.replace(
event.cell.position,
cell.copyWith(
objects: newObjects,
));
return table.copyWith.cellsBox(
content: Map<VectorDefinition, TableCell>.from(table.cells)
..[event.cell.position] = cell.copyWith(objects: newObjects));
});
case BackgroundChanged():
return state.copyWith.table(background: event.background);
Expand All @@ -137,8 +139,9 @@ WorldState? processServerEvent(
var newTable = table;
for (final entry in event.objects.entries) {
final cell = newTable.cells[entry.key] ?? TableCell();
newTable = newTable.copyWith.cells
.replace(entry.key, cell.copyWith(objects: entry.value));
newTable = newTable.copyWith.cellsBox(
content: Map<VectorDefinition, TableCell>.from(newTable.cells)
..[entry.key] = cell.copyWith(objects: entry.value));
}
return newTable;
});
Expand All @@ -158,32 +161,36 @@ WorldState? processServerEvent(
...to.objects,
...toAdd,
]);
return table.copyWith(cells: {
...Map<VectorDefinition, TableCell>.from(table.cells)
..remove(event.from),
if (!from.isEmpty) event.from: from,
event.to: to,
});
final cells = Map<VectorDefinition, TableCell>.from(table.cells)
..[event.to] = to;
if (from.isEmpty) {
cells.remove(event.from);
} else {
cells[event.from] = from;
}

return table.copyWith.cellsBox(content: cells);
});
case CellHideChanged():
return state.mapTableOrDefault(event.cell.table, (table) {
final cell = table.cells[event.cell.position] ?? TableCell();
final objectIndex = event.object;
if (objectIndex != null) {
final object = cell.objects[objectIndex];
return table.copyWith.cells.replace(
event.cell.position,
cell.copyWith.objects.replace(objectIndex,
object.copyWith(hidden: event.hide ?? !object.hidden)));
return table.copyWith.cellsBox(
content: Map<VectorDefinition, TableCell>.from(table.cells)
..[event.cell.position] = cell.copyWith.objects.replace(
objectIndex,
object.copyWith(hidden: event.hide ?? !object.hidden)));
}
final hidden =
!(event.hide ?? cell.objects.firstOrNull?.hidden ?? false);
return table.copyWith.cells.replace(
event.cell.position,
cell.copyWith(
objects:
cell.objects.map((e) => e.copyWith(hidden: hidden)).toList(),
));
return table.copyWith.cellsBox(
content: Map<VectorDefinition, TableCell>.from(table.cells)
..[event.cell.position] = cell.copyWith(
objects: cell.objects
.map((e) => e.copyWith(hidden: hidden))
.toList()));
});
case CellItemsCleared():
return state.mapTableOrDefault(event.cell.table, (table) {
Expand All @@ -196,9 +203,13 @@ WorldState? processServerEvent(
newCell = cell.copyWith(objects: []);
}
if (newCell.isEmpty) {
return table.copyWith.cells.remove(event.cell.position);
return table.copyWith.cellsBox(
content: Map<VectorDefinition, TableCell>.from(table.cells)
..remove(event.cell.position));
}
return table.copyWith.cells.replace(event.cell.position, newCell);
return table.copyWith.cellsBox(
content: Map<VectorDefinition, TableCell>.from(table.cells)
..[event.cell.position] = newCell);
});
case ObjectIndexChanged():
return state.mapTableOrDefault(event.cell.table, (table) {
Expand All @@ -207,8 +218,9 @@ WorldState? processServerEvent(
final newObjects = List<GameObject>.from(cell.objects);
newObjects.removeAt(event.object);
newObjects.insert(event.index, object);
return table.copyWith.cells
.replace(event.cell.position, cell.copyWith(objects: newObjects));
return table.copyWith.cellsBox(
content: Map<VectorDefinition, TableCell>.from(table.cells)
..[event.cell.position] = cell.copyWith(objects: newObjects));
});
case TeamChanged():
return state.copyWith.info.teams.put(event.name, event.team);
Expand Down Expand Up @@ -251,7 +263,7 @@ WorldState? processServerEvent(
cells[entry.key] =
table.getCell(entry.key).copyWith.tiles.addAll(entry.value);
}
return table.copyWith(cells: cells);
return table.copyWith.cellsBox(content: cells);
});
case BoardTilesChanged():
return state.mapTableOrDefault(event.table, (table) {
Expand All @@ -264,7 +276,7 @@ WorldState? processServerEvent(
cells[entry.key] = newCell;
}
}
return table.copyWith(cells: cells);
return table.copyWith.cellsBox(content: cells);
});
}
}
2 changes: 1 addition & 1 deletion api/lib/src/event/state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ final class WorldState with WorldStateMappable {
GameTable restrict(Channel user) {
final cells =
table.cells.keys.map((e) => MapEntry(e, restrictCell(e, user)!));
return table.copyWith(cells: Map.fromEntries(cells));
return table.copyWith.cellsBox(content: Map.fromEntries(cells));
}

QuokkaData save() =>
Expand Down
53 changes: 50 additions & 3 deletions api/lib/src/models/table.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,63 @@ import 'vector.dart';

part 'table.mapper.dart';

@MappableClass(generateMethods: GenerateMethods.all & ~GenerateMethods.equals)
@MappableClass(
includeCustomMappers: [IgnoreForEquality()],
generateMethods: GenerateMethods.all &
~GenerateMethods.equals &
~GenerateMethods.stringify)
class IgnoreEqualityBox<T> with IgnoreEqualityBoxMappable<T> {
final T content;

const IgnoreEqualityBox(this.content);
}

class IgnoreForEquality extends SimpleMapper1<IgnoreEqualityBox> {
const IgnoreForEquality();
@override
// use the type parameter [T] in the return type [GenericBox<T>]
IgnoreEqualityBox<T> decode<T>(dynamic value) {
// use the type parameter [T] in your decoding logic
T content = MapperContainer.globals.fromValue<T>(value);
return IgnoreEqualityBox<T>(content);
}

@override
// use the type parameter [T] in the parameter type [GenericBox<T>]
dynamic encode<T>(IgnoreEqualityBox<T> self) {
// use the type parameter [T] in your encoding logic
return MapperContainer.globals.toValue<T>(self.content);
}

// In case of generic types, we also must specify a type factory. This is a special type of
// function used internally to construct generic instances of your type.
// Specify any type arguments in alignment to the decode/encode functions.
@override
Function get typeFactory => <T>(f) => f<IgnoreEqualityBox<T>>();

@override
bool equals(value, other, MappingContext context) => value == other;

@override
int hash(value, MappingContext context) => value.hashCode;

@override
String stringify(value, MappingContext context) => value.toString();
}

@MappableClass()
class GameTable with GameTableMappable {
final Map<VectorDefinition, TableCell> cells;
@MappableField(key: "cells")
final IgnoreEqualityBox<Map<VectorDefinition, TableCell>> cellsBox;
final ItemLocation? background;

const GameTable({
this.cells = const {},
this.cellsBox = const IgnoreEqualityBox({}),
this.background,
});

Map<VectorDefinition, TableCell> get cells => cellsBox.content;

TableCell getCell(VectorDefinition position) =>
cells[position] ?? TableCell();
}
Expand Down
Loading

0 comments on commit b6f9f7e

Please sign in to comment.