LibGDX - why isn't their a create() method on "implements screen"? - libgdx

When I had the application listener their was a create method but now their isn't. And I need the create() method to continue with my app. Currently, I have a main menu screen and I need a stage and such to get button and other things to appear but I need the create() method. Can someone explain this to me please?

ApplicationListener needs a create() method because at construction time resources like OpenGL might not be initialised, create() is called once Libgdx is actually initialised.
Typically you would create your Screen objects from ApplicationListener.create() so you can simply use their constructors to initialise whatever you need.
There is no need for a create() method in Screen.

Related

JavaFX FXML Parameter passing from Controller A to B and back

I want to create a controller based JavaFX GUI consisting of multiple controllers.
The task I can't accomplish is to pass parameters from one Scene to another AND back.
Or in other words:
The MainController loads SubController's fxml, passes an object to SubController, switches the scene. There shall not be two open windows.
After it's work is done, the SubController shall then switch the scene back to the MainController and pass some object back.
This is where I fail.
This question is very similar to this one but still unanswered. Passing Parameters JavaFX FXML
It was also mentioned in the comments:
"This work when you pass parameter from first controller to second but how to pass parameter from second to first controller,i mean after first.fxml was loaded.
– Xlint Xms Sep 18 '17 at 23:15"
I used the first approach in the top answer of that thread.
Does anyone have a clue how to achieve this without external libs?
There are numerous ways to do this.
Here is one solution, which passes a Consumer to another controller. The other controller can invoke the consumer to accept the result once it has completed its work. The sample is based on the example code from an answer to the question that you linked.
public Stage showCustomerDialog(Customer customer) {
FXMLLoader loader = new FXMLLoader(
getClass().getResource(
"customerDialog.fxml"
)
);
Stage stage = new Stage(StageStyle.DECORATED);
stage.setScene(
new Scene(
(Pane) loader.load()
)
);
Consumer<CustomerInteractionResult> onComplete = result -> {
// update main screen based upon result.
};
CustomerDialogController controller =
loader.<CustomerDialogController>getController();
controller.initData(customer, onComplete);
stage.show();
return stage;
}
...
class CustomerDialogController() {
#FXML private Label customerName;
private Consumer<CustomerInteractionResult> onComplete
void initialize() {}
void initData(Customer customer, Consumer<CustomerInteractionResult> onComplete) {
customerName.setText(customer.getName());
this.onComplete = onComplete;
}
#FXML
void onSomeInteractionLikeCloseDialog(ActionEvent event) {
onComplete.accept(new CustomerInteractionResult(someDataGatheredByDialog));
}
}
Another way to do this is to add a result property to the controller of the dialog screen and interested invokers could listen to or retrieve the result property. A result property is how the in-built JavaFX dialogs work, so you would be essentially imitating some of that functionality.
If you have a lot of this passing back and forth stuff going on, a shared dependency injection model based on something like Gluon Ignite, might assist you.
I've used AfterBurner.fx for dependency injection, which is very slick and powerful as long as you follow the conventions. It's not necessarily an external lib if you just copy the 3 classes into your structure. Although you do need the javax Inject jar, so I guess it is an eternal reference.
Alternately, if you have a central "screen" from which most of your application branches out you could use property binding probably within a singleton pattern. There are some good articles on using singleton in JavaFX, like this one. I did that for a small application that works really great, but defining all of those bindings can get out of hand if there are a lot of properties.
To pass data back, the best approach is probably to fire custom Events, which the parent controller subscribes to with Node::addEventHandler. See How to emit and handle custom events? for context.
In complex cases when the two controllers have no reference to each other, a Event Bus as #jewelsea mentioned is the superior option.
For overall architecture, this Reddit comment provides some good detail: https://www.reddit.com/r/java/comments/7c4vhv/are_there_any_canonical_javafx_design_patterns/dpnsedh/

Model-view design in Flash

I'm creating a simple game to learn Flash programming. To have a clean model/view separation, I want to create a Player class which simply holds data relevant to the user. I'm also creating a StatusView class which extends MovieClip and which coresponds to a movie clip symbol which I've created in my Flash project. Basically the StatusView will display the data of my Player class onscreen.
I'm used to doing this sort of thing using listeners, so I've found the EventDispatcher class and added one as a member of my Player class. I'd like to have my StatusView movie clip add an event listener to my Player class so that it can receive messages whenever I change the data in my Player class.
The problem is, there doesn't seem to be anywhere for me to put my Player class so that the StatusView can find it (to add the listener). Everything in the project is created directly by one of the movie clips, and the runtime seems to create these movie clips in an arbitrary order. For example, say I create a MovieClip symbol called GameView and I create the instance of the Player there, and GameView is the parent of StatusView. When StatusView is constructed, I'd like to be able to access the Player from it's parent, but at that point GameView hasn't had it's constructor code run yet. This is true even if I wait for the ADDED_TO_STAGE event.
I could put the game model code in a singleton, but this seems like a hack to me. Is there a best practices way in Flash that lets me create and access my game model independent of all the MovieClip symbol stuff?
If you want to pass the reference of the Model to the constructor of the View, but are not calling the constructor yourself (because you do not create the object via code) you are out of luck here.
You could instead simply define a method on your View to pass a reference of the Model object:
public function setModel(value:Model):void
usage:
view.setModel(player);
There's no "law" that you have to pass the Model to the constructor of the View.
You can also create a set function for convenience:
public function set model(value:Model):void
usage:
view.model = player;
I feel like I have to disagree on the Singleton. The purpose of a Singleton is to guarantee that there's only one instance of it in existence. That's it.
It is not there to pass reference around easily (because the method to get the single instance is static). This is (IMO) a bad practice.
You could make anythign static in order to pass it around "easily". But this would make a mess and nobody does that.
But suddenly, just because the singleton pattern uses a static method, a lot of people think it's a clever way to get to the reference. I beg to differ.
First of all, you could implement Player class as singleton if you need just one instance. I don't think that that looks like a hack (for example, in PureMVC framework each model is a singleton).
At second, you can create instances of Player class in some general class (manager) and send them to views.
P.S. Also, I want to note that you can extend your Player class from EventDisptacher without creating specific field "eventDispatcher" in Player class. I don't know what way is better, but this one is simpler, imho.

WHY does Context become a GCRoot?

I appreciate Robotlegs very much, but recently a GC problem came to me. I failed to dispose context object by just set the reference null.With the help of FB profile tool, I find that context object appears to be a "GC Root".
To figure it out, I wirte a simple class, which creates a context obj and leave it unreachable.Here is the detail of this class:
public class MemoryLeak extends Sprite{
public function MemoryLeak()
{
makeAndDrop();
}
public function makeAndDrop():void{
var _context = new Context(this);
_context = null;
}
}
When I ran this class, I hoped it be disposed by GC, but it didn't work(most times, not everytime). And the profile tool show me this instance is a GCRoot. I read some articles about GC, but few of them mention GCRoot itself. Could anybody tell me why and thank you so much!
PS: I tried to call System.gc() twice after makeAndDrop() but it didn't work. In fact, I'm more interested in the "is GCRoot" issue(implied by the fb profile), it may help more if you tell me about it.
I think the Context will probably listen to this so that it can perform dependency injection on any added children or create mediators for them. One would hope that the listener would not be attached until you talk to the mediatorMap or the viewMap, but I think it is likely that the RL authors would not consider a use case where you'd want a Context on a View for a time period shorter than the View's actual lifespan.

flex 4 - why dispatchEvent triggering creationComplete recursively

I have a custom component called shopView which is an MXML skinnable component. I have a controller class called ShopController which takes care of showing this component in popup, updating info shown in the component etc.
Now, I wanted to maniupate some of the subcomponents of this ShopView after it has been created from the controller after the ShopView is created (creationComplete() event)
So, I have attached an event listener which intern does some initialization process
creationComplete="init(event)"
the init() function
private function init(event:FlexEvent):void{
event.stopImmediatePropagation();
initMenus();
initSlots();
dispatchEvent(event);
}
Attached another creation complete event from the controller class
_shop.addEventListener(FlexEvent.CREATION_COMPLETE,onShopCreated);
*_shop is the instance of ShopView*
Now, if you see the init() function, there I am stopping the event propagation, doing some initialization process and after that I am dispatching the event (for the shop controller do the rest of the job)
Now, this is crashing the app because the crationComplete event of the ShopView is recursively called. I was thinking the dispatchEvent will propagate to the other listerners but seems like it is propagating back to the same component.
I have fixed it by removing the e.stopImmediatePropagation() and dispatchEvent(event) lines from the init() function. But I want to know why it is happening like this?
Is it a known issue for the mxml/flex components? OR it is expected behavior?
Update: I am not doing same in .as as I said below. Got answer, basically its my stupidity :)
because I have not seen this behavior when I write .as classes where I
stopevent propagation and dispatch the event based on business logic.
Thanks in advance.
This is expected behavior.
When you redispatch an existing event dispatchEvent automatically clones it (since you can't dispatch the same event twice.) This clears any propagation-related flags.
May I ask why you want to redispatch CREATION_COMPLETE in this situation anyway? Both handlers will function just fine without the two lines you removed.

AS3: Major Slowdown

I'm working on a Flash game, and after running my game for a while there is a huge drop in frame rate. There aren't a lot of MovieClips onscreen at once, but MovieClips are being replaced using removeChild and addChild often.
How can one test for problems such as memory leaks? And what are some good AS3 programming standards on this matter?
It seems like you're not preparing your instances of MovieClip for garbage collection. This thread could be extremely helpful to you.
Some of the basic things you want to cover when discarding a MovieClip (or any other Object) properly are:
Remove the object from the DisplayList (if it's a DisplayObject). This is done via what you're doing already, removeChild()
Remove any event listeners that have been applied to the Object. Best thing to do is keep on top of this right from the beginning; by that I mean, when you call addEventListener(), be sure to somewhere in the very near future add a sister removeEventListener() as well.
Remove reference to your Object. This includes, but is not limited to: reference to the Object via being part of an Array/Vector, reference via being stored in a property of another Object, etc.
A suggestion that I can offer is to have in the base class of your objects a method that handles all of this, eg remove() or deconstruct().
Here's an example:
public function deconstruct():void
{
if(parent)
parent.removeChild(this);
removeEventListener(MouseEvent.CLICK, _onClick);
}
And when you extend this class and need other dereferencing features, just build on your deconstruct() method:
override public function deconstruct():void
{
removeEventListener(MouseEvent.MOUSE_OVER, _mouseOver);
var i:int = someArray.indexOf(this);
someArray.splice(i, 1);
super.deconstruct();
}
http://gskinner.com/talks/resource-management/