diff --git a/plugins/spectate/pause.cpp b/plugins/spectate/pause.cpp index 10e8304f4..0c8462580 100644 --- a/plugins/spectate/pause.cpp +++ b/plugins/spectate/pause.cpp @@ -21,7 +21,6 @@ namespace pausing { const size_t announcement_flag_arr_size = sizeof(decltype(df::announcements::flags)) / sizeof(df::announcement_flags); bool state_saved = false; // indicates whether a restore state is ok - bool announcements_disabled = false; // indicates whether disable or restore was last enacted, could use a better name bool saved_states[announcement_flag_arr_size]; // state to restore bool locked_states[announcement_flag_arr_size]; // locked state (re-applied each frame) bool allow_player_pause = true; // toggles player pause ability @@ -70,6 +69,16 @@ inline bool only_or_none_locked(Locks locks, LockT* this_lock) { return true; } +template +inline bool reportLockedLocks(color_ostream &out, Locks locks) { + for (auto &L: locks) { + if (L->isLocked()) { + out.print("Lock '%s' is locked\n", L->name.c_str()); + } + } + return true; +} + bool AnnouncementLock::captureState() { if (only_or_none_locked(locks, this)) { for (size_t i = 0; i < announcement_flag_arr_size; ++i) { @@ -93,6 +102,10 @@ bool AnnouncementLock::isOnlyLocked() const { return only_lock(locks, this); } +void AnnouncementLock::reportLocks(color_ostream &out) { + reportLockedLocks(out, locks); +} + bool PlayerLock::isAnyLocked() const { return any_lock(locks); } @@ -101,14 +114,19 @@ bool PlayerLock::isOnlyLocked() const { return only_lock(locks, this); } -bool World::DisableAnnouncementPausing() { +void PlayerLock::reportLocks(color_ostream &out) { + reportLockedLocks(out, locks); +} + +bool World::DisableAnnouncementPausing(color_ostream &out) { if (!announcementLock.isAnyLocked()) { for (auto& flag : df::global::d_init->announcements.flags) { flag.bits.PAUSE = false; + //out.print("pause: %d\n", flag.bits.PAUSE); } - announcements_disabled = true; + return true; } - return announcements_disabled; + return false; } bool World::SaveAnnouncementSettings() { @@ -116,6 +134,7 @@ bool World::SaveAnnouncementSettings() { for (size_t i = 0; i < announcement_flag_arr_size; ++i) { saved_states[i] = df::global::d_init->announcements.flags[i].bits.PAUSE; } + state_saved = true; return true; } return false; @@ -126,7 +145,6 @@ bool World::RestoreAnnouncementSettings() { for (size_t i = 0; i < announcement_flag_arr_size; ++i) { df::global::d_init->announcements.flags[i].bits.PAUSE = saved_states[i]; } - announcements_disabled = false; return true; } return false; diff --git a/plugins/spectate/pause.h b/plugins/spectate/pause.h index 98d703998..90e884b90 100644 --- a/plugins/spectate/pause.h +++ b/plugins/spectate/pause.h @@ -1,6 +1,8 @@ #pragma once #include #include +#include +#include namespace DFHack { //////////// @@ -9,16 +11,17 @@ namespace DFHack { { class Lock { - bool locked = false; - std::string name; + std::atomic_bool locked{}; public: - explicit Lock(const char* name) { this->name = name;}; + const std::string name; + explicit Lock(const char* name) : name(name){ locked = false; } virtual ~Lock()= default; virtual bool isAnyLocked() const = 0; virtual bool isOnlyLocked() const = 0; bool isLocked() const { return locked; } - virtual void lock() { locked = true; }; //simply locks the lock - void unlock() { locked = false; }; + virtual void lock() { locked = true; } //simply locks the lock + void unlock() { locked = false; } + virtual void reportLocks(color_ostream &out) = 0; }; // non-blocking lock resource used in conjunction with the announcement functions in World @@ -32,6 +35,7 @@ namespace DFHack { void lock() override; // locks and attempts to capture state bool isAnyLocked() const override; // returns true if any instance of AnnouncementLock is locked bool isOnlyLocked() const override; // returns true if locked and no other instance is locked + void reportLocks(color_ostream &out) override; }; // non-blocking lock resource used in conjunction with the Player pause functions in World @@ -43,10 +47,11 @@ namespace DFHack { ~PlayerLock() override { locks.erase(this); } bool isAnyLocked() const override; // returns true if any instance of PlayerLock is locked bool isOnlyLocked() const override; // returns true if locked and no other instance is locked + void reportLocks(color_ostream &out) override; }; } namespace World { - bool DisableAnnouncementPausing(); // disable announcement pausing if all locks are open + bool DisableAnnouncementPausing(color_ostream &out); // disable announcement pausing if all locks are open bool SaveAnnouncementSettings(); // save current announcement pause settings if all locks are open bool RestoreAnnouncementSettings(); // restore saved announcement pause settings if all locks are open