-
Notifications
You must be signed in to change notification settings - Fork 586
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
First attempt at Java side automatic downcast feature #548
base: master
Are you sure you want to change the base?
Conversation
We shouldn't need to modify the Parser in any way for this. Could you explain what doesn't work when we directly annotate a Java method in a base class somewhere? |
Well I did not consider that we should not modify the Parser. I did try several places/ways to do this and this was the first one that worked. Since AFAIU parser is responsible producing the Java code (JNI native side) that corresponds to the C++ code I felt and found that this is the easiest place to do this. There are three things that need to happen:
|
In my opinion, it's a lot simpler to just call your method from JNI, somewhere around Pointer.init()... |
Sorry, I'm not following you. Can you elaborate a bit? |
Well, basically what you did in pull #542, but have the Generator "write" that JNI code instead of forcing the user to do it manually. Even if we're using some JNI to call Java methods, which is a bit slow, it can still be pretty fast when caching everything, and possibly merging the logic with Pointer.init(). As long as the user doesn't have to touch JNI, we can optimize things in the background with JavaCPP if/when anyone cares, but still have an JNI-less user experience, also leaving the window open to use tech like Panama Foreign in the future. |
Thanks. I see what you mean, I think. So the 'API' for the auto downcast feature would be something like : package org.bytedeco.javacpp.annotation;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.PARAMETER })
public @interface Downcaster {
String typenamefun() default "";
} @Properties(value = @Platform(compiler = "cpp11",
include = { //
"fun_to_get_type_name.hxx", //
...
infoMap.put(new Info("opencascade::handle").skip().annotations("@Downcaster(typenamefun=\"fun_to_get_type_name\")", "@MySmartPtr")); Hmm, I kind of like the economy of expression in this solution. There is one thing that needs to be solved, ie in a multi toolkit situation the Java classes to be dynamically instantiated are spread across number of target classes and thus the name alone is enough to instantiate the class. I guess we can generate code to populate at runtime a global cache of classes or constructors, indexed by class name. |
Well, we don't need to know their names. We just need to be able to associate any given C++ object with a Java class, which is something we can do with, as I mentioned previously, |
Hi,
this is my first sketch for a Java side automatic downcast feature.
To use it do as follow:
The base type of the class hierarchy is annotated with
@Downcast
and the name of the downcast function in the target class.For example:
And the downcast function is injected into the target as follows:
Since in the case of multi toolkit library it usefull to inject some code to all toolkits (for example to register the downcastable classe) I also added:
How it works:
Any function (say foo) that returns a type that is tagged with
@Downcast
is renamed and tagged with '_ _' (for examplefoo_ _
). In addition a new pure Java function with the original name and same signature is created . This new function calls the renamed function and passes the returned value to the downcast function and returns the value returned from the downcast function. The renamed function is also annotated with@Renamed
For example: