diff options
author | Alexey Rusakov <Kitsune-Ral@users.sf.net> | 2022-08-09 18:42:24 +0200 |
---|---|---|
committer | Alexey Rusakov <Kitsune-Ral@users.sf.net> | 2022-09-04 18:42:11 +0200 |
commit | a18f505fe7ca66556d66538a7c9b9ff31d2c1b29 (patch) | |
tree | 19a01e8f42a10f6086b0dda6dc8ec14f8a784a53 /lib/events/event.cpp | |
parent | a26147582ce8cbd6a5206aee4b59de98c9dfe9b6 (diff) | |
download | libquotient-a18f505fe7ca66556d66538a7c9b9ff31d2c1b29.tar.gz libquotient-a18f505fe7ca66556d66538a7c9b9ff31d2c1b29.zip |
EventMetaType, QUO_EVENT, QUO_BASE_EVENT
The new metatype framework replaces
EventFactory/DEFINE_EVENT_TYPEID/REGISTER_EVENT_TYPE; it is faster,
more functional and extensible. Of note:
- EventMetaType mostly reproduces the logic of EventFactory but supports
custom base event types not just for loading (that part EventFactory
also supported) but also for matching - previously you had to have
Event::is*Event() for base type matching. Now Quotient::is() can
match against both base and leaf types.
- Instead of DEFINE_EVENT_TYPEID and REGISTER_EVENT_TYPE there's now
a single macro, QUO_EVENT, intended for use in the way similar to
Q_OBJECT. Actually, the entire framework borrows heavily from
QMetaObject and Q_OBJECT. Making event types full-fledged QObjects
is still not considered because half of QObject functions would not
be applicable (e.g. signals/slots) while another half (in particular,
using Matrix type ids to select event types) would still have to be
done on top of QObject. And QML can just access events as
const QJsonObjects which is arguably more lightweight as well.
- QUO_BASE_EVENT is a new macro replacing EventFactory object
definitions. This was necessary for the same reason why Q_OBJECT is
a macro: aside from a static object definition, this macro
introduces a virtual function override to resolve the metatype at
runtime. This very mechanism is used to make event type
matching/casting as quick as possible
- QUO_BASE_EVENT and QUO_EVENT use the C++20 __VA_OPT__ feature that
is only available with the new MSVC preprocessor (see
https://docs.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview);
the respective switch was added to CMakeLists.txt.
Diffstat (limited to 'lib/events/event.cpp')
-rw-r--r-- | lib/events/event.cpp | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/lib/events/event.cpp b/lib/events/event.cpp index 1f1eebaa..595e20a5 100644 --- a/lib/events/event.cpp +++ b/lib/events/event.cpp @@ -4,6 +4,7 @@ #include "event.h" #include "logging.h" +#include "stateevent.h" #include <QtCore/QJsonDocument> @@ -11,12 +12,38 @@ using namespace Quotient; QString EventTypeRegistry::getMatrixType(event_type_t typeId) { return typeId; } -void _impl::EventFactoryBase::logAddingMethod(event_type_t TypeId, - size_t newSize) +void AbstractEventMetaType::addDerived(AbstractEventMetaType* newType) { - qDebug(EVENTS) << "Adding factory method for" << TypeId << "events;" - << newSize << "methods will be in the" << name - << "chain"; + if (const auto existing = + std::find_if(derivedTypes.cbegin(), derivedTypes.cend(), + [&newType](const AbstractEventMetaType* t) { + return t->matrixId == newType->matrixId; + }); + existing != derivedTypes.cend()) + { + if (*existing == newType) + return; + // Two different metatype objects claim the same Matrix type id; this + // is not normal, so give as much information as possible to diagnose + if ((*existing)->className == newType->className) { + qCritical(EVENTS) + << newType->className << "claims" << newType->matrixId + << "repeatedly; check that it's exported across translation " + "units or shared objects"; + Q_ASSERT(false); // That situation is plain wrong + return; // So maybe std::terminate() even? + } + qWarning(EVENTS).nospace() + << newType->matrixId << " is already mapped to " + << (*existing)->className << " before " << newType->className + << "; unless the two have different isValid() conditions, the " + "latter class will never be used"; + } + derivedTypes.emplace_back(newType); + qDebug(EVENTS).nospace() + << newType->matrixId << " -> " << newType->className << "; " + << derivedTypes.size() << " derived type(s) registered for " + << className; } Event::Event(Type type, const QJsonObject& json) : _type(type), _json(json) @@ -48,6 +75,10 @@ const QJsonObject Event::unsignedJson() const return fullJson()[UnsignedKeyL].toObject(); } +bool Event::isStateEvent() const { return is<StateEventBase>(); } + +bool Event::isCallEvent() const { return is<CallEventBase>(); } + void Event::dumpTo(QDebug dbg) const { dbg << QJsonDocument(contentJson()).toJson(QJsonDocument::Compact); |