Age | Commit message (Collapse) | Author |
|
|
|
|
|
|
|
[skip ci]
|
|
As mentioned in the commit introducing `Expected`, `QOlmExpected` is
simply an alias for `Expected<T, QOlmError>`. This simplifies quite
a few function signatures in `QOlm*` classes and collapses unwieldy
`std::holds_alternative<>`/`std::get<>` constructs into a neat
contextual bool cast and an invocation of `operator*` or
`value()`/`error()` accessors that don't need to specify the type.
While refactoring the code, I found a couple of cases of mismatching
`uint32_t` and `qint32_t` in return values; a couple of cases where
`decrypt()` returns `QString` which is in fact `QByteArray` (e.g., in
`QOlmSession::decrypt()`); there's a repetitive algorithm in
`Connection::Private::sessionDecryptPrekey()` and
`sessionDecryptGeneral()`
|
|
There's no particular use in letting `QOlmError` out, only to confirm
that, well, `QOlmError` is just another form of no-match.
|
|
Making Qt signals const is an impossible commitment - once the signal
is out, you can't control if any called slot will change the emitting
class or not. The code compiles but const-ness is not preserved.
|
|
This is a minimal implementation along the lines of `std::expected<>`
introduced in C++23; once compilers catch up with C++23 support, it may
become simply a typedef of std::expected. There are no tests as yet; but
the following commits will introduce QOlmExpected that would replace
the current `std::variant<T, QOlmError>` pattern used throughout `QOlm*`
classes, automatically pulling Expected under the coverage of `QOlm*`
unit tests.
|
|
|
|
|
|
Mainly driven by clang-tidy and SonarCloud warnings (sadly, SonarCloud
doesn't store historical reports so no link can be provided here).
|
|
See https://github.com/matrix-org/matrix-spec/pull/1054.
# Conflicts:
# lib/events/callanswerevent.cpp
# lib/events/callanswerevent.h
|
|
QCoreApplication::processEvents() is well-known to be a _wrong_ solution
to the unresponsive UI problem; despite that, connection.cpp has long
had that call to let UI update itself while processing bulky room
updates (mainly from the initial sync). This commit finally fixes this,
after an (admittedly rare) race condition has been hit, as follows:
0. Pre-requisite: quotest runs all the tests and is about to leave
the room; there's an ongoing sync request.
1. Quotest calls /leave
2. Sync returns, with the batch of _several_ rooms (that's important)
3. The above code handles the first room in the batch
4. processEvents() is called, just in time for the /leave response.
5. The /leave response handler in quotest ends up calling
Connection::logout() (processEvents() still hasn't returned).
6. Connection::logout() calls abandon() on the ongoing SyncJob,
pulling the rug from under onSyncSuccess()/consumeRoomData().
7. processEvents() returns and the above code proceeds to the next
room - only to find that the roomDataList (that is a ref to
a structure owned by SyncJob), is now pointing to garbage.
Morals of the story:
1. processEvents() effectively makes code multi-threaded: one flow is
suspended and another one may run _on the same data_. After the first
flow is resumed, it cannot make any assumptions regarding which data
the second flow touched and/or changed.
2. The library had quite a few cases of using &&-refs, avoiding even
move operations but also leaving ownership of the data with the
original producer (SyncJob). If the lifetime of that producer ends
too soon, those refs become dangling.
The fix makes two important things, respectively:
2. Ownership of room data is now transfered to the processing side,
the moment it is scheduled (see below), in the form of moving
into a lambda capture.
1. Instead of processEvents(), processing of room data is scheduled
via QMetaObject::invokeMethod(), uncoupling the moment when the
data was received in SyncJob from the moment they are processed
in Room::updateData() (and all the numerous signal-slots it calls).
Also: Room::baseStateLoaded now causes Connection::loadedRoomState, not
the other way round - this is more natural and doesn't need Connection
to keep firstTimeRooms map around.
|
|
|
|
To streamline adding of simple getters of content parts.
|
|
QPair is giving way to its STL counterpart, becoming its alias in Qt 6.
|
|
|
|
This macro was defined in accountdataevents.h but adding one more
parameter (base class) makes it applicable to pretty much any event
with the content that has one key-value pair (though state events
already have a non-macro solution in the form of
`StateEvent<EventContent::SingleKeyValue>`). Now CustomEvent definition
in quotest.cpp can be replaced with a single line.
|
|
Not that it was very important, as the two are basically the same thing
(and matrixTypeId() is about to be obsoleted); but formally basicJson()
is supposed to get the former, not the latter.
|
|
This makes it easier and more intuitive to build a minimal JSON payload
for a given event type. A common basicJson() call point is also
convenient in template contexts (see next commits).
|
|
EventContent::Base has been made primarily for the sake of dynamic
polymorphism needed within RoomMessageEvent content (arguably, it might
not be really needed even there, but that's a bigger matter for another
time). When that polymorphism is not needed, it's easier for reading
and maintenance to have toJson() member function (or even specialise
JsonConverter<> outside of the content structure) instead of deriving
from EC::Base and then still having fillJson() member function. This
commit removes EventContent::Base dependency where it's not beneficial.
|
|
Main changes:
1. Base::fillJson() gets a QJsonObject& instead of QJsonObject* - c'mon,
there's nothing inherently wrong with using an lvalue reference for a
read-write parameter.
2. UrlWithThumbnailContent merged into UrlBasedContent. The original
UrlBasedContent was only used to produce a single class,
AudioContent, and even that can logically have a thumbnail even if
the spec doesn't provision that. And there's no guarantee even for
visual content (ImageContent, e.g.) to have thumbnail data; the
fallback is already tested.
3. toInfoJson is converted from a template to a couple of overloads
that supersede fillInfoJson() member functions in FileInfo/ImageInfo.
These overloads are easier on the eye; and clang-tidy no more warns
about ImageInfo::fillInfoJson() shadowing FileInfo::fillInfoJson().
4. Now that UrlWithThumbnail is gone, PlayableContent can directly
derive from UrlBasedContent since both its specialisations use it.
5. Instead of FileInfo/ImageInfo, fillInfoJson() has been reinvented
within UrlBasedContent so that, in particular, PlayableContent
wouldn't need to extract 'info' subobject and then roll it back
inside the content JSON object.
|
|
|
|
With the reworked JsonConverter code it is possible to work uniformly
with structures that have a member toJson() and a constructor converting
from QJsonObject, as well as with structures that rely on an external
JsonConverter specialisation.
|
|
This is a rework of EventContent::SimpleContent previously defined in
simplestateevents.h. Quite a few events (and not only state events) have
just a single key-value pair in their content - this structure (which
is really just a template wrapper around the value) and the accompanying
JsonConverter<> specialisation encapsulate the concept to streamline
definition of such events. This commit only has simplestateevents.h
using it; further commits will use SingleKeyValue in other places.
toSnakeCase is a facility function that converts camelCase used for
C++ variables into snake_case used in JSON payloads. Combined with
the preprocessor trick that makes a string literal from an identifier,
this allows to reduce boilerplate code that repeats the same name for
fields in C++ event classes and fields in JSON. SingleKeyValue uses it,
and there are other cases for it coming.
|
|
|
|
|
|
|
|
Add a macro to make slicing clear in the code and quiet for static
analysis.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|