Mate libGDX and Jetbrains MPS - java

I also posted this question on the LibGDX forums.
Hey there! For my thesis, I'm writing a DSL to describe the look of pictures. These pictures will be painted by libGDX according to the DSL-Input.
By now, jetbrains MPS (v. 3.0) and the newest libGDX-version is in use. My actual problem is: how to design the interconnection between my MPS-language and the java-libGDX-picture-generator.
Jetbrains MPS is not widely spread, but I'm sure, my problem can be solved without knowledge of it.
In the DSL, a generator is designed to build a class that can be executed (public static void main). Here goes several method calls to start picture-generation. Think of it as generatePicture(200px, 150px, "blue") (it's much more complicated, but I think that's not important for my problem).
In libGDX I have several launchers (especially the DesktopLauncher), these are the programms main classes, the ones that were started. At the moment, the launcher starts another class (I named it "Main") and here are the method calls.
The libGDX programm is inserted into MPS via jar artifact, so it's methods can be used in my DSL.
What would be a good solution to make my DSL-code start my libGDX-programm?
I have to make all these method calls and start the launcher. I thought about an additional class to initialize the launcher and make the calls, or trying to insert the calls from the DSL into the jar-classes.
Are there any comparable problems out there or someone who faced this very issue? I'm sure I will bring it to work somehow, but I'm interested in a nice and smooth solution.
Edit
The problem is that I'm somewhot sure I need the DesktopLauncher and its config to run the libGDX stuff inside my PictureGenerator.
Edit 2 - first approach
This is MPS related again. I thought about generating the Picture class with the MPS generator, but run the Launcher class.
Is this somehow possible? To run a class from the solution it need to implement IMainClass, but the Launcher couldn't. The launcher will always look the same. Is there a functionality to run another class than the generated one?
Or on libGDX-site: is it possible to merge launcher and Picture-class to insert the config?

Look at robot_Kaja sample (in MPSSamples.3.3\robot_Kaja). The Script concept implements IMainClass interface which makes it possible to run instances of this concept. You can right-click on any script in the jetbrains.mps.samples.Kaja.sandbox solution and you will see a Run option in the popup menu. Clicking on it will run the generated code for this script.
In your case, you probably also have some top-level concept similar to Script, which is generated into the Java (baseLanguage) Main class. Just make this concept implement IMainClass and it should become possible to run it directly from MPS.

Ok, I made it, following the idea of my second edit.
one file is generated in MPS
the generated file can be executed
a libgdx jar file is used
In MPS, I generate the following class with an inner class
public class DesktopLauncher {
public static void main(string[] args) {
LwjglApplicationConfiguration config = new LwgjlApplicationConfiguration();
new LwjglApplication(new Picture(), config);
}
public static class Picture extends ApplicationAdapter {
public Picture(){}
PictureGeneratorImpl generator;
public void create() {
generator = new PictureGeneratorImpl();
}
public void render() {
generator.generatePicture();
generator.exit();
}
public void dispose() {
generator.dispose();
}
}
}
As additional information: my libgdx jar contained the whole project (including core and desktop).
I hope this might help anyone who got the idea to combine MPS and libGDX.

Related

How and when to declare a Main Method

This may seem like a stupid queestion to most of you, but I have been learning Java using BlueJ, and BlueJ is created for learning, and as such Main Methods are not necessary given the BlueJ extensions provided by my University.
Therefore, now that I am playing around in both NetBeans and IntelliJ - I really want to get a good idea of when to declare a Main Method.
I know the Main method is the entry point of a package when it is compiled and run. But that is the extent of my knowledge.
If I am to build some apps in a full blown IDE, should I place all of my Class methods within a Main Method? Should the Main method be seperate from all others? Do I declare instance Variables within the Main Method?
Are there any good sites, or tutorial materials available that can help me structure my BlueJ Java knowledge into an IDE that requires a Main Method?
Thanks
Ok.
Main method is an entry point to your application.
If you watch any Java related tutorial, you'll probably see something like this.
public class HelloWorld {
public static void main(String[] args) {
// Prints "Hello, World" to the terminal window.
System.out.println("Hello, World");
}
}
This has been taken from Oracle's website.
When working with IntelliJ, you'll be presented with a package main on the top, or something else.
You see. Java unlike some other languages distinguish between namespaces using those packages. Think of them as a little packages full of Java classes that you can reuse.
For example, if you look at Log4J's repo => here, all these folders are essentially packages.
That way you can have many packages, and a single file that will trigger your main method, and start everything else.
That's how it's usually done.
But if you really want to learn Java from scratch. My suggestion is go to YouTube. Derek has done some marvelous job with his tutorials.
Best of luck.
While technically you can have more than one main method, for most use cases you only need one.
You should define it where it makes sense to do so in some "central" class responsible for bootstrapping your application and getting everything going.
The main method is static though so it can't access your class' instance. Typically this is how you'd get around this.
class TicTacToe {
public void theEntryPointToYourApplication() {
// ...
}
public static void main(String[] args) {
// This doesn't necessarily have to be the same class where you
// defined your main method
TicTacToe ticTacToe = new TicTacToe();
ticTacToe.theEntryPointToYourApplication();
}
}
This is just a small example though there are many ways and different approaches depending on your specific use case and needs.
Personally I have never used BlueJ.I've always been a netbeans fan.But the answer to your question is a general rule that most of the Object Oriented Programming Languages follow.You know that main method is the entry point of a package when it is compiled and run.Let me explain it in simple language.
Consider a soccer game.Assume that the field is the main method.The players are different functions.You are free to define any number of functions, but only 22 functions are called in the field.The whole game is controlled and played by these 22 functions only.So what do you learn from this?
We learn that java is only concerned with what is present in its main method just like the fans sitting in the stadium are only concerned with the 22 players who are currently playing.So if a programmer is writing a small program,normally the whole logic goes into the main method.But if its a large program,the program is distributed into various modules/functions and then these functions are called in the main method so that they get executed.

Why Is .headless Defaulted To True?

Question Setup
There are a few moving parts to this question, so I will try to do my best to replicate the issue in its simplest form.
I am attempting to add a TrayIcon to a SystemTray. This is typically a very simple objective on operating systems ("platforms") that support the call (this will play an integral part in a few moments).
I am programming for and on a Windows machine, presently (this is not a question about interoperability).
Here's the logic behind the code I've got that works:
public class SomeClass {
public static void main(String[] args) {
if(SystemTray.isSupported()) {
// DO SOMETHING TO ADD AN ICON
}
}
}
With all of its inclusions, this works. However, what I am really after, is the ability to inject the SystemTray instance with it's icon already "ready to go".
That code looks something a little more like this:
public class SomeClass extends NecessarySpringExtension {
private #Setter(onMethod=#_#Resource(name="SystemTrayControl"))) SystemTrayControl systemTrayControl;
// The above uses Lombok, as well.
public static void main(String[] args) {
// DO SOME RELATED STUFF like setting the configurations for
// for the application
}
}
The resource returns an instance (#Bean) of the SystemTrayControl class which, itself, makes a call to SystemTray; however, now, SystemTray is no longer supported (see some explanation in the The Question section, below).
Some Change Detail
Here's a snippet of some of that code (obviously, I've got my head submerged in the issue. Let me know if the context needs expanding. My belief is the following should be enough code to give you a sense of the structure):
SystemTrayControl Class:
#PostConstruct
public void showIcon() {
if (SystemTray.isSupported()) {
val tray = SystemTray.getSystemTray(); ....
Resource Class:
#Configuration
public class BeansForNeeds {
#Bean
public SystemTrayControl systemTrayControl() {
return new SystemTrayControl():
} ....
For the sake of more context: if I remove the condition seen in the SystemTrayControl class , I get a HeadlessException (which I've done a bit of reading on).
The Question
The issue stems from that fact that when utilizing a SpringApplicationBuilder in your program, the .headless property defaults to true. The javadoc states:
Sets if the application is headless and should not instantiate AWT.
Defaults to true to prevent java icons appearing
If I manually set the property to false, then the application runs well; however, I am always a bit "shaky" overwriting default behavior, particular if the language of "prevents" x, y, or z makes into the mix.
So, the question is:
Why is the property defaulted to true? What are the side effects of allowing the behavior prohibited by .headless? What's it got against AWT?
Once upon a time, pulling in the AWT classes (and native stuff) on a true headless box like Unix without X would cause runtime exceptions and other nasty OS level failures. And the errors would only happen once the classes were loaded, so it could be slightly non-deterministic.
This was with Java 6 or so, I recall.Things may have changed since then. And I suppose it is important that it was a problem only for the AIX Java, which is a clean-room Java that is not based on the Sun reference implementation. It wasn't strictly a bug, though, because the reference implementations just escaped the same problem by mistake when I looked at the code for each.
In my case, we had to be careful in some startup code to not accidentally use a handy utility class if it touched AWT, because then all of it would be pulled in, and fall over as it ran into missing native UI. This would never happen on Windows, where a lot of development took place. But once deployed on a true headless AIX box the app would fail hard with a runtime exception that bubbled right up to the user.
This is because we had "client" code (that was, ostensibly, headless and did not rely on the any UI code) and "UI" code (that knew how to interact with a command line or a full Swing GUI.) The client code was changed such that it pulled in some handy utility class (I forget which one) but this caused the VM to pull in some other classes, which pulled in AWT, which hit some native code expecting there to be a native UI of some sort.
Since the AIX box had no X, these native components were not there, and the whole thing fell apart with a translated native/runtime exception.
So, not only did we have to run the VM headless, we had to make sure our code did not accidentally reference any AWT code, either directly or indirectly.
I'd want to do more research to see how this scenario interacts with the property discussed here, but the key takeaway for me is that cross-platform means cross-platform! And "headless" can mean something very specific on different platforms.

How do I import and use a class that is in a specified path?

I am working on a program, which is supposed to have "Modules" which people can make their own code from an API, and they can then add one of their Modules, let's say it's called ModuleNicerText, they add it to the MyProgram\Modules folder as a .java class (the source), and the class implements Module.
The Module class has one method (well, it has more but for the sake of this post I'll say one), called onUpdate(), and I want to be able to somehow import that class to my code, and then run the .onUpdate() whenever I need to, I hope I explained it well enough, if I haven't then here is another example:
I have an interface, named Module
this is the body of Module:
public interface Module {
void onUpdate();
}
Now, I have my main class named MyProgram, and in that class I have this method:
public void onUpdate(){
for (Module module : modules){
module.onUpdate();
}
}
I use this kind of system, so I can easily add or remove components without having to mess with a bunch of stuff, if it is all crowded in one class/method.
Now, there is a directory that gets created when the program is run which is MyProgram\Modules and anyone who wants can add a .java file which extends the Module interface there.
I want to be able to look through the .java files in that directory and be able to call the .onUpdate() method for them, so that my users can have as much customization as they possibly can!
Any help at all is very much appreciated, and I thank you in advance for taking your time to read this enormous wall of text :)
There is a good article (a little old, but great explanation).
It provides detailed information about how to use the Proxy Pattern through UpToDate file check.
By the time you keep the same methods inside your interface, and change only implementation of it, you can make use of this technique only in classes which implements the interface.
Check it out: Dynamic Java code to your Application
You can use Java Simple Plugin Framework. It does something similiar to what you want and is ready to use.

Eclipse export as runnable JAR

I know SO dislikes this type of questions but after googling and checking SO for close to an hour I am no closer to a solution. I have a package with some classes which together form a GUI based game which runs fine when I do CTRL-F11 but when I right-click the package->Export->Runnable JAR it is nowhere to be found in the Launch Configuration dropdown, while other packages/projects are.
I would like to be able to run this game outside of Eclipse even if I don't need to now. I have no main methods, my runnable uses acm. public class SokobanGFX extends GraphicsProgram.
Found this in Javadoc:
http://jtf.acm.org/javadoc/student/acm/program/Program.html
"In many programming environments, objects that are specific instances of a Program
subclass will run automatically without any special action on your part. For maximum
portability, you might want to define a static main method as described in the comment
for the standard implementation of main."
Should be easy to make an executable jar after that.
I'm not familiar with ACM, but based on my observations with the Javadoc, I believe:
public static void main(String[] args){
new SokobanGFX().start()
}
//http://jtf.acm.org/javadoc/student/acm/program/Program.html#main(String[])
Should launch the program.

C++ .NET equivalent to java public static void main()?

In java I can simply test classes directly with
public static void main()
I then just add quick code and under Eclipse "Run" the class. Is there anything similar in C++ .NET ?
Right now I have to create an empty project, reference the correct headers then set that project as start up project.
Unit tests. There's also the object test bench if you're using VS.
I do this in C# so I don't know if this will react any differently, but I set up an empty "test" class with the main method and then set the project to startup with that class file. You shouldn't have to create the file in a separate project.
I'm not terribly familiar with Eclipse but if you're just looking to run your objects in the IDE do the following.
Open up the Immediate window and just call whatever function you want. This will start execute the code you type. You will likely have to qualify the name. Ex: ClassLibrary1.MyClass.SomeMethod()
I like using TestDriven.NET for this. It allows you to execute any public method by rightclicking on the header and selecting "Run test".
I like making
public static void Test()
methods on dialog- and form-classes to use with this feature.
It supports C++/CLI, so if that is what you mean by C++.NET, it should work for you.
Edit: You should only do that for things that are not automatically testable - such as pure GUI classes. Otherwise I agree with the other commenters: use a unit test framework.

Categories

Resources