#pragma once #include #include #include namespace DFHack { //////////// // Locking mechanisms for control over pausing namespace Pausing { class Lock { bool locked = false; public: const std::string name; explicit Lock(const char* name) : name(name){} 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 reportLocks(color_ostream &out) = 0; }; // non-blocking lock resource used in conjunction with the announcement functions in World class AnnouncementLock : public Lock { static std::unordered_set locks; public: explicit AnnouncementLock(const char* name): Lock(name) { locks.emplace(this); } ~AnnouncementLock() override { locks.erase(this); } bool captureState(); // captures the state of announcement settings, iff this is the only locked lock (note it does nothing if 0 locks are engaged) 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 class PlayerLock : public Lock { static std::unordered_set locks; public: explicit PlayerLock(const char* name): Lock(name) { locks.emplace(this); } ~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; }; // non-blocking lock resource used in conjunction with the pause set state function in World // todo: integrate with World::SetPauseState // class PauseStateLock : public Lock // { // static std::unordered_set locks; // public: // explicit PauseStateLock(const char* name): Lock(name) { locks.emplace(this); } // ~PauseStateLock() 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 SaveAnnouncementSettings(); // save current announcement pause settings if all locks are open bool RestoreAnnouncementSettings(); // restore saved announcement pause settings if all locks are open and there is state information to restore (returns true if a restore took place) bool EnablePlayerPausing(); // enable player pausing if all locks are open bool DisablePlayerPausing(); // disable player pausing if all locks are open bool IsPlayerPausingEnabled(); // returns whether the player can pause or not void Update(); } }