mirror of
https://github.com/zenorogue/hyperrogue.git
synced 2025-02-01 03:39:16 +00:00
Replace the hookset
typedef with a full-blown class type. NFC.
This restricts the "API surface area" of `hookset` to just these three accessor methods; there's no longer any way to break into a hookset and iterate it manually, or erase elements from a hookset, or ask for its size, or anything else that you could have done given the raw `std::map *`.
This commit is contained in:
parent
961a8919c6
commit
d1458b3ee5
59
hyper.h
59
hyper.h
@ -407,9 +407,41 @@ struct movedir {
|
||||
|
||||
// shmup
|
||||
|
||||
template<class T> class hookset_impl : public map<int, function<T>> {};
|
||||
template<class T> using hookset = hookset_impl<T> *;
|
||||
using purehookset = hookset_impl<void()> *;
|
||||
template<class T>
|
||||
class hookset {
|
||||
std::map<int, std::function<T>> *map_ = nullptr;
|
||||
|
||||
public:
|
||||
template<class U>
|
||||
int add(int prio, U&& hook) {
|
||||
if (map_ == nullptr) map_ = new std::map<int, std::function<T>>();
|
||||
while (map_->count(prio)) {
|
||||
prio++;
|
||||
}
|
||||
map_->emplace(prio, static_cast<U&&>(hook));
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<class... U>
|
||||
void callhooks(U&&... args) const {
|
||||
if (map_ == nullptr) return;
|
||||
for (const auto& p : *map_) {
|
||||
p.second(static_cast<U&&>(args)...);
|
||||
}
|
||||
}
|
||||
|
||||
template<class V, class... U>
|
||||
V callhandlers(V zero, U&&... args) const {
|
||||
if (map_ == nullptr) return zero;
|
||||
for (const auto& p : *map_) {
|
||||
auto z = p.second(static_cast<U&&>(args)...);
|
||||
if (z != zero) return z;
|
||||
}
|
||||
return zero;
|
||||
}
|
||||
};
|
||||
|
||||
using purehookset = hookset<void()>;
|
||||
|
||||
static const int NOHINT = -1;
|
||||
|
||||
@ -634,25 +666,16 @@ color_t darkena(color_t c, int lev, int a);
|
||||
|
||||
static const int DISTANCE_UNKNOWN = 127;
|
||||
|
||||
template<class T, class U> int addHook(hookset<T>& m, int prio, const U& hook) {
|
||||
if(!m) m = new hookset_impl<T> ();
|
||||
while(m->count(prio)) {
|
||||
prio++;
|
||||
}
|
||||
(*m)[prio] = hook;
|
||||
return 0;
|
||||
template<class T, class U> int addHook(hookset<T>& m, int prio, U&& hook) {
|
||||
return m.add(prio, static_cast<U&&>(hook));
|
||||
}
|
||||
|
||||
template<class T, class... U> void callhooks(hookset<T> h, U&&... args) {
|
||||
if(h) for(auto& p: *h) p.second(std::forward<U>(args)...);
|
||||
template<class T, class... U> void callhooks(const hookset<T>& h, U&&... args) {
|
||||
return h.callhooks(static_cast<U&&>(args)...);
|
||||
}
|
||||
|
||||
template<class T, class V, class... U> V callhandlers(V zero, hookset<T> h, U&&... args) {
|
||||
if(h) for(auto& p: *h) {
|
||||
auto z = p.second(std::forward<U>(args)...);
|
||||
if(z != zero) return z;
|
||||
}
|
||||
return zero;
|
||||
template<class T, class V, class... U> V callhandlers(V zero, const hookset<T>& h, U&&... args) {
|
||||
return h.callhandlers(zero, static_cast<U&&>(args)...);
|
||||
}
|
||||
|
||||
string XLAT(string);
|
||||
|
Loading…
Reference in New Issue
Block a user