Age | Commit message (Collapse) | Author |
|
Move out current room state to its own class
|
|
Because Apple Clang choked on `explicit(false)`.
|
|
Default construction was only done to support stubbed state in Room
and even that did not really use those, opting to construct an event
from an empty QJsonObject instead. Now that Room doesn't have
stubbed state, default constructors are even less needed.
|
|
There are two important aspects here:
- Introducing Room::setState(evtType, stateKey, contentJson). These
components are ultimately what is getting sent to the homeserver,
so it makes sense to expose a respective `setState()` overload.
Unlike setState(event) the new overload can be Q_INVOKABLE.
- Room::setState() is no more const. Although it doesn't cause any
changes in Room class (and only transient changes in Room::Private),
it ultimately initiates a change in the room state, so calling it
const has always been a bit of hypocrisy. If you relied on that, you
most likely do something wrong (see the fix to User::rename()
in this very commit for a simple example of such wrongness).
Also: the backend is simplified by calling the original templated
Room::setState() instead of calling Room::Private::requestSetState()
that does exactly the same thing.
|
|
These are not required to build libQuotient, and omittable.cpp entirely
consisted of them.
|
|
This class is called to provide an arbitrary snapshot of a room state;
as the first step, Room::currentState() returns an instance of this
class that stores, well, the current state. Implelementation-wise it's
the same hash map of two-part state event keys to const event pointers;
however, RoomStateView provides additional operations:
- get(), that deprecates Room::getCurrentState(), returns a pointer to
a particular event if the current state has it. Unlike the original
method, the pointer returned from this one can be nullptr; this is
done to get rid of stubbed state events that have to be created
everytime a "state miss" occurred (i.e., when getCurrentState()
does not find an existing event in the current state).
- eventsOfType() - this is a new place for Room::stateEventsOfType()
introduced recently.
- query() - this is a way to specify a piece of the state content that
you need to retrieve by passing a member function or a function object
that retrieves it. That is especially convenient with member functions
of the event class; just pass the pointer to this member function,
and query() will parse the event type it has to retrieve out of it and
call that member function on the event object. Returns an Omittable<>;
if the respective piece of state doesn't exist, you'll get
`Quotient::none` (the same as `std::nullopt`).
- queryOr() - the same but with the fallback value; instead of an
Omittable<>, the fallback value will be returned if the needed event
is not found.
|
|
|
|
|
|
Improvements:
- Quotient::lift() - a way to invoke a function on an optional (including
Omittable) or a pointer if it's 'truthy'. Doesn't need enhanced
function_traits<>, only the standard library; works on any number
of arguments that can be dereferenced and casted to bool.
- then() - the version of lift() as a member function.
- edit() was renamed to ensure() (edit() might become a read-write
counterpart of then() at some point). It's not really used across
libQuotient codebase (or elsewhere) but is staying there just in case.
It can also accept an initializer, removing the requirement of
default-constructibility.
- Quotient::merge() is simplified, with one universal implementation
covering both Omittable/optional and plain values.
- All that now lives in its dedicated pair of files, further
decluttering util.h
|
|
It's too restrictive compared to switchOnType() overloads and doesn't
map to the case with a default value.
|
|
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.
|
|
|
|
|
|
Notably, Quotient::AccountRegistry::instance() is now deprecated
in favour of Quotient::Accounts inline variable.
|
|
- Templates and constexpr imply inline
- A function called from a single site better be inlined.
|
|
Although parented to Connection, SsoSession was pretty leaky in that
unsuccessful login attempts didn't delete the object and in some errors
didn't even close the local HTTP socket (though new connections would no
more be accepted). Also, without the documentation it wasn't clear who
owns the object returned by Connection::prepareForSso(). Now it is.
Unfortunately, it's not easy to cover SsoSession with tests. Basically,
it takes a homeserver and a mock "SSO agent" that would check
the SSO URL for validity and then both send the login authorisation
to the homeserver as well as ping the callback given by SsoSession.
Maybe for another time.
|
|
Use 'auto'; range-for instead of an iterator loop.
|
|
|
|
|
|
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'.
|
|
ImplPtr
|
|
|
|
|
|
The original (more complex and comprehensive) solution belongs to
https://oliora.github.io/2015/12/29/pimpl-and-rule-of-zero.html - this
commit only provides a small wrapper for non-copyable Private class
implementations common throughout libQuotient. Unlike the original,
default initialisation is made explicit - you have to pass
ZeroImpl<Private>() instead (and I firmly believe it's a good thing:
normally pointers to Private should not remain nullptr). The reason
ZeroImpl<> is not a template variable is quite simple: unique_ptr is
non-copyable and so cannot be initialised from; while a template
function will initialise the value in-place thanks to copy elision.
|
|
|
|
|
|
|
|
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.
|
|
Once visibility kicks in, MSVC changes its ways and tries to instantiate
Private classes wrapped in smart pointers upon their occurence in the
header file - which leads to build breakage because of a missing
destructor. Usually making the outer class destructor out-of-line helps
to fix this (see RoomEvent, for one example).
|
|
MSVC is quite picky to redeclaration with __declspec(dllexport), judging
it as changing the class of storage. This commit tries to reorder
declarations so that MSVC is made aware of dllexport attribute on the
first encounter rather than the second one.
|
|
Pinned message support
|
|
`Room::Change` has been changed to be an enum class recently; and it's values are no more suffixed with `Change`.
|
|
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.
|
|
Instead of using CMake's generate_export_header macro, it's a bit easier
to maintain a static file (that is not supposed to ever change) with
necessary export/import/hidden visibility macros.
|
|
Fixes a clang-tidy warning.
|
|
At some point macros were prepended with QTNT (pronounced "cute-n't",
"Quotient" with vowels dropped) but that didn't go very far. Having
forgotten about this, I introduced QUO prefix in a few places. Being
initial letters of "Quotient", QUO feels more understandable (and
coincidentally is a well-known Latin word); so let's unify on this.
|
|
Because that's what it really is.
|
|
|
|
This is a leftover from deferred `name` initialisation that wasn't
needed in the end.
|
|
Fixes a clang-tidy warning.
|
|
|
|
There's no need to return lambdas where pointers to specialised function
templates would work just fine.
|