From eaa8c091627e4dd743c88dda42d4da70dca40e8b Mon Sep 17 00:00:00 2001 From: Peter Vullings Date: Mon, 11 Sep 2023 00:54:00 +1200 Subject: [PATCH] feat(flame_jenny): Allow removal of variables (#2716) Allow variables to be removed from variable storage, or variable storage to be cleared. It's not usual to do this, but could be useful in large games where each scene may have its own set of variables. They can be cleared between scenes. Another use-case is for implementing a 'save game' feature. The variables can be cleared, and a new set of variables loaded in from a save game. It's important to note that Jenny uses variable storage to retain the node visit counts (the number of times the player has visited each node). This has been taken into account in the clear method, which allows the user to retain the node visit counts. --- .../jenny/runtime/variable_storage.md | 37 +++++++++++++++++++ .../jenny/lib/src/variable_storage.dart | 20 ++++++++++ .../jenny/test/variable_storage_test.dart | 31 ++++++++++++++++ 3 files changed, 88 insertions(+) diff --git a/doc/other_modules/jenny/runtime/variable_storage.md b/doc/other_modules/jenny/runtime/variable_storage.md index 9bcd45a88..353b89bf4 100644 --- a/doc/other_modules/jenny/runtime/variable_storage.md +++ b/doc/other_modules/jenny/runtime/variable_storage.md @@ -5,3 +5,40 @@ :symbol: VariableStorage :file: src/variable_storage.dart ``` + + +## Accessing variable storage + +Variable storage is accessed via the [YarnProject]. + +```dart +final variables = yarnProject.variables; +``` + + +## Removing variables + +In most cases variables should be retained for the life of the [YarnProject]. However there may be +situations where variables need to be removed from storage. For example, in a game with many +scenes, variables specific to that scene could be removed if they are no longer required. + +Remove all variables with `clear`. By default this will retain node visit counts, which are also +stored as variables. Node visit counts are used by Yarn for logic such as 'do this if the node has +already been visited', so it's best to leave these alone. However, to remove them as well set +`clearNodeVisits` to `true`. + +```dart +/// Clear all variables except node visit counts. +yarnProject.variables.clear(); + +/// Clear all variables including node visit counts. +yarnProject.variables.clear(clearNodeVisits: true); +``` + +Use `remove` to remove a single variable. + +```dart +yarnProject.variables.remove('money'); +``` + +[YarnProject]: yarn_project.md diff --git a/packages/flame_jenny/jenny/lib/src/variable_storage.dart b/packages/flame_jenny/jenny/lib/src/variable_storage.dart index c610189f8..0bd2f5649 100644 --- a/packages/flame_jenny/jenny/lib/src/variable_storage.dart +++ b/packages/flame_jenny/jenny/lib/src/variable_storage.dart @@ -57,4 +57,24 @@ class VariableStorage { } variables[name] = value; } + + /// Clear all variables. By default node visit counts will not be cleared. + /// To remove node visit counts as well, set [clearNodeVisits] to `true`. + /// + /// Note that node visit variable names are prefixed with an @ symbol. + /// If you have custom variables that start with an @ symbol these will + /// also be retained if [clearNodeVisits] is `false`. These will need to be + /// removed individually using [remove]. + void clear({bool clearNodeVisits = false}) { + if (!clearNodeVisits) { + variables.removeWhere((key, _) => !key.startsWith('@')); + } else { + variables.clear(); + } + } + + /// Remove a variable by [name]. + void remove(String name) { + variables.remove(name); + } } diff --git a/packages/flame_jenny/jenny/test/variable_storage_test.dart b/packages/flame_jenny/jenny/test/variable_storage_test.dart index aa744116f..44c7c252a 100644 --- a/packages/flame_jenny/jenny/test/variable_storage_test.dart +++ b/packages/flame_jenny/jenny/test/variable_storage_test.dart @@ -67,6 +67,37 @@ void main() { ), ); }); + + test('remove a variable', () { + final storage = VariableStorage(); + storage.setVariable('x', 42); + expect(storage.hasVariable('x'), true); + + storage.remove('x'); + + expect(storage.hasVariable('x'), false); + }); + + test('clear variables except node visits', () { + final storage = VariableStorage(); + storage.setVariable('x', 42); + storage.setVariable('@node_name1', 1); + + storage.clear(); + + expect(storage.hasVariable('x'), false); + expect(storage.hasVariable('@node_name1'), true); + }); + + test('clear variables including node visits', () { + final storage = VariableStorage(); + storage.setVariable('x', 42); + storage.setVariable('@node_name1', 1); + + storage.clear(clearNodeVisits: true); + + expect(storage.isEmpty, true); + }); }); }