Age | Commit message (Collapse) | Author |
|
|
|
Get rid of that Q_ASSERT() in the middle that only worked in Debug
builds anyway.
|
|
RelatesTo and EventRelation have been two means to the same end in two
different contexts. (Modernised) EventRelation is the one used now both
for ReactionEvent and EventContent::TextContent. The modernisation
mostly boils down to using inline variables instead of functions to
return relation types and switching to QLatin1String from const char*
(because we know exactly that those constants are Latin-1 and
QLatin1String is more efficient than const char* to compare/convert to
QString).
|
|
When internal linkage is necessary, anonymous namespaces fulfil the same
purpose in a better way. See also:
https://stackoverflow.com/questions/4422507/superiority-of-unnamed-namespace-over-static
|
|
It's better than const char* because any interaction between const char*
and QString assumes that const char* contains UTF-8, which is
pessimistic and therefore inefficient; at the same time:
- construction of QString from QLatin1String is extremely fast
(boiling down to padding null bytes)
- "something"_ls is much shorter than QStringLiteral("something")
- "something"_ls produces a direct pointer to the literal at compile
time, using the benefits of raw string literals (deduplication, e.g.)
The library API will also transition to QLatin1String where applicable,
likely in 0.8.
|
|
- Templates and constexpr imply inline
- A function called from a single site better be inlined.
|
|
|
|
It doesn't need all those things inside - order_type alias is no more
in use; operator<() is better outside; QLatin1String is better to
compare against than const char* (because const char* is assumed to be
UTF-8); and TagRecord is really small so it doesn't need const& for
parameters.
|
|
Those are already inherited with 'using'.
|
|
|
|
|
|
On Windows QUOTIENT_API expands to different things depending on whether
the library is built or used. This results in confusing statements (and
MSVC erroring out on them, in some cases - see below - quite
legitimately) not only when the application includes Quotient headers
but also when the application defines custom events and uses
REGISTER_EVENT_TYPE to make them creatable from /sync responses.
To avoid repeated registration when dynamic linking is involved,
EventFactory<>::addMethod() now bluntly looks up the method for this
type in the vector of already registered methods. It would surely be
quicker to use a static variable instead; but since the refreshed API
for addMethod returns a reference to the factory method it's necessary
to do this lookup anyway. Once the primary goal of this branch is
achieved across platforms I might experiment with lighter ways to
register factory methods; for now here's a minimal change to make
the code build on Windows.
|
|
Thanks to Sonar for reminding that constexpr implies inline.
|
|
Pinned message support
|
|
Before all, this fixes the problem with double-initialising of type ids;
it could have been fixed with a smaller change but EventTypeRegistry
is fairly superfluous now when inline variables are a thing and it's
possible to have an extensible registry system using literally pointers
to the memory that are guaranteed to be unique. That being said,
event_type_t is still QLatin1String and not a bare const char* (or
void*), mostly to stay on the safe side when it comes to type
identities: unlike const char*, QLatin1String's are deep-compared,
meaning that matching for switchOnType (former visit) occurs a bit
slower now. This may change in the future; but this is the first step
in getting rid of EventTypeRegistry.
This change means that initializeTypeId is no more needed; also, two
static member functions, typeId() and matrixTypeId(), are being replaced
with a single inline static member variable, TypeId. This commit doesn't
apply that transition across the event types, meaning that you'll get
a pile of warnings when compiling the library. These warnings will be
tackled in further commits within this branch.
|
|
Strictly speaking, EventFactory can be further instantiated if any
client application figures they need a whole new base class for events
and respectively a separate EventFactory specialisation for it.
Where this whole commit started though was a linkage error because I
did not plan to expose Quotient-specific logging categories for linkage
(effectively, usage) from the client code - meanwhile the inline code
of EventFactory uses qDebug(EVENTS), meaning I had to either add
QUOTIENT_API to EVENTS or hide those invocations. This in turn led
to trimming the EventFactory constructor back to trivial implementation
and dropping the guard variable that was supposed to trace duplicate
EventFactory<BaseEventT> objects for the same BaseEventT - with the
reasoning that such situation is not really dangerous (unlike
EventTypeRegistry double-initialisation fiasco, see #413), and at the
same time it can be easily detected in the logs by duplicated factory
method registration messages. And while I was at it, I replaced the
meaningless bool in the return type of EventFactory<>::addMethod with
the slightly more (but still barely) useful reference to the inserted
factory method. One can (in theory) use it now if they need to turn
some event JSON into an object of some specific event type or nullptr
if the event type in the JSON payload doesn't match - but at the same
rate (for now at least) one can call makeIfMatches<EventT>() directly.
With this commit, both Quotest and Quaternion build and link using
either Clang or GCC even under -fvisibility=hidden. However, running
quotest now reproduces #413, which is a matter of event typeId
infrastructure refactoring, coming in further commits.
|
|
This include all (hopefully) classes/structures and functions that have
non-inline definitions, as well as namespaces with Q_NAMESPACE since
those have non-inline (as of Qt 5.15) QMetaObject - for that a new
macro, QUO_NAMESPACE, has been devised to accommodate the lack of
Q_NAMESPACE_EXPORT in Qt before 5.14.
|
|
Fixes a clang-tidy warning.
|
|
|
|
This is a leftover from deferred `name` initialisation that wasn't
needed in the end.
|
|
|
|
|
|
|
|
The former code assumed that EventFactory<> is just a class-level shell
for a bunch of functions and a static data member that only exists to
allow specialisations to occur for the whole group together. On top of
that, setupFactory() and registerEventType() strived to protect this
group from double registration coming from static variables in an
anonymous namespace produced by REGISTER_EVENT_TYPE.
The whole thing is now de-static-ed: resolving the factory now relies
on class-static Event/RoomEvent/StateEventBase::factory variables
instead of factory_t type aliases; and REGISTER_EVENT_TYPE produces
non-static inline variables instead, obviating the need of
registerEventType/setupFactory kludge.
|
|
Objects derived from Event are not room events (in the spec sense) and
never occur in the same arrays as room events; therefore this chaining
has always been superfluous.
|
|
Also: extended quotest to cover member renames, not just user profile renames.
|
|
Also, RoomAliasesEvent is to be completely gone after 0.7.
|
|
Quotient::function_traits<> did not support member functions in a proper
way (i.e. the way std::invoke_result<> treats them, with the function's
owning class represented as the first parameter). Now that I gained
the skill and understanding in function_traits<> somewhat wicked
machinery, I could properly support member functions. Overloads and
generic lambdas are not supported but maybe we'll get to those one day.
|
|
It has not much to do with the Visitor design pattern; also,
std::visit() has different conventions on the order of parameters.
|
|
Proper linters recognise that the returned types are not primitive,
while people might still be confused a bit.
|
|
In both fixed cases the callee accepts a const reference, which makes
std::move() useless. Static analyzers apparently missed them because
the cases are inside a macro.
|
|
Similar to contentPart() - apparently there are enough places across
the code that would benefit from it.
|
|
Given that QJsonObject only accepts QStrings in the list constructor,
the template is useless cruft.
|
|
There's a clash between Event::content() (a template function) and
RoomMessageEvent::content() (plain member). Out of these two, the name
more fits to the RME's member function - strictly speaking,
Event::content() retrieves a part of content, and so is renamed.
In addition, contentPart() defaults to QJsonValue now, which is pretty
intuitive (the function returns values from a JSON object) and allows
to implement more elaborate logic such as
if (const auto v = contentPart<>("key"_ls); v.isObject()) {
// foo
} else if (v.isString()) {
// bar
} else {
// boo
}
|
|
Doesn't really help build times, instead breaking the build on older Qt.
|
|
The "original JSON" wording is misleading: the returned JSON can be and
is routinely edited as a part of event construction, redaction, editing.
Also, originalJson() name is misleading in that it returns a stringified
(in a very specific way) JSON and not an object. You have to call
fullJson() to get the object, and originalJsonObject(), confusingly,
returns exactly the same thing but as a value rather than as
a reference. The original intention of keeping originalJsonObject() was
to make it Q_INVOKABLE or use it as an accessor for a Q_PROPERTY.
unfortunately, this was never really practical as discussed in
the previous commit.
All that implies that clients have to handle passing event JSON to QML
themselves, in the form they prefer (as an object or a string). The
added complexity is negligible though; on the other hand, there's added
flexibility in, e.g., choosing a compact instead of default JSON layout
or even generate a highlighted JSON representation.
|
|
Makes compilation a tad lighter.
|
|
Q_GADGET is generally used to enable two things outside of QObject:
Q_PROPERTY/Q_INVOKABLE and Q_ENUM/Q_FLAG. While the latter can be used
in its own right in QML, the former requires Q_GADGET instances to be
passed to QML by value, which is not really possible with
uncopyable/unassignable classes. Bottom line is that Q_PROPERTY in
anything derived from Quotient::Event is not viable, making Q_GADGET
macro useless unless there's a Q_ENUM/Q_FLAG (as is the case with
RoomMessageEvent, e.g.).
|
|
|
|
Makes the Room::P::toJson() code more readable.
|
|
DISABLE_MOVE is no more; instead, the library provides Q_DISABLE_MOVE
(and also Q_DISABLE_COPY_MOVE while at it) for Qt pre-5.13 that don't
have it yet. Same for QT_IGNORE_DEPRECATIONS - it only arrived in 5.15
but all the building pieces existed prior so libQuotient has it
regardless of the Qt version used for building.
|
|
Closes #514.
|
|
|
|
|
|
|
|
EncryptionEvent constructor
|
|
Use originTimestamp(); the corresponding Q_PROPERTY was not renamed
(in error) so it is now.
|
|
BaseJob: StatusCode::JsonParseError
Connection: resolved() and reconnected() signals; roomMap(); postReceipt()
User: bridged() and rawName()
ConnectionData: setHost() and setPort()
StateEventBase: prev_content()
|
|
|
|
RoomAliasesEvent is no more even registered (meaning that the library
will load m.room.aliases as unknown state events); quotest code updated
to use historyEdge() instead of timelineEdge().
|