Skip to content

Commit

Permalink
fix: add count for duplicate events
Browse files Browse the repository at this point in the history
Completing puzzles multiple times was resulting in duplicate events,
which could eventually blow up the save file size - this instead looks
for a matching event, updating a count field on it if found.
  • Loading branch information
russmatney committed Feb 12, 2024
1 parent 7e02893 commit 2486603
Show file tree
Hide file tree
Showing 7 changed files with 122 additions and 14 deletions.
9 changes: 8 additions & 1 deletion data.pandora
Original file line number Diff line number Diff line change
Expand Up @@ -904,12 +904,19 @@
"_id": "57",
"_name": "puzzle_idx",
"_type": "int"
},
{
"_category_id": "28",
"_default_value": 1,
"_id": "59",
"_name": "count",
"_type": "int"
}
]
},
"_id_generator": {
"_ids_by_context": {
"default": 58
"default": 59
}
}
}
49 changes: 36 additions & 13 deletions src/Store.gd
Original file line number Diff line number Diff line change
Expand Up @@ -54,31 +54,51 @@ func get_themes() -> Array[PuzzleTheme]:
func get_events() -> Array[Event]:
return events

## events ###########################################
func find_events(filter_fn) -> Array[Event]:
return events.filter(filter_fn)

func find_event(filter_fn) -> Event:
var evs = find_events(filter_fn)
if len(evs) > 0:
return evs[0]
else:
return null

# TODO how to deal with repeats/dupes ? ignore, update-count-in-place?
## events ###########################################

func complete_puzzle_set(puz: PuzzleSet):
var event = PuzzleSetCompleted.new_event(puz)
state.apply_event(event)
events.append(event)
var event = find_event(func(ev): return PuzzleSetCompleted.is_matching_event(ev, puz))
if event:
event.inc_count()
elif not event:
event = PuzzleSetCompleted.new_event(puz)
state.apply_event(event)
events.append(event)
save_game()

if puz.get_next_puzzle_set():
unlock_next_puzzle_set(puz)

func complete_puzzle_index(puz: PuzzleSet, idx: int):
var event = PuzzleCompleted.new_event(puz, idx)
state.apply_event(event)
events.append(event)
var event = find_event(func(ev): return PuzzleCompleted.is_matching_event(ev, puz, idx))
if event:
event.inc_count()
elif not event:
event = PuzzleCompleted.new_event(puz, idx)
state.apply_event(event)
events.append(event)
save_game()

func unlock_next_puzzle_set(puz: PuzzleSet):
var next = puz.get_next_puzzle_set()
if next:
var event = PuzzleSetUnlocked.new_event(next)
state.apply_event(event)
events.append(event)
var event = find_event(func(ev): return PuzzleSetUnlocked.is_matching_event(ev, next))
if event:
event.inc_count()
elif not event:
event = PuzzleSetUnlocked.new_event(next)
state.apply_event(event)
events.append(event)

# save update events for later reloading
save_game()
Expand All @@ -88,7 +108,10 @@ func unlock_next_puzzle_set(puz: PuzzleSet):
func unlock_all_puzzle_sets():
Log.warn("Unlocking all puzzle sets!")
for ps in state.puzzle_sets:
var event = PuzzleSetUnlocked.new_event(ps)
var event = find_event(func(ev): return PuzzleSetUnlocked.is_matching_event(ev, ps))
if event:
continue
event = PuzzleSetUnlocked.new_event(ps)
state.apply_event(event)
events.append(event)
save_game()
save_game()
7 changes: 7 additions & 0 deletions src/events/Event.gd
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ func get_timestamp_string() -> String:
func get_timestamp_float() -> float:
return get_float("timestamp_float")

func get_count() -> int:
return get_integer("count")

func data():
return {
name=get_display_name(),
time=get_timestamp_string(),
count=get_count(),
}

func set_event_data(opts: Dictionary):
Expand All @@ -26,3 +30,6 @@ func set_event_data(opts: Dictionary):
var now_float = Time.get_unix_time_from_system()
set_string("timestamp_string", now_str)
set_float("timestamp_float", now_float)

func inc_count():
set_integer("count", get_count() + 1)
9 changes: 9 additions & 0 deletions src/events/PuzzleCompleted.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ class_name PuzzleCompleted
func get_puzzle_set() -> PuzzleSet:
return Pandora.get_entity(get_string("puzzle_set_id")) as PuzzleSet

func get_puzzle_set_id() -> String:
return get_string("puzzle_set_id")

func get_puzzle_index() -> int:
return get_integer("puzzle_idx")

Expand All @@ -25,3 +28,9 @@ static func new_event(puzzle_set: PuzzleSet, puzzle_idx: int):
display_name="Puzzle %s completed in set '%s'" % [puzzle_idx, puzzle_set.get_display_name()],
})
return event

static func is_matching_event(event, puzzle_set: PuzzleSet, idx: int):
if not event is PuzzleCompleted:
return false
return event.get_puzzle_set_id() == puzzle_set.get_entity_id() and \
event.get_puzzle_index() == idx
8 changes: 8 additions & 0 deletions src/events/PuzzleSetCompleted.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ class_name PuzzleSetCompleted
func get_puzzle_set() -> PuzzleSet:
return Pandora.get_entity(get_string("puzzle_set_id")) as PuzzleSet

func get_puzzle_set_id() -> String:
return get_string("puzzle_set_id")

func data():
var d = super.data()
d.merge({puzzle_set=get_puzzle_set(),})
Expand All @@ -18,3 +21,8 @@ static func new_event(puzzle_set: PuzzleSet):
display_name="%s completed" % puzzle_set.get_display_name(),
})
return event

static func is_matching_event(event, puzzle_set: PuzzleSet):
if not event is PuzzleSetCompleted:
return false
return event.get_puzzle_set_id() == puzzle_set.get_entity_id()
8 changes: 8 additions & 0 deletions src/events/PuzzleSetUnlocked.gd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ class_name PuzzleSetUnlocked
func get_puzzle_set() -> PuzzleSet:
return Pandora.get_entity(get_string("puzzle_set_id")) as PuzzleSet

func get_puzzle_set_id() -> String:
return get_string("puzzle_set_id")

func data():
var d = super.data()
d.merge({puzzle_set=get_puzzle_set(),})
Expand All @@ -18,3 +21,8 @@ static func new_event(puzzle_set: PuzzleSet):
display_name="%s unlocked" % puzzle_set.get_display_name(),
})
return event

static func is_matching_event(event, puzzle_set: PuzzleSet):
if not event is PuzzleSetUnlocked:
return false
return event.get_puzzle_set_id() == puzzle_set.get_entity_id()
46 changes: 46 additions & 0 deletions test/store/store_test.gd
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,49 @@ func test_completing_a_puzzle(indexes, test_parameters=[[[0]], [[0, 1]], [[0, 1,
assert_that(puz_set.can_play_puzzle(idx)).is_true()
assert_that(puz_set.can_play_puzzle(idx + 1)).is_true()
assert_that(puz_set.can_play_puzzle(idx + 2)).is_false()

#########################################################################
## dupe events

func test_complete_puzzle_idx_dupe_events_increment_count():
Store.reset_game_data()
assert_that(len(Store.events)).is_equal(0)

var sets = Store.get_puzzle_sets()
var puz_set = sets.filter(func(e): return not e.is_completed())[0]

Store.complete_puzzle_index(puz_set, 0)
Store.complete_puzzle_index(puz_set, 0)

assert_that(len(Store.events)).is_equal(1)
var ev = Store.events[0]
assert_that(ev.get_puzzle_set().get_entity_id()).is_equal(puz_set.get_entity_id())
assert_that(ev.get_puzzle_index()).is_equal(0)
assert_that(ev.get_count()).is_equal(2)

assert_that(len(Store.events)).is_equal(1)

Store.complete_puzzle_index(puz_set, 0)
assert_that(ev.get_count()).is_equal(3)

func test_puzzle_set_complete_and_unlock_dupe_events_increment_count():
Store.reset_game_data()
assert_that(len(Store.events)).is_equal(0)

var sets = Store.get_puzzle_sets()
var puz_set = sets.filter(func(e): return not e.is_completed())[0]

Store.complete_puzzle_set(puz_set)
Store.complete_puzzle_set(puz_set)
Store.complete_puzzle_set(puz_set)
Store.unlock_next_puzzle_set(puz_set)
Store.unlock_next_puzzle_set(puz_set)

assert_that(len(Store.events)).is_equal(2)
var ev = Store.events[0]
assert_that(ev.get_puzzle_set().get_entity_id()).is_equal(puz_set.get_entity_id())
assert_that(ev.get_count()).is_equal(3)

ev = Store.events[1]
assert_that(ev.get_puzzle_set().get_entity_id()).is_equal(puz_set.get_next_puzzle_set().get_entity_id())
assert_that(ev.get_count()).is_equal(5) # b/c the 'completed' event also unlocks these

0 comments on commit 2486603

Please sign in to comment.