-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Delayed DBus answer #5
Comments
@rmescandon suggested to replace the last callback parameter (Tp::DBusError) by the dbus context. Pros:
Cons:
Still, this sounds good for me. Opinions? @gkiagia ? |
That was also one of my thoughts. The other thought I had was to use Tp::PendingOperation and wrap Tp::MethodInvocationContext inside it, somehow. In both cases, though, there is something that I don't like about the whole design... Historically, telepathy-qt's design originates in telepathy-glib's design, meaning that, telepathy-qt has always tried to copy the design of tp-glib (explains the refcounted objects for one ;). For inspiration, I had a look at how tp-glib implements the service-side BaseSomething classes. So, in tp-glib, the generated bindings are classes that resemble a lot our adaptees, mixing with the high-level bindings. Some sample (generated) API:
This is exactly the same as our "high-level" tricks with the callbacks. Think that Now looking at the higher level bindings, you will notice that not all the classes represent dbus objects directly. And vice-versa, there are interfaces that are nowhere to be found on the high level. glib-based CMs simply mix low-level and high-level bindings. Methods like the ones we are talking about in this ticket, are mostly implemented with the low level bindings. This brings into question the bindings that we are writing in tp-qt. In tp-qt we have a lot of duplication. Basically, the Adaptor API is reflected in the Adaptee, which is reflected on the high-level class, and we have so many high-level classes that you even started to generate them with a tool... sounds like something is wrong there. Bridging this with the original subject, I have no objection exposing the low-level API, but the point I am trying to make is that if we do that, then we may as well try to use it directly instead of wrapping it again and again. The problem, though, is that it is not so obvious how to mix those two with the current API (and it is actually a bit complex). So, I want to propose some changes around the service-side API in general:
This will eliminate the need for high-level Now all these are just my thoughts after spending the whole morning thinking about the problem... Since I have some spare time these days, I'll try to prototype it and we can see... In any case, I don't object to the original idea, but I'd like to try something better. |
Here is a first version of my idea: So far I have modified the generator to output this, so it's not hand-written. (I only removed the generated doc strings to make the gist more readable) Main points of this implementation: On the base class level:
On the generated level:
Comments? |
So, opinions? @Kaffeine ? |
I like the proposal and think that we should do it that way for 1.0. |
+1 |
+1 Em 8 de nov de 2016 12:53, "Niels Ole Salscheider" [email protected]
|
@gkiagia I'm sorry, I would like to read it carefully, but I have a very limited time (I'm changing the job and have to get done so many tasks for my former project). I like the idea, but I have one point, one question and a few nit-picks (may be I just misreading something):
Nit-picks (probably you posted a quick draft, so they makes no sense):
inline bool isRegistered() const
{ return dbusObject() ? dbusObject()->isRegistered() : false; } May be it would be better this way: bool isRegistered() const { return dbusObject() && dbusObject()->isRegistered(); }
Still, +1 :) |
Take your time in checking details, I was just unsure whether the whole design sounded good or not.
We don't need it, but I thought that maybe it can be useful for some people. I can remove them and see if we find any need for them in the future. We can always add those later.
Totally random, I just needed an interface that would showcase all bindings: at least one read-only property, at least one read-write property, at least one method and at least one signal. Most interfaces have all of those except the read-write property, and I remembered this one had the "URI" property because I had happened to look at its spec recently, so I picked it... I didn't even see what the high level class looks like.
A matter of style, I would say :) I usually like to put keywords, even though they can be inferred easily, since that makes the statement implicitly clear to the human eye about what it does. At least this was very much needed with virtuals in C++03, as there was no override keyword. Now I guess I can live without the redundant "virtual" keyword...
Of course :S /me feels stupid
Actually, Qt and KDE follow the convention that you say. TelepathyQt follows the opposite. The existing generated bindings use the same style that I have used there, I just chose not to change it. I prefer the Qt/KDE one, though. |
Main points of this implementation: On the base class level: * DBusObject is the main class exported on the bus. Unlike before, it now derives from Tp::Object, so it can be put in a SharedPtr etc... DBusService then inherits DBusObject and provides the additional service registration functionality. * AbstractDBusInterfaceAdaptee is the base class of all adaptees. This is a class that provides the mechanism that allows 'plugging' adaptees on the main DBusObject. There is no base class for the Adaptor anymore. On the generated level: * The Adaptor looks like before, api-wise, but is not exported * It relies purely on C++, there is no QMetaObject magic * The Adaptee creates the Adaptor internally when the object is about to be registered. The Adaptee is still fully usable when it is not registered * Adaptee properties act as cache variables for the values exported on the bus. They are always read/write, even if they are read-only on the bus, so that the implementation can set the values internally. * Writable properties have an additional signal on the Adaptee that notifies the implementation when a property was set from the bus. The property is set anyway, even if the implementation doesn't handle the new value * DBus API methods on the Adaptee can be implemented with a callback. They always return void and the return values are returned from the context (async API, yay!) * DBus API signals are implemented as emitFoo() slots on the Adaptee, which feels more natural than having Q_SIGNALS that are meant to be emitted instead of connected to. #5
struct TP_QT_NO_EXPORT DebugAdaptee::Private
{
+ Private() :
+ isEnabled(false)
+ {
+ }
+
QPointer<DebugAdaptor> adaptor;
bool isEnabled;
GetMessagesCallback getMessagesCb;
}; |
I have pushed a commit in my svc-refactoring branch to address the POD-member initialization. I have used C++11 non-static member initializers instead of a constructor, as it was easier (it's hard to do the commas between the member initializers when you are going through them in a for loop!) |
We need to be able to delay DBus answers, but it is not possible with current design.
Some methods need to make a network request before complete the call.
Examples:
Telepathy-Morse also needs to delay Connection.Interface.Requests CreateChannel() to get a native identifier of created group chat.
The text was updated successfully, but these errors were encountered: