1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 06:17:34 +00:00

LibCore: Move LibGUI/GObject to LibCore/CObject.

This commit is contained in:
Andreas Kling 2019-04-10 17:01:54 +02:00
parent b8062f69d8
commit 2f1f51b8ab
30 changed files with 144 additions and 75 deletions

View file

@ -1,7 +1,7 @@
#include <LibCore/CEvent.h>
#include <LibGUI/GObject.h>
#include <LibCore/CObject.h>
CChildEvent::CChildEvent(Type type, GObject& child)
CChildEvent::CChildEvent(Type type, CObject& child)
: CEvent(type)
, m_child(child.make_weak_ptr())
{

69
LibCore/CEvent.h Normal file
View file

@ -0,0 +1,69 @@
#pragma once
#include <AK/AKString.h>
#include <AK/Types.h>
#include <AK/WeakPtr.h>
#include <AK/Function.h>
class CObject;
class CEvent {
public:
enum Type {
Invalid = 0,
Quit,
Timer,
DeferredDestroy,
DeferredInvoke,
ChildAdded,
ChildRemoved,
};
CEvent() { }
explicit CEvent(unsigned type) : m_type(type) { }
virtual ~CEvent() { }
unsigned type() const { return m_type; }
private:
unsigned m_type { Type::Invalid };
};
class CDeferredInvocationEvent : public CEvent {
friend class GEventLoop;
public:
CDeferredInvocationEvent(Function<void(CObject&)> invokee)
: CEvent(CEvent::Type::DeferredInvoke)
, m_invokee(move(invokee))
{
}
private:
Function<void(CObject&)> m_invokee;
};
class CTimerEvent final : public CEvent {
public:
explicit CTimerEvent(int timer_id)
: CEvent(CEvent::Timer), m_timer_id(timer_id)
{
}
~CTimerEvent() { }
int timer_id() const { return m_timer_id; }
private:
int m_timer_id;
};
class CChildEvent final : public CEvent {
public:
CChildEvent(Type, CObject& child);
~CChildEvent();
CObject* child() { return m_child.ptr(); }
const CObject* child() const { return m_child.ptr(); }
private:
WeakPtr<CObject> m_child;
};

107
LibCore/CObject.cpp Normal file
View file

@ -0,0 +1,107 @@
#include <LibCore/CObject.h>
#include <LibCore/CEvent.h>
#include <LibGUI/GEventLoop.h>
#include <AK/Assertions.h>
#include <stdio.h>
CObject::CObject(CObject* parent)
: m_parent(parent)
{
if (m_parent)
m_parent->add_child(*this);
}
CObject::~CObject()
{
stop_timer();
if (m_parent)
m_parent->remove_child(*this);
auto children_to_delete = move(m_children);
for (auto* child : children_to_delete)
delete child;
}
void CObject::event(CEvent& event)
{
switch (event.type()) {
case GEvent::Timer:
return timer_event(static_cast<CTimerEvent&>(event));
case GEvent::DeferredDestroy:
delete this;
break;
case GEvent::ChildAdded:
case GEvent::ChildRemoved:
return child_event(static_cast<CChildEvent&>(event));
case GEvent::Invalid:
ASSERT_NOT_REACHED();
break;
default:
break;
}
}
void CObject::add_child(CObject& object)
{
m_children.append(&object);
GEventLoop::current().post_event(*this, make<CChildEvent>(GEvent::ChildAdded, object));
}
void CObject::remove_child(CObject& object)
{
for (ssize_t i = 0; i < m_children.size(); ++i) {
if (m_children[i] == &object) {
m_children.remove(i);
GEventLoop::current().post_event(*this, make<CChildEvent>(GEvent::ChildRemoved, object));
return;
}
}
}
void CObject::timer_event(CTimerEvent&)
{
}
void CObject::child_event(CChildEvent&)
{
}
void CObject::start_timer(int ms)
{
if (m_timer_id) {
dbgprintf("CObject{%p} already has a timer!\n", this);
ASSERT_NOT_REACHED();
}
m_timer_id = GEventLoop::register_timer(*this, ms, true);
}
void CObject::stop_timer()
{
if (!m_timer_id)
return;
bool success = GEventLoop::unregister_timer(m_timer_id);
ASSERT(success);
m_timer_id = 0;
}
void CObject::delete_later()
{
GEventLoop::current().post_event(*this, make<CEvent>(CEvent::DeferredDestroy));
}
void CObject::dump_tree(int indent)
{
for (int i = 0; i < indent; ++i) {
printf(" ");
}
printf("%s{%p}\n", class_name(), this);
for (auto* child : children()) {
child->dump_tree(indent + 2);
}
}
void CObject::deferred_invoke(Function<void(CObject&)> invokee)
{
GEventLoop::current().post_event(*this, make<CDeferredInvocationEvent>(move(invokee)));
}

49
LibCore/CObject.h Normal file
View file

@ -0,0 +1,49 @@
#pragma once
#include <AK/Function.h>
#include <AK/Vector.h>
#include <AK/Weakable.h>
class CEvent;
class CChildEvent;
class CTimerEvent;
class CObject : public Weakable<CObject> {
public:
CObject(CObject* parent = nullptr);
virtual ~CObject();
virtual const char* class_name() const { return "CObject"; }
virtual void event(CEvent&);
Vector<CObject*>& children() { return m_children; }
CObject* parent() { return m_parent; }
const CObject* parent() const { return m_parent; }
void start_timer(int ms);
void stop_timer();
bool has_timer() const { return m_timer_id; }
void add_child(CObject&);
void remove_child(CObject&);
void delete_later();
void dump_tree(int indent = 0);
void deferred_invoke(Function<void(CObject&)>);
virtual bool is_widget() const { return false; }
virtual bool is_window() const { return false; }
protected:
virtual void timer_event(CTimerEvent&);
virtual void child_event(CChildEvent&);
private:
CObject* m_parent { nullptr };
int m_timer_id { 0 };
Vector<CObject*> m_children;
};

View file

@ -1,5 +1,6 @@
OBJS = \
CElapsedTimer.o \
CObject.o \
CEvent.o
LIBRARY = libcore.a