Skip to content

Commit

Permalink
Load-state always gives the savestate's replay
Browse files Browse the repository at this point in the history
The old behavior was confusing when you had the tweaker open and wanted
to stash your entire timeline with save-state and load-state.
  • Loading branch information
SimonN committed Jan 9, 2023
1 parent 561f5d4 commit 5a9e27c
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 53 deletions.
94 changes: 44 additions & 50 deletions src/file/replay/replay.d
Original file line number Diff line number Diff line change
Expand Up @@ -183,21 +183,52 @@ public:
_players[nr] = p;
}

bool wasPlayedBy(string who) const pure nothrow @safe @nogc
{
return _players.byValue.canFind!(pl => pl.name == who);
}
const pure nothrow @safe @nogc {
bool wasPlayedBy(string who)
{
return _players.byValue.canFind!(pl => pl.name == who);
}

// This doesn't check whether the metadata/general data is the same.
// We assume that Game only calls this on replays of the same level.
// "Before" is exclusive, you might want to pass Phyu(now + 1).
bool equalBefore(in Replay rhs, in Phyu before) const @nogc nothrow
in {
assert (rhs !is null);
/*
* equalBefore(), extends():
* These don't check whether the metadata/general data is the same.
* We assume that Game only calls this on replays of the same level.
* "Before" is exclusive, you might want to pass Phyu(now + 1).
*/
bool equalBefore(in Replay rhs, in Phyu t)
in { assert (rhs !is null); }
do {
return this.plySliceBefore(t) == rhs.plySliceBefore(t);
}

bool extends(in Replay rhs)
in { assert (rhs !is null); }
do {
immutable rlen = rhs._plies.length;
return _plies.length >= rlen && _plies[0 .. rlen] == rhs._plies[];
}

/*
* Call allPlies() rarely, e.g., to list all entries in the tweaker.
* Prefer to call plySliceFor().
*/
const(Ply)[] allPlies() { return _plies; }
const(Ply)[] plySliceFor(in Phyu upd)
{
auto slice = this.plySliceBefore(Phyu(upd + 1));
int firstGood = slice.len;
while (firstGood > 0 && slice[firstGood - 1].update == upd)
--firstGood;
assert (firstGood >= 0);
assert (firstGood <= slice.length);
return _plies[firstGood .. slice.length];
}
}
do {
return this.plySliceBefore(before)
== rhs.plySliceBefore(before);

void add(in Ply d)
{
touch();
this.addWithoutTouching(d);
}

void eraseEarlySingleplayerNukes()
Expand Down Expand Up @@ -271,43 +302,6 @@ public:
touch();
}

/*
* Our users should prefer to call plySliceFor() over allPlies().
*/
const(Ply)[] plySliceFor(in Phyu upd) const pure nothrow @nogc
{
auto slice = this.plySliceBefore(Phyu(upd + 1));
int firstGood = slice.len;
while (firstGood > 0 && slice[firstGood - 1].update == upd)
--firstGood;
assert (firstGood >= 0);
assert (firstGood <= slice.length);
return _plies[firstGood .. slice.length];
}

/*
* Call allPlies() rarely, e.g., to list all entries in the replay editor.
*/
@property const(Ply)[] allPlies() const pure nothrow @nogc
{
return _plies;
}

bool getOnPhyuLixClicked(in Phyu upd, in int lix_id, in Ac ac) const
{
auto vec = plySliceFor(upd);
foreach (const ref d; vec)
if (d.isSomeAssignment && d.toWhichLix == lix_id && d.skill == ac)
return true;
return false;
}

void add(in Ply d)
{
touch();
this.addWithoutTouching(d);
}

/*
* See file.replay.change for what it returns.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/file/replay/tweakimp.d
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ do {
inout(Ply)[] plySliceBefore(
inout(Replay) rep,
in Phyu upd
) pure nothrow @nogc { with (rep)
) pure nothrow @safe @nogc { with (rep)
{
// The binary search algo works also for this case.
// But we add mostly to the end of the data, so check here for speed.
Expand Down
10 changes: 8 additions & 2 deletions src/game/nurse/savestat.d
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,15 @@ public:
auto loaded = _cache.loadUser(replay, Phyu(cs.update + 1));
model.takeOwnershipOf(loaded.state.clone);

if (! replay.equalBefore(loaded.replay, Phyu(upd + 1))) {
// Now, upd is the loaded state's physics update, not our old update.
immutable bool eqb = replay.equalBefore(loaded.replay, Phyu(upd + 1));
immutable bool ext = replay.extends(loaded.replay);
if (! eqb || ! ext) {
replay = loaded.replay.clone();
onCutGlobalFutureFromReplay(); // don't cut, but maybe play sound
if (! eqb) {
// A visible difference already at upd().
onCutGlobalFutureFromReplay(); // Don't cut, but play sound.
}
}
if (! replayAfterFrameBack.value) {
cutGlobalFutureFromReplay();
Expand Down

0 comments on commit 5a9e27c

Please sign in to comment.