I wonder if it is possible to call a method with QMetaObject::invokeMethod, if the method has optional parameters like this.
class Foo {
Q_INVOKABLE void myMethod(int a, bool b = true);
}
I have tried :
QMetaObject::invokeMethod(foo, "myMethod", Q_ARG(int, 42), Q_ARG(bool, true));
But the output tells me there are (of course) multiple candidates:
Candidates are:
myMethod(int,bool)
myMethod(int)
Is it possible to disambiguate invokeMethod so I am sure to call myMethod(int,bool) ?
EDIT: I found out that it was an issue with the namespaces for custom classes, instead of ìntandbool`. I wrote a quick and dirty solution.
class Foo {
Q_INVOKABLE void myMethod(bar::A a, blop::B b = blop::B::Default);
}
// When I need to call invokeMethod
auto success = QMetaObject::invokeMethod(foo, "myMethod", Q_ARG(A, A()),
Q_ARG(B, B()));
if(!success) {
QMetaObject::invokeMethod(foo, "myMethod", Q_ARG(bar::A, bar::A()),
Q_ARG(blop::B, blop::B()));
}
But this seems very very very dirty. Anyone got a good solution to handle this ussue?
There's no "good solution" yet. Always fully qualify the arguments to the signals/slots and to the matching string-based connect() and invokeMethod(). The long story is that the lookup is done by string comparison, so you need a perfect match.
Related
I am new to Qt and I want to try to understand it better.
I know from an inheritance perspective that a QMainWindow is derived from QObject. (Directly/Indirectly)
This allows for us to connect signals to slots in the following ways within the QMainWindow:
`
1- QObject::connect(sender, &QObject::signal, this, &MyObject::slot);
2- connect(sender, &QObject::signal, this, &MyObject::slot);
`
Even tough both ways are a possibility, I never understood what the major differences between them are.
Here are my questions:
1- Which method is more performant and why?
2- Why do programmers sometimes use one over the other?
I used both of these methods and they both seem to work similarly.
Consider following code.
class Foo {
static void fn();
};
class Bar: public Foo {
void bar() {
// 1
}
};
void main() {
// 2
}
If you want to call Foo::fn() at 1, you can just write fn(); since static functions is "visible" inside methods in derived classes, you can also write Foo::fn() and it will do exactly the same. If you want to call it at 2, you can only use full name Foo::fn().
Given the following code:
interface MyInterface {
fun foo() {
// body
}
fun bar() {
// body
}
}
class MyInterfaceImpl: MyInterface {
override fun bar() {
// body
}
}
I need to know at runtime that bar() has been overridden and foo() hasn't. How to do this using reflection?
Note: java.lang.reflect.Method#getDeclaringClass() always returns MyInterfaceImpl::class.java and java.lang.reflect.Method#isDefault() always returns false. I did not find the solution in KClass.
From what I know, where are two ways to achieve that dubious goal.
I'll demonstrate easy one, and discuss idea behind the harder one.
Easy one is based on simply calling toString() on the method:
val functions = MyInterfaceImpl::class.functions
val bar = (functions.toList()[0])
val foo = (functions.toList()[2])
println(bar.toString()) // fun MyInterfaceImpl.bar(): kotlin.Unit
println(foo.toString()) // fun MyInterface.foo(): kotlin.Unit
As you can see, you can figure if the method was overridden or not by parsing the string.
Harder solution would be to dig into KFunctionImpl, which has delegate member, which has dispatchReceiverParameter
That's a lot of nasty reflection, which is even more nasty, because most of those classes are internal and lazily initialized.
We can compare MyInterfaceImpl::class.declaredFunctions and MyInterface::class.declaredFunctions.
This property lists all functions declared in this class.
I have the following scenario (https://run.dlang.io/is/19OOW9):
import std.stdio;
void main(string[] args)
{
inter1 c1 = new foo();
foo c2 = new foo();
writeln("Origin=interface: ", typeof(c1).stringof);
writeln("Origin=class: ", typeof(c2).stringof);
}
interface inter1 {
}
class foo : inter1 {
}
I work with interfaces and have different implementations for them. Now I need to know which concrete implementation is currently being used. So in the example above, I would like to know from c1 that it is an instance of the class foo.
Is this possible in the language D?
I have already tried the possibilities of object (e.g. TypeInfo_Class) and std.traits. Unfortunately without success.
A workaround is, of course, to provide the interface with a suitable meta method (https://run.dlang.io/is/Xnt0TO):
import std.stdio;
void main(string[] args)
{
inter1 c1 = new foo();
foo c2 = new foo();
writeln("Origin=interface: ", c1.strategyName);
writeln("Origin=class: ", c2.strategyName);
}
interface inter1 {
#property string strategyName() const;
}
class foo : inter1 {
#property string strategyName() const {
return "foo";
}
}
However, this is cumbersome and unusual for D. I can well imagine that there is a better implementation of this.
Best regards
Thorsten
It is quite simple actually: first cast to Object, then fetch the typeid, after a null check:
Object o = cast(Object) your_object;
if(o is null) { /* i don't think this ever happens but you should check anyway */ }
writeln(typeid(o)); // will tell the class name
If you want to call a method on a specific class, you can just cast directly to your class, and again, null check it.
The intermediate cast to Object allows the typeid (aka classinfo) to succeed, whereas calling it directly on an interface always returns the typeid of the interface itself. This is because a D interface is defined to be very thin for maximum compatibility with other languages and doesn't automatically assume run time type information is actually present through it. But the cast to Object tells it you are assuming the RTTI is present, and then typeid will pull it.
Note that the typeid data doesn't provide a whole lot of information... it is mostly just what's needed for dynamic cast, comparison, and other features of the language runtime. But one convenience method it has is a class name and toString methods, which is why the writeln succeeds. But if you're looking for more detailed runtime reflection, you'll have to do it with a CT bridge function, or probably better yet, just write your own methods in the interface.
But if all you need is the class name, use that toString. It gives the fully-qualified name, including module name, so instead of foo, you will get like yourmodule.foo. You can just cut that off if you like by slicing at the dot.
I'm trying to generalize my hack from an answer to another question.
It should provide a way to reference a value which is not constructed yet inside its initializer (of course, not directly, but in lambdas and object expressions).
What I have at the moment:
class SelfReference<T>(val initializer: SelfReference<T>.() -> T) {
val self: T by lazy {
inner ?: throw IllegalStateException("Do not use `self` until initialized.")
}
private val inner = initializer()
}
fun <T> selfReference(initializer: SelfReference<T>.() -> T): T {
return SelfReference(initializer).self
}
It works, see this example:
class Holder(var x: Int = 0,
val action: () -> Unit)
val h: Holder = selfReference { Holder(0) { self.x++ } }
h.action()
h.action()
println(h.x) //2
But at this point the way in which initializer references the constructed value is self property.
And my question is: is there a way to rewrite SelfReference so that initializer is passed an argument (or a receiver) instead of using self property? This question can be reformulated to: is there a way to pass a lazily evaluated receiver/argument to a function or achieve this semantics some way?
What are the other ways to improve the code?
UPD: One possible way is to pass a function that returns self, thus it would be used as it() inside the initializer. Still looking for other ones.
The best I have managed to produce while still being completely generic is this:
class SelfReference<T>(val initializer: SelfReference<T>.() -> T) {
val self: T by lazy {
inner ?: throw IllegalStateException("Do not use `self` until initialized.")
}
private val inner = initializer()
operator fun invoke(): T = self
}
Adding the invoke operator lets you use it in the following way:
val h: Holder = selfReference { Holder(0) { this().x++ } }
This is the closest I got to make it look like something you would "normally" write.
Sadly I think it is not possible to get completely rid of a explicit access to the element. Since to do that you would need a lambda parameter of type T.() -> T but then you wouldn't be able to call that parameter without an instance of Tand being T a generic there is no clean and safe way to acquire this instance.
But maybe I'm wrong and this helps you think of a solution to the problem
is there a way to rewrite SelfReference so that initializer is passed an argument (or a receiver) instead of using self property? This question can be reformulated to: is there a way to pass a lazily evaluated receiver/argument to a function or achieve this semantics some way?
I'm not sure I completely understand your use case but this may be what you're looking for:
fun initHolder(x: Int = 0, holderAction: Holder.() -> Unit) : Holder {
var h: Holder? = null
h = Holder(x) { h!!.holderAction() }
return h
}
val h: Holder = initHolder(0) { x++ }
h.action()
h.action()
println(h.x) // 2
This works because holderAction is a lambda with a receiver (Holder.() -> Unit) giving the lambda access to the receiver's members.
This is a general solution since you may not be able to change the signature of the respective Holder constructor. It may be worth noting this solution does not require the class to be open, otherwise a similar approach could be done with a subclass using a secondary constructor.
I prefer this solution to creating a SelfReference class when there are only a few number of classes that need the change.
You may want to check for null instead of using !! in order to throw a helpful error. If Holder calls action in it's constructor or init block, you'll get a null pointer exception.
I'm pretty sure you can achieve the same results in a more readable and clear way using something like this:
fun <T> selfReferenced(initializer: () -> T) = initializer.invoke()
operator fun<T> T.getValue(any: Any?, property: KProperty<*>) = this
and later use
val valueName: ValueType by selfReferenced{
//here you can create and use the valueName object
}
Using as example your quoted question https://stackoverflow.com/a/35050722/2196460 you can do this:
val textToSpeech:TextToSpeech by selfReferenced {
TextToSpeech(
App.instance,
TextToSpeech.OnInitListener { status ->
if (status == TextToSpeech.SUCCESS) {
textToSpeech.setLanguage(Locale.UK)
}
})
}
Inside the selfReferenced block you can use the outer object with no restrictions. The only thing you should take care of, is declaring the type explicitly to avoid recursive type checking issues.
Let's say I have a class like so:
class Gerbil{
int id;
float x,y,z;
}
Let's further say this is part of a real-time simulation where I have a server/client setup and I change a property on the server-side:
//...
gerbil.x = 9.0;
//...
Now I want to send over this change to the client to synchronize the world state. However, the problem is I have potentially vast amounts of gerbils, and these gerbils also potentially have long lists of properties—not just x,y,z as depicted here.
My question is: Is there a way we can intercept these property assignments, transparently, and compile a diff from them?
From reading the D reference I got the impression opAssign might be the right thing, only there's actually no examples of how to use it? (D Ref. / opAssign) I suppose it would look something like this, but I'm just shooting from the hip:
void opAssign(string name)(float val){ //Just guessing here
if(name in floatProps){
if(isServer){
changedProps.push(this.id, name, val);
}
floatProps[name] = val;
}
}
And then opAssign would be called when we do:
gerbil.x = 9.0; //Same as gerbil.opAssign!("x")(9.0) ??
Apart from possibly wrong syntax, is this a step in the right direction? What is the right syntax? What about performance? It looks like it could be quite slow? Is there a faster, more "direct" way of this?
What I'd really like to avoid here are elaborate setups like:
gerbil.incProp(Prop.X, 9.0);
Thanks for your time.
Building on Jonathan's answer, I use code like this in a number of my libraries:
public template property(string name, T) {
mixin(`protected T _`~name~`;` ~
propertyGetter!(name, T) ~ propertySetter!(name, T));
}
public template property(string name, T, T def)
{
mixin(`protected T _`~name~` = `~def.stringof~`;` ~
propertyGetter!(name, T) ~ propertySetter!(name, T));
}
template propertyGetter(string name, T) {
enum propertyGetter = `public T `~name~`(){ return _`~name~`; }`;
}
template propertySetter(string name, T) {
enum propertySetter = `public typeof(this) `~name~`(T value){ _`~name~` = value;`~
`/* notify somebody that I've changed here */`~
`return this; }`;
}
The mixin strings are a bit ugly, but they preserve the proper line count.
I add properties to my classes like this:
class Gerbil {
mixin property!("id", int);
mixin property!("x", float);
mixin property!("y", float, 11.0); // give this one a default value
}
If you wanted, you could add some code to the propertySetter template that notified some sort of monitor that it had changed (passing id, property name, and new value). Then the monitor could transmit this info to a corresponding monitor on the server side who would find the object with proper id and set the specified property to the new value.
Overloading opAssign() is like overloading the assignment operator in C++. It's for assigning to the object itself, not one of its members. It's really not going to do what you want. I believe that the closest that you're going to get is properties:
class Gerbil
{
public:
#property int id()
{
return _id;
}
#property id(int newID)
{
//... Do whatever interception you want.
_id = newID;
}
#property float x()
{
return _x;
}
#property x(float newX)
{
//... Do whatever interception you want.
_x = newX;
}
#property float y()
{
return _y;
}
#property y(float newY)
{
//... Do whatever interception you want.
_y = newY;
}
#property float z()
{
return _z;
}
#property z(float newZ)
{
//... Do whatever interception zou want.
_z = newZ;
}
private:
int _id;
float _x, _y, _z;
}
#property enables property syntax so that you can use the function as if it were a variable. So,
//...
auto copyOfGerbilX = gerbil.x; //translates to gerbil.x()
gerbil.x = 9.0; //translates to gerbile.x(9.0)
//...
is now legal even though x is a function rather than a variable. You can insert whatever special handling code you want in the functions. And because the syntax used to access the variables is just as if they were public member variables, you can freely refactor your code to switch between having them be properties or public member variables in your class definition (assuming that you haven't tried to do something like take their address, since that doesn't mean the same thing for a variable as a function).
However, if what you're looking for is a generic way to not have to do all of those functions yourself, there is no direct construct for it. I believe that you could do it with compile-time reflection and string mixins or template mixins which would look at the list of your variables and then generate each of the property functions for you. However, then the extra handling code would have to be essentially the same for each function, and you'd have to be careful that the generated code was really what you wanted. I'm sure that it's feasible, but I'd have to work on the problem for a bit to produce a workable solution.
To generate such code, you'd need to look at __traits and std.traits for the compile-time reflection and at template mixins and string mixins for the code generation. I'd think twice about generating the code like that though rather than writing it by hand. It should be quite doable, but it won't necessarily be easy, debugging it could be entertaining, and if you're going to have to be fairly good with D templates and mixins to get it right.
But essentially, what you're looking for is to use #property functions so that you can add your handler code and then possibly use compile-time reflection along with mixins to generate the code for you, but generating code like that is a fairly advanced technique, so you may want to wait to try that until you're more experienced with D.