Idea: How about introducing a JmeProperty annotation in the engine

The annotation could then be used by for example the JmeCustomControl and the SceneExplorerProperty class to lookup property editors for otherwise unsupported property types?

For example:

public class CustomControl extends AbstractControl {

@JmeProperty(valueTypeImpl= “java.util.HashMap”, editor = “org.example.MapPropertyEditor”, keyEditor = “…”, valueEditor = “…”)
private Map<String, CustomType> mapProperty;

public void setMapProperty(…) {…}
public Map<String, CustomType> getMapProperty(…) {…}

[…]
}

I admit that the mapProperty is a rather weak example, but I think that you understand on where I am heading.

To stay with the map example, and considering the additional, optional annotation properties such as keyEditor and valueEditor, arbitrary maps could be defined where individual entries could be edited using for example selection dialogs where the user selects individual nodes from the currently edited scene, that then would be assigned as a value for a specific key and so on. Or keys could be defined that are not just simple “primitive” type wrappers such as Integer or Boolean, but which hold additional information which then could be edited directly from within the scene composer.

And this could also be used for custom Savables assigned as user data to a spatial.

The JmeProperty annotation would have only minimal impact during runtime but would enhance the SDK alot by having the ability to specify custom property editors and other stuff that then would be evaluated by the SDK.

Of course, the loosely referenced property editors would still have to be made available as a netbeans plugin, as otherwise there would be no property editor.

If the SDK is using the Java Beans API properly (not sure it is) then you can do this with standard Java beans mechanisms.

http://docs.oracle.com/javase/6/docs/api/java/beans/BeanInfo.html

If the SDK isn’t using proper bean introspection to find properties (but still uses the beans API) then that’s the real issue.

1 Like

Good point. I guess that the SDK is using the bean API for convenience only, i.e. to not having to reinvent the wheel on finding out which setters and getters are available.

Hm, in SceneExplorerProperty it does

    for (SceneExplorerPropertyEditor di : Lookup.getDefault().lookupAll(SceneExplorerPropertyEditor.class)) {
        di.setEditor(valueType, this);
    }

using some kind of “plugin” mechanism where individual property editors will set themselves as the actual editor, however, this might fail under certain circumstances, for example if there are multiple different editors which respond to the same valueType but which might differ in their overall functionality. Consequently, there is no actual control on which property editor to use.

Looking at the BeanInfo interface gives me the chills :smiley:

What about a simple and low overhead annotation interface like this (still referring to the map/list example)

public @interface JmeProperty {

// hint on the actual implementation of the value type in case that one declares it using an abstract base
String implType() default “”;

// editor used for the value type impl
String implEditorType() default “”;

// hint which impl class to use for the key in case one uses an abstract base class or an interface as the key
String keyImplType() default “”;

// editor used for the key in list/map
String keyEditorType() default “”;

// editor used for the value in list/set/map/array
String valueEditorType() default “”;

// hint which impl class to use for the value in case one uses an abstract base class or an interface as the value
String valueImplType() default “”;

}

One would not need to have to implement all of the BeanInfo interface with lots of unrequired stuff…
Much simpler for both the user and the SDK plugin developer…

To make it even more complicated, one could allow multiple valueImplTypes and a valueEditorFactory and so on,
to make it even more versatile.

And, if you have a look at http://axnsoftware.github.io/commons-settings, it shows that this can be realized rather
easily for arbitrary types. And yes, I know, there is a “lot” of code that still requires some work, but it does the trick
and it would allow the JME team to replace the java.beans dependency altogether.

Of course, the code that would “parse” the existing savables/controls would have to be different from what is
found in the above presented project, eventually utilizing the netbeans framework, but I think that this would be
the way to go for.

E.g.

public class SomeControl extends AbstractControl {

@JmeProperty(...)
private SomeCustomSavable foo;

[...]

}

public class SomeCustomSavable {

@JmeProperty(...)
private SomeOtherCustomSavable bar;

[...]

}

and so on.

The respective property editors would then be somewhat generic in order to support custom properties.

Actually we would have code in the engine that is only useful for the SDK and that’s something we want to avoid absolutely.
A lot of people are using JME without the SDK. Also this kind of annotation would be useless for a game. Not that it would bring some overhead, but we don’t want to mix SDK code and engine code.
We are using reflection a lot in the SDK and it’s kind of ok.

The only “code” in the engine would be the annotation and fields that would be annotated by that annotation. The rest would be part of the SDK.
Consider it for being a small overhead hint that is placed in the runtime classes that can be evaluated by the SDK to provide a much richer and more adaptive environment.
And I can not think of any alternative to it, other than what is currently present in the ScenePropertyEditor class which simply iterates over all property editors available and
the last one responsible for a type winning the bet.

@axnsoftware said: The only "code" in the engine would be the annotation and fields that would be annotated by that annotation. The rest would be part of the SDK.

I have ZERO say into this, but I think the engine’s code is, at times, hard enough to get fully, thus I don’t think there’s a necessity to add this. I totally agree with Nehon’s assessment: only pure engine code should be found in the engine, nothing else.

My 2c.

Again, this will be a convenience for game authors that could use a simple annotation to provide the SDK’s scene composer with hints as to which property editors it should be using instead of making random guesses.

This would help both the game developer, the one responsible for developing the tools on top of the SDK, and the designer responsible for designing the scene, as it would make overall work so much more comfortable.

But Java Beans ALREADY provides a way to do exactly this. Why reinvent that wheel that’s been around since 1997 or so? Creating a bean info class for your code is not tough. I just don’t know if the SDK is properly using it (a bug if it’s not in my opinion).

I’m kind of against creating one-off SDK-specific annotations that if they are at all useful over what Java already provides would already exist in some standard form out in the wild. When even “dependency injection” annotations have been standardized by this point, surely bean property annotations would have been.

Besides, they are only useful in the outlier cases where standard naming conventions don’t work… and since these are your own classes it should be possible to massage them if you want them to work. You will have to create setters and getters in any case. Going directly to the fields is a no-no here.

@axnsoftware said: The only "code" in the engine would be the annotation and fields that would be annotated by that annotation. The rest would be part of the SDK. Consider it for being a small overhead hint that is placed in the runtime classes that can be evaluated by the SDK to provide a much richer and more adaptive environment. And I can not think of any alternative to it, other than what is currently present in the ScenePropertyEditor class which simply iterates over all property editors available and the last one responsible for a type winning the bet.
I understand your point and to be clear, at some point I went this way for filters. I added annotations to be able to add some kind of meta data to filter properties (like min val max val, what kind of control you want to edit it in the SDK). The problem is that it's a bottomless pit, once you started it, you add things here and there and before you know it you have 5 annotations for each properties and that much interfaces to define them. All that in the engine code, and that clutters the code for no purpose in the engine itself, making it difficult to read. I rolled back the change after a long discussion in the core team chat where we all agreed in the end that it was not the way to go.

If you want properties meta data use and additional description file, xml or whatever. I know that it sounds a lot less sexy than annotations, but we want to keep the engine code as clean as possible and completely abstracted from the SDK.

1 Like
@axnsoftware said: Again, this will be a convenience for game authors that could use a simple annotation to provide the SDK's scene composer with hints as to which property editors it should be using instead of making random guesses.

They are not “random guesses”. They are based on well established conventions for almost 20 years now.

@nehon said: I understand your point and to be clear, at some point I went this way for filters. I added annotations to be able to add some kind of meta data to filter properties (like min val max val, what kind of control you want to edit it in the SDK). The problem is that it's a bottomless pit, once you started it, you add things here and there and before you know it you have 5 annotations for each properties and that much interfaces to define them. All that in the engine code, and that clutters the code for no purpose in the engine itself, making it difficult to read. I rolled back the change after a long discussion in the core team chat where we all agreed in the end that it was not the way to go.

If you want properties meta data use and additional description file, xml or whatever. I know that it sounds a lot less sexy than annotations, but we want to keep the engine code as clean as possible and completely abstracted from the SDK.

Put much more eloquently than I did. :slight_smile:

@pspeed: as I said, hinting on java.beans is a good point, but the interface does provide a lot more than what is actually required and it fails to provide the information that is actually required, namely loosely coupled hints on which classes should be used when creating the property sheet.

Of course, we could always also extend the Savable interface by a getBeanInfo() method, which would then return a class that is based on some AbstractBeanInfo base class that would then leverage the overall implementation overhead for the engine user.

And I guess, that the Savable or some other, additionally introduced interface, would suffice to provide such information.

However, if you would care to have a closer look on the PropertyDescriptor class and its getPropertyEditor method, then you will notice that we would be introducing dependencies towards the SDK, which is definetely something that the JME team would want.

As such, the loosely coupled annotation seems to be the only reasonly way to go for.

Unless we would revamp the SceneExplorerProperty class so that it would not just search for all available property editors but rather for bean info instances that would provide the required information.

If that is what you are actually aiming for, then you gave me a very hard time in finding out myself.

@nehon said: I understand your point and to be clear, at some point I went this way for filters. I added annotations to be able to add some kind of meta data to filter properties (like min val max val, what kind of control you want to edit it in the SDK). The problem is that it's a bottomless pit, once you started it, you add things here and there and before you know it you have 5 annotations for each properties and that much interfaces to define them. All that in the engine code, and that clutters the code for no purpose in the engine itself, making it difficult to read. I rolled back the change after a long discussion in the core team chat where we all agreed in the end that it was not the way to go.

If you want properties meta data use and additional description file, xml or whatever. I know that it sounds a lot less sexy than annotations, but we want to keep the engine code as clean as possible and completely abstracted from the SDK.

This I take as a reasonable argument against the annotation based approach and engine based evaluation of these annotations.
However, what I meant was merely a hint for the SDK. Nevertheless, the BeanInfo approach, when being moved into the SDK plugin itself, seems to be a reasonable solution.
I will take a look into it and provide you with a patch, which might be quite extensive.

Do you have a sandbox where I can contribute code to the SDK for you to review?

@axnsoftware said: @pspeed: as I said, hinting on java.beans is a good point, but the interface does provide a lot more than what is actually required and it fails to provide the information that is actually required, namely loosely coupled hints on which classes should be used when creating the property sheet.

Of course, we could always also extend the Savable interface by a getBeanInfo() method, which would then return a class that is based on some AbstractBeanInfo base class that would then leverage the overall implementation overhead for the engine user.

And I guess, that the Savable or some other, additionally introduced interface, would suffice to provide such information.

However, if you would care to have a closer look on the PropertyDescriptor class and its getPropertyEditor method, then you will notice that we would be introducing dependencies towards the SDK, which is definetely something that the JME team would want.

As such, the loosely coupled annotation seems to be the only reasonly way to go for.

Unless we would revamp the SceneExplorerProperty class so that it would not just search for all available property editors but rather for bean info instances that would provide the required information.

If that is what you are actually aiming for, then you gave me a very hard time in finding out myself.

Look. It’s clear that you mean well and I appreciate that. But the Java Beans API has been around a long time and is well documented 100 times over. I’m not sure how much to regurgitate just to prove a point. Sometimes the person making a proposal should take some time to do the research completely and not just glancing through some classes.

My original point in more detail:

If the SDK is using bean properties and PropertyDescriptors and is not using:
BeanInfo info = Introspector.getBeanInfo( beanClass );
PropertyDescriptor props = info.getPropertyDescriptors();
…to find them then that’s probably an issue. As stated in my first response:

@pspeed said: If the SDK isn't using proper bean introspection to find properties (but still uses the beans API) then that's the real issue.

Maybe there is a good reason to bypass the nice stuff the beans API provides but I don’t see it. I’ve never really looked into the SDK code, though. I just have a TON of experience with Java Beans and related frameworks. My very first self-managed open source project was in fact based on exactly that (published circa 2002 or so). (http://meta-jb.sourceforge.net/)

You can post patches in the issue tracker, but don’t hesitate to drop a message here because we’re not checking the issue tracker everyday.
We will eventually change to git hub at some point and you’ll be able to make pull requests and I hope this will ease the patch contribution process.

@nehon said: You can post patches in the issue tracker, but don't hesitate to drop a message here because we're not checking the issue tracker everyday. We will eventually change to git hub at some point and you'll be able to make pull requests and I hope this will ease the patch contribution process.

This would be great! Please make that happen in the near future, say a week or so :smiley:

And note: for most classes, 99% of the time the naming convention will work without any other add-ons necessary. Just follow the right conventions and things will work.

@pspeed said: Look. It's clear that you mean well and I appreciate that. But the Java Beans API has been around a long time and is well documented 100 times over. I'm not sure how much to regurgitate just to prove a point. Sometimes the person making a proposal should take some time to do the research completely and not just glancing through some classes.

Of course I do, I am not here to cause any trouble. You! You lookin’ at me? :smiley:

As for the BeanInfo stuff, and as I proposed in one of the previous posts, I see now at where you are headed.

And we are here for disputing and discussion issues and giving input to each other. And I admit that I did not see your point as I was fixated on getting the information into the SDK as cleanly as possible without introducing any dependencies towards the SDK in the runtime. And at that time, the annotation based solution seemed the most elegant way to go for.
Pardon my negligence regarding the BeanInfo API.

My original point in more detail:

If the SDK is using bean properties and PropertyDescriptors and is not using:
BeanInfo info = Introspector.getBeanInfo( beanClass );
PropertyDescriptor props = info.getPropertyDescriptors();
…to find them then that’s probably an issue. As stated in my first response:

And, if you would have provided me with this or something similar, perhaps in more words, then I would have understood your intention right away.

Regardless, I will have a look into it and see what I can do so that the SceneExplorerProperty becomes more versatile and allows plugin authors way more than what is currently possible.

To extend upon your BeanInfo proposal and what I have learned from the sources, I presume that

SDK Plugin Developers should be required to provide a FooBeanInfo class, whenever they want support for their Foo custom savable or control, which is also a savable.

The FooBeanInfo class would then provide the system with the required information, namely the property editors and so on.

And, yes, this will even allow for nested savables and thus recursive resolution of property editors.

@axnsoftware said: To extend upon your BeanInfo proposal and what I have learned from the sources, I presume that

SDK Plugin Developers should be required to provide a FooBeanInfo class, whenever they want support for their Foo custom savable or control, which is also a savable.

The FooBeanInfo class would then provide the system with the required information, namely the property editors and so on.

And, yes, this will even allow for nested savables and thus recursive resolution of property editors.

First, Savable is something else and has to do with serialization. Serialization has to avoid any java.beans.* dependencies, I think. My recollection is that android has no java.beans.* at all… I could be wrong.

Second, the FooBeanInfo class would only be required in the (extremely) rare case where a developer must somehow name his methods in a way that automatic detection wouldn’t work. Really, BeanInfo’s primary function is to help ‘beanify’ classes that you have no control over. For your own code, it’s almost always better to just follow convention… not just for introspection but also because that’s the accepted convention and anyone reading your code will understand instantly what is going on.

So, yes, BeanInfo support I think is a good idea but this is to handle some fairly rare use cases.