mirror of
https://github.com/geode-sdk/geode.git
synced 2024-11-27 01:45:35 -05:00
add optional ids to node event listeners + properly clean them up
This commit is contained in:
parent
69bd0d99ef
commit
35f7f86e6d
2 changed files with 51 additions and 14 deletions
21
loader/include/Geode/cocos/base_nodes/CCNode.h
vendored
21
loader/include/Geode/cocos/base_nodes/CCNode.h
vendored
|
@ -852,7 +852,10 @@ private:
|
|||
|
||||
GEODE_DLL geode::modifier::FieldContainer* getFieldContainer();
|
||||
GEODE_DLL std::optional<json::Value> getAttributeInternal(std::string const& attribute);
|
||||
GEODE_DLL void addEventListenerInternal(geode::EventListenerProtocol* protocol);
|
||||
GEODE_DLL void addEventListenerInternal(
|
||||
std::string const& id,
|
||||
geode::EventListenerProtocol* protocol
|
||||
);
|
||||
|
||||
public:
|
||||
/**
|
||||
|
@ -1003,24 +1006,28 @@ public:
|
|||
|
||||
template <class Filter, class... Args>
|
||||
geode::EventListenerProtocol* addEventListener(
|
||||
geode::utils::MiniFunction<typename Filter::Callback> callback, Args&&... args
|
||||
std::string const& id,
|
||||
geode::utils::MiniFunction<typename Filter::Callback> callback,
|
||||
Args&&... args
|
||||
) {
|
||||
auto listener = new geode::EventListener<Filter>(
|
||||
callback, Filter(this, std::forward<Args>(args)...)
|
||||
);
|
||||
this->addEventListenerInternal(listener);
|
||||
this->addEventListenerInternal(id, listener);
|
||||
return listener;
|
||||
}
|
||||
template <class Ev, class... Args>
|
||||
template <class Filter, class... Args>
|
||||
geode::EventListenerProtocol* addEventListener(
|
||||
geode::utils::MiniFunction<geode::ListenerResult(Ev*)> callback,
|
||||
geode::utils::MiniFunction<typename Filter::Callback> callback,
|
||||
Args&&... args
|
||||
) {
|
||||
return this->template addEventListener<typename Ev::Filter>(
|
||||
callback, std::forward<Args>(args)...
|
||||
return this->template addEventListener<Filter, Args...>(
|
||||
"", callback, std::forward<Args>(args)...
|
||||
);
|
||||
}
|
||||
GEODE_DLL void removeEventListener(geode::EventListenerProtocol* listener);
|
||||
GEODE_DLL void removeEventListener(std::string const& id);
|
||||
GEODE_DLL geode::EventListenerProtocol* getEventListener(std::string const& id);
|
||||
|
||||
/// @{
|
||||
/// @name Shader Program
|
||||
|
|
|
@ -22,7 +22,8 @@ private:
|
|||
Ref<Layout> m_layout = nullptr;
|
||||
std::unique_ptr<LayoutOptions> m_layoutOptions = nullptr;
|
||||
std::unordered_map<std::string, json::Value> m_attributes;
|
||||
std::vector<EventListenerProtocol*> m_eventListeners;
|
||||
std::unordered_set<std::unique_ptr<EventListenerProtocol>> m_eventListeners;
|
||||
std::unordered_map<std::string, std::unique_ptr<EventListenerProtocol>> m_idEventListeners;
|
||||
|
||||
friend class ProxyCCNode;
|
||||
friend class cocos2d::CCNode;
|
||||
|
@ -31,9 +32,6 @@ private:
|
|||
|
||||
virtual ~GeodeNodeMetadata() {
|
||||
delete m_fieldContainer;
|
||||
for (auto& listener : m_eventListeners) {
|
||||
delete listener;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -195,12 +193,44 @@ std::optional<json::Value> CCNode::getAttributeInternal(std::string const& attr)
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
void CCNode::addEventListenerInternal(EventListenerProtocol* listener) {
|
||||
GeodeNodeMetadata::set(this)->m_eventListeners.push_back(listener);
|
||||
void CCNode::addEventListenerInternal(std::string const& id, EventListenerProtocol* listener) {
|
||||
auto meta = GeodeNodeMetadata::set(this);
|
||||
if (id.size()) {
|
||||
if (meta->m_idEventListeners.contains(id)) {
|
||||
meta->m_idEventListeners.at(id).reset(listener);
|
||||
}
|
||||
else {
|
||||
meta->m_idEventListeners.emplace(id, listener);
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::erase_if(meta->m_eventListeners, [=](auto& l) {
|
||||
return l.get() == listener;
|
||||
});
|
||||
meta->m_eventListeners.emplace(listener);
|
||||
}
|
||||
}
|
||||
|
||||
void CCNode::removeEventListener(EventListenerProtocol* listener) {
|
||||
ranges::remove(GeodeNodeMetadata::set(this)->m_eventListeners, listener);
|
||||
auto meta = GeodeNodeMetadata::set(this);
|
||||
std::erase_if(meta->m_eventListeners, [=](auto& l) {
|
||||
return l.get() == listener;
|
||||
});
|
||||
std::erase_if(meta->m_idEventListeners, [=](auto& l) {
|
||||
return l.second.get() == listener;
|
||||
});
|
||||
}
|
||||
|
||||
void CCNode::removeEventListener(std::string const& id) {
|
||||
GeodeNodeMetadata::set(this)->m_idEventListeners.erase(id);
|
||||
}
|
||||
|
||||
EventListenerProtocol* CCNode::getEventListener(std::string const& id) {
|
||||
auto meta = GeodeNodeMetadata::set(this);
|
||||
if (meta->m_idEventListeners.contains(id)) {
|
||||
return meta->m_idEventListeners.at(id).get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#pragma warning(pop)
|
||||
|
|
Loading…
Reference in a new issue