Rachael wrote:Let's not get ahead of ourselves, here. Those VM's are general purpose VM's that have no business being inside of a game like GZDoom. Not to mention the invitation of a MASSIVE amount of code bloat. Java? JavaScript? Any sane programmer is going to balk at this and for good reason. My answer to that is NO, and HELL... NO!
Seems to me that execution speed is of greater concern at run time than code size.
Easy for me to say, though. I'm not the one who has to pay for hosting it.
Also as one of the distributors for GZDoom, both for its dev builds and releases, I am vehemently against this idea because of the inevitable bloat in archive size these VM's will bring. To put it simply, even LLVM wasn't that bad!
Fair enough. There's no easy way around that problem.
Java 9 has a new way to make a stripped-down, application-specific JRE image, but the bare-bones image (just the java.base module, probably enough for game scripting) is still 7 MB (Win64) compressed (7z with “ultra” compression). Pretty impressive for Java, but it'd still double the size of a GZDoom binary distribution archive (3.2.0 x64 compresses down to 7.55 MB with 7z ultra).
On that note, if you're facing a bandwidth squeeze, why not distribute GZDoom in 7z format? The zip archive is 9.08 MB, so you'd save 1.53 MB per Windows x64 download.
If you have copious amounts of free time, as you said, why not honor the original request and play with Lemon?
I don't know what that is.
Graf Zahl wrote:Just one word: No! Or: NO!!! Java has one of the worst interfaces to native code ever cooked up
Huh? JNI? I admit it's been a long time since I integrated a C program (X-Chat, an IRC client) with JNI, but I don't remember it being
that bad…
Javascript as a language is just too volatile. The driving objective behind it was "Anything goes, type what you want and I'll try to make sense of it." which will result in endless hidden bugs that can never be found by analyzing the code.
On that, I definitely agree. Dealing with JavaScript is unfortunately an occasional part of my job, and one of my least favorite, because of its chaotic, unpredictable nature.
The issue with general purpose VMs normally is that the script-declared classes implicitly inherit from some internal class the using app has no access to. This cannot work for declaring actors in scripts - for that the script classes must fulfill two requirements:
1. Inheriting from a native class must be possible and the result must be seamless to both native and scripting code.
2. You must be able to override native virtual functions from scripts.
No third-party scripting solution can do that.
SWIG can do that. At least, the website claims that it can.
You can do it by hand, too. For each C++ class that needs to be inherited from and overridable in the VM, make a stub C++ class that overrides
all of the superclass virtual methods, to call into the VM:
Code: Select all
class Actor … {
public:
virtual void SomeMethod();
}
void Actor::SomeMethod() {
// do stuff
}
class ScriptedActor : AActor {
<VM object reference> _vm_obj;
void _super_SomeMethod();
public:
virtual void SomeMethod() override;
}
void ScriptedActor::_super_SomeMethod() {
Super::SomeMethod();
}
void ScriptedActor::SomeMethod() {
// call into VM
}
Or, if VM objects are statically typed (like in Java), you could examine each VM subclass of a scripted class, determine which ones are overridden, store the list of overridden methods in a C++ variable somewhere, and adapt IFVIRTUAL to consult that list.
Let's be clear: You should never design a GUI like that. It'd be better to set everything and then call a 'layout' function because otherwise you will end up recalculating the layout multiple times per frame and that will kill your frame rate no matter what if you do it more frequently.
Of course. I have a GUIWidget::RequestLayout method that marks a widget and its ancestors as needing layout, causing the tree's layout to be recomputed next time it's drawn. I'm avoiding doing layout even
once per frame, let alone more than once.
Trouble is, that needs to happen whenever one or more layout-relevant fields are changed, and it'd be much safer to just call it from setters than to rely on application code to separately call RequestLayout afterward.