Open plata opened 6 years ago
I can't really follow your idea. Could you give a rough example how it could look like?
About my last suggestion:
We would create an Engine
instance in JS, the same way we do now, e.g. via an include
followed by new Wine()
.
The interesting point of my suggestion is, how the Java side handles a passed Wine
instance object, i.e. the result of new Wine()
.
In a perfect world we would case the passed Wine
object into an Engine
interface and then access it, but because the Wine
class/prototype doesn't directly implement the Engine
interface we need another way to convert it into an Engine
instance.
This conversion is done via the EngineWrapper
class.
After passing the resulting object from new Wine()
to a Java method, the object will be of type ScriptObjectMirror
, and can therefore be passed to the EngineWrapper
constructor.
Ideally the EngineWrapper
constructor should also do a check, that ensures, that all required methods by the Engine
interface are contained in the given ScriptObjectMirror
object.
There's two things I don't like about this:
Wine
shall "implement" the Engine
interface.1) Yes, you're right about that, but I think this is a more common problem with Javascript/Nashorn.
If Nashorn would support the new ES6 class definitions and if its inheritance schema would work when inheriting from Java classes, we wouldn't face this problem. 2) You're right again, but I don't think we can use the same approach for the engines and for the installers/tools.
The reason for this is, that installers/tools don't require additional methods to the run method. In comparison, engines do need additional engine specific methods.
Again, in my eyes this is a problem located in the way inheritance and class definitions are done in Nashorn.
It's true that the issues are caused by the way Nashorn does the inheritance. Nevertheless I believe that we could solve both problems I've described above by using composition over inheritance.
However, I would like to understand @qparis suggestion first. Maybe his idea solves the issues altogether.
Another idea:
var engineImplementation = { ... }
var WineEngine = Java.extend(org.phoenicis.engines.EngineTool, toolImplementation);
Wine.prototype = Object.create(WineEngine);
Wine.prototype.foo = function () { ... }
If WineEngine
is a Javascript object, this should work (I guess).
Are you sure the line:
Wine.prototype = Object.create(WineEngine);
works?
This is the first time, I've heard you can do this with Nashorn and a Java class (i.e. WineEngine
).
I'm not sure. Will have to try. I just thought that WineEngine
should be a Javascript object but maybe it's not.
Doesn't work. You get a type error ("is not an Object").
I'm not sure about what changes we've agreed on after all the new ideas we had.
Should I still change the applications and tools to an implementation looking like this:
include(["engines", "wine", "quick_script", "online_installer_script"]);
{
run: function () {
new OnlineInstallerScript()
.name("7-zip")
.editor("Igor Pavlov")
.applicationHomepage("http://www.7-zip.org/")
.author("ImperatorS79")
.url("https://www.7-zip.org/a/7z1801.exe")
.checksum("d56bca4973b1d1aa5915c41dce318b077ce8b5b2")
.category("Accessories")
.executable("7zFM.exe")
.go();
}
};
Yes, I think you can do that in any case (don't forget to update the documentation like we've discussed above).
Is it clear that the script exposes the anonymous object or should we write a return
somewhere (if that works)?
Currently, the class name is computed in a pretty hacky way in
WinePrefixContainerWineToolsTab#populate
. It works as long as the ID is the snake case form of the class name. There must be a better solution for this.Some possible solutions:
specified variable
CLASS_NAME = "RebootWine"
)JSON
script.json
script.js
can contain multiple classes.no class