mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 06:47:35 +00:00
LibCore: Add typed find_child and find_descendant helpers to Object
These look a lot like the parallel functionality in GUI::Widget :). These use dynamic_cast now, to make use of that RTTI we just added.
This commit is contained in:
parent
350d4d3543
commit
5b03a0867f
1 changed files with 41 additions and 4 deletions
|
@ -91,7 +91,13 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Callback>
|
template<typename T, typename Callback>
|
||||||
void for_each_child_of_type(Callback callback);
|
void for_each_child_of_type(Callback callback) requires IsBaseOf<Object, T>::value;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* find_child_of_type_named(const String&) requires IsBaseOf<Object, T>::value;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* find_descendant_of_type_named(const String&) requires IsBaseOf<Object, T>::value;
|
||||||
|
|
||||||
bool is_ancestor_of(const Object&) const;
|
bool is_ancestor_of(const Object&) const;
|
||||||
|
|
||||||
|
@ -181,15 +187,46 @@ struct Formatter<Core::Object> : Formatter<StringView> {
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
template<typename T, typename Callback>
|
template<typename T, typename Callback>
|
||||||
inline void Object::for_each_child_of_type(Callback callback)
|
inline void Object::for_each_child_of_type(Callback callback) requires IsBaseOf<Object, T>::value
|
||||||
{
|
{
|
||||||
for_each_child([&](auto& child) {
|
for_each_child([&](auto& child) {
|
||||||
if (is<T>(child))
|
if (auto* child_as_t = dynamic_cast<T*>(&child); child_as_t)
|
||||||
return callback(downcast<T>(child));
|
return callback(*child_as_t);
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* Object::find_child_of_type_named(const String& name) requires IsBaseOf<Object, T>::value
|
||||||
|
{
|
||||||
|
T* found_child = nullptr;
|
||||||
|
for_each_child_of_type<T>([&](auto& child) {
|
||||||
|
if (child.name() == name) {
|
||||||
|
found_child = &child;
|
||||||
|
return IterationDecision::Break;
|
||||||
|
}
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
|
||||||
|
return found_child;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T* Object::find_descendant_of_type_named(const String& name) requires IsBaseOf<Object, T>::value
|
||||||
|
{
|
||||||
|
auto* this_as_t = dynamic_cast<T*>(this);
|
||||||
|
if (this_as_t && this->name() == name)
|
||||||
|
return this_as_t;
|
||||||
|
T* found_child = nullptr;
|
||||||
|
for_each_child([&](auto& child) {
|
||||||
|
found_child = child.template find_descendant_of_type_named<T>(name);
|
||||||
|
if (found_child)
|
||||||
|
return IterationDecision::Break;
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
|
return found_child;
|
||||||
|
}
|
||||||
|
|
||||||
const LogStream& operator<<(const LogStream&, const Object&);
|
const LogStream& operator<<(const LogStream&, const Object&);
|
||||||
|
|
||||||
#define REGISTER_INT_PROPERTY(property_name, getter, setter) \
|
#define REGISTER_INT_PROPERTY(property_name, getter, setter) \
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue