I have two objects that are searching for one-another on the stage. They move in a certain direction with a certain speed. This is done via the Event.ENTER_FRAME. Once an objects finds the other it will start to do certain modifications on both objects, including stopping it.
Now, a certain problem came into mind. What if Object A finds Object B, start to do some modifications on Object B and the CPU is taken from ObjectA and given to ObjectB. Now, Object B will find ObjectA and will start to do modifications on ObjectA even though ObjectA is already in the process of doing this. This can be fixed with a very simple technique: once ObjectA find ObjectB it calls a lock() method. And objectB won't check for the other object while locked. The problem is that I don't know how to make the checking of the distance between the objects (this is how they find eachother) and the locking in an atomic way.
P.S. I have done a lot of multy-threading programming in Java in the past months so maybe these things don't apply here.
Thanks.
There should be no problem. Flash doesn't do multi-threading.
You can be sure that once an event function is called, it will run without interruption by other events. The only problem that you may need to consider is that you don't know the order in which multiple enter frame events will be executed. If the order matters, you should use a single event which calls your objects' event methods in the desired order.
Related
I have a question how can I clear/free memory in flash? For example I am finishing game and I want to start from beginning and if I will just jump to the first frame all the objects there are still in this memory, is any possibility to force cleaning memory?
Can I free memory for an object? for example I removeChild(something) - and I want to free memory for an object as I will reuse it?
Can anybody explain me how the engine works?
Thanks
I would encourage you to read Chapter 14, Garbage Collection in the "Moock Book" (Essential ActionScript 3.0 by O'Reilly Publishing).
The short answer to your question is that you're not in control of de-allocation, the garbage collector is. In a garbage-collected language like AS3 or Java, you don't have manual control over allocation and de-allocation of memory like you do in lower level languages; there are no AS3 equivalents to things like delete in C++ or free in C. Your goal should not be controlling when you destroy things, but rather not forgetting to remove references to things you no longer need around and making sure you disable things that you intend for garbage collection.
Memory leaks in AS3 typically come from a mixture of newbie misunderstanding (like thinking removeChild or setting a reference to null destroys objects), and from not keeping good track of references to objects--especially where strong listeners are involved.
A previous respondent posted this:
myObject = null;
What this does is remove a reference to the object that the variable myObject was holding. Nothing more. You need to know a lot more about the situation in order to be able to say whether this assignment even makes the object in question eligible for garbage collection, especially how many other variable are holding references to the object. And the object might already be eligible for garbage collection even if you didn't set the reference to null (i.e. if myObject has no connection to a GC root).
Suffice to say, the entire GC mechanism is more complex than can be satisfactorily explained in a StackOverflow post. That's why it has a whole chapter in the Moock Book, and even that book does not go into implemenation detail or great detail about when exactly the Flash Player does its ref counting deletions or mark and sweep passes.
The most important things to remember are, IMHO:
When you intend to "kill" an object, give it a cleanUp() or destroy() function where you do things like stop all its timers, sounds, remove listeners, etc. An object will continue to exist and execute code until it gets GC'd. And the Flash Player defers GC as long as it can--it's usually triggered when the Player needs to allocate more RAM from your system, because allocating memory is about the only thing that's more time consuming than doing the mark and sweep GC pass.
Read about weak vs strong listeners. Basically, when you have a weak listener, the listener reference is one that is ignored by mark-and-sweep GC, so it alone will not prevent an object from getting collected. But don't listen to anyone who tells you "always use weak" or "always use strong listeners and manually remove them" because there are times where each is appropriate, and that's why the choice is yours.
removeChild() will remove object from stage, but will still keep it in memory. You will have to null the object like this myObject = null if you wish to get rid of it entirely. You might not need to do that thought. Just removing it from stage and removing all associated events will be sufficient in most cases.
Clearing memory is a tricky thing with Flash, the proper way ow implementing it setting up objects properly in the first play for easy clearing, rather than forcing deletion. When you want to remove an object from memory, you do it by removing any reference to it, and then flash marks it for garbage collection. Then Flash at a later point removes the object from memory.
In order for the object to be ready for data collection it cannot have any connection to another object.
so if you have an object that has a single connection to a MovieClip and the movie clip has no other relation, then if you set it to null, you will remove it.
if you, however, have two objects that point to it, if you remove one link by setting it to null, the MovieClip will not be removed.
furhtermore, if you have a 2 or more movie clips that have a network of connections, removing those objects requires these connections be broken as-well. For example if you have a level with many characters and listeners set up, removing the lavel movieClip will not clear it.
one way of breaking these connections is adding onRemovedFromStage Events, that remove further children, listeners and objects. I've started using the casaLib extension of movieclip - CasaMovieClip, that has a function called removeChildrenAndDestroy. this makes it a bit easier, but would take a while to implement on an older project.
Anyhow, you'll find there are many sites discussing this, a good place to start is grant skinner's blog
My professor gave my class an assignment today based on object oriented programming in Pygame. Basically he has said that the game that we are to create will be void of a main game loop. While I believe that it is possible to do this (and this question has stated that it is possible) I don't believe that this is required for adherence to the Object Oriented paradigm.
In a diagram that the professor gave, he showed the game initializing and as the objects were instantiated the control flow of the program would be distributed among the objects.
Basically I believe it would be possible to implement a game this way, but it would not be an ideal way nor is it required for Object Oriented adherence. Any thoughts?
EDIT: We are creating an asteroids clone, which I believe further complicates things due to the fact that it is a real time action game.
Turn based games or anything event driven would be the route to go. In other words, take desktop GUI apps. They'll just tick (wait) over until an event is fired. The same could be done for a simple game. Take Checkers for example. Looping each game cycle would be overkill. 90% of the time the game will be static. Using some form of events (the observer design pattern would be nice here) would provide a much better solution. You're using Pygame, so there may be support for this built in, through due to my limited use I cannot comment fully. Either way, the general principles are the same.
All in all it's a pretty rubbish assignment if you ask me. If it's to teach you event driven programming, a simple GUI application would be better. Even the simplest of games us a basic game loop, which can adhere to OO principles.
Hmm. In the general case, I think this idea is probably hokum. SDL (upon which PyGame is implemented), provides information to the program via an event queue, and consuming that queue requires some sort of repeatedly checking the queue for events, processing them, and waiting until the next event arrives.
There are some particular exceptions to this, though. You can poll the mouse and keyboard for their state without accessing the event queue. The problem with that is it still requires something like a loop, so that it happens over and over again until the game exits.
You could use pygame.time to wait on a timer instead of waiting on the event queue, and then pass control to the game objects which poll the mouse and keyboard as per above, but you are still 'looping', but bound by a timer instead of the event queue.
Instead of focusing on eliminating a main loop, how about instead think about using it in an object oriented way.
For instance, you could require a 'root' object, which actually has its own event loop, but instead of performing any action based on the incoming events, it calls a handler on several child objects. For instance when the root object recieves a pygame.event.MOUSEBUTTONDOWN event, it could search through it's children for a 'rect' attribute and determine if the event.pos attribute is inside that rect. if it is it can call a hypothetical onClick method on that child object.
I think it might qualify as event driven programming? Which can still be object oriented. You see this in Flash a lot.
There's a difference between a main loop in a main class. You can still have a game class initialize all of your objects, and then rely on inputs to move the game onward.
Kinda hard to say exactly without knowing the exact parameters of your assignment, the devil is in the details.
You might look at how python utilizes signals. A decent example I found is at: http://docs.python.org/library/signal.html
i'm curious about something. Let say we have 30 object in the code, and every object should be animated trough enter frame event. Which will be faster(in terms of memory execution) : to have just one event listener in the main object (for example) and to call object methods, or, to have separate event listener for every object?
Thanks :) .
UPDATE: Well, actually, i need to monitor each object to find out when that object is on current frame, e.g. on end of animation, and than remove it from display list. What is the best way to that?
For 30 objects, this doesn't really matter. Actually, in general it matters only little, since the bottleneck will always be rendering.
But to answer your question: Listeners are slow. For one notification to happen, an Event object needs to be created (allocation is generally quite expensive), and an untyped call of an anonymous function or a method closure needs to be done (which is signifficantly slower than calling a method on a strictly typed value).
You should try to use tweens instead of animating via ENTER FRAME event.
Animating on ENTER FRAME will cause tremendous lag, especially if you have lots of objects.
Checkout TweenLite: http://www.greensock.com/tweenlite/
Definitely to have just one event listener. The less listeners, the faster.
As a rule of thumb, one listener is better, and will induce a more predictible behaviour.
That being said, it depends pretty heavily on what you're trying to do. You might not have to animate every object on every enter frame event, thus gaining performance further.
So, I've been toying around with Flash, browsing through the documentation, and all that, and noticed that the ENTER_FRAME event seems to defy my expectation of a deterministic universe.
Take the following example:
(new MovieClip()).addEventListener(Event.ENTER_FRAME,
function(ev) {trace("Test");});
Notice this anonymous MovieClip is not added to the display hierarchy, and any reference to it is immediately lost.
It will actually print "Test" once a frame until it is garbage collected. How insane is that? The behavior of this is actually determined by when the garbage collector feels like coming around in all its unpredictable insanity! Is there a better way to create intermittent failures? Seriously.
My two theories are that either the DisplayObject class stores weak references to all its instances for the purpose of dispatching ENTER_FRAME events, or, and much wilder, the Flash player actually scans the heap each frame looking for ENTER_FRAME listeners to pull on.
Can any hardened Actionscript developer clue me in on how this works? (And maybe a why - the - f**k they thought this was a good idea?)
Short answer: you get what you ask for.
The fact that your MovieClip is "anonymous", as you call it, doesn't change how garbage collection works.
Both of your theories are wrong. It's simpler. You asked your MovieClip instance to notify you whenever a frame is entered. Quote from the docs:
Dispatched when the playhead is
entering a new frame. If the playhead
is not moving, or if there is only one
frame, this event is dispatched
continuously in conjunction with the
frame rate. This event is dispatched
simultaneously to all display objects
listenting for this event.
And this is what is happening.
Objects such as MovieClips are heap allocated. If you store a reference to it in a local variable, the reference lives in the stack and will get out of scope when you return from your function. You'll have no way to refer to the object, but the object will still be alive, in the heap. So, whether you store a reference to the mc instance or not, that doesn't change this basic fact of how heap and garbage collection works.
Now, since the are no strong refs to this object, this object is elligible for collection. This does not mean it will be collected when the function returns.
Since the object is still alive, it will continue to dispatch the event, because you asked for it. Once it's collected, naturally, your code in the handler will no longer be executed.
Edit
I said that both of your theories are wrong. I think that's the case from an Actionscript perspective. However, at the player level, it seems evident that the player has to keep track of objects on which it must fire certain events, so yes, it must be storing an internal reference to said objects. This is no different to how it works for other objects that are globally handled by the player, though, such as for instance, loaders. There's one exception to this that I'm aware of: running Timers. As long as a Timer is running, it won't be collected, even though you don't have any Actionscript reference to it.
So I'm attempting to use the MVC pattern for a game I'm working on. Everything has been going pretty smoothly so far, but I'm having trouble figuring out how to get my model and my view to talk to each other effectively.
My general model structure involves lots of nested information.
a Level has Rooms
a Room have Layers
a Layer has Objects
Each layer has an index and a corresponding layer in the view that is rendering it. I need the objects to post an update message as they animate so it's corresponding layer in the view can update. I'm trying to use the built in event system to handle these updates.
My issue is I'm not sure how to avoid putting listeners on every object in the game - which strikes me as bad ( perhaps I'm wrong here ). If I change the rooms, the layer doesn't have a way of removing listeners from the objects in the last room because it only accesses layers through the current room. Objects are only updated when they are in the current room, so the other objects won't need to fire events.
The view is set up to cascade events to all of the children, so the root node can receive all updates ( I think I did that part correctly ), and the layer can match the target because it knows which layer it's rendering. The problem is getting the message out from the objects to the view.
Of course this makes sense to me, because I've been working with the code for a while now.
If I can provide more clarification please ask. This is my first time working with the MVC pattern, so I'm sure I could do things better.
If you have any suggestions as to how I might solve this conundrum, please share!
Edit: I have something working keeping track of the current layerset from outside of the view and the model which manages adding/removing the appropriate event listeners and delegating the update event to the layer as suggested. But please, anything I can do to improve this please do.
If you are new to MVC you may want to check out the PureMVC framework for AS3. When I first started learning MVC I started by trying to build my own implementation of the pattern. After trying out PureMVC I got a much better understanding of the structure of MVC.
Your rooms/layers/objects sound like they have a parent/child like relationship and may be a good candidate for the composite design pattern. Basically this is a tree like structure where you could trigger an event which would then cascade through all branches. If you do a search for 'composite pattern' you may get a better explanation of how this may work for you.
There a few solutions you could take, adding event listeners is reasonable, but as mentioned you are going to need to make sure you clean them up appropriately, but this will be a requirement with a lot of other solutions as well.
Another one would be to pass in the layer on object construction, perhaps in the form of a "parent" property. In this case the object would notify its parent whenever it has changed, then on layer update, it would go through and handle all objects who have registered as having changed. This has performance benefits in that the object could change several time between renders, but the parent would only act on this changes once, (when its been told to update itself.) In this case you would still need to make sure you clean up your references properly to avoid garbage collection problems.
Yet another solution would be objects register with them selves as having been changed, typically in the form of a simple Boolean value. In this case the parent (your layer) would loop through all children, presumable stored in some form of collection, and handle updates to all those who say they've been changed. This solution removes the dependencies from object to layer, but in extreme cases, could lead to performance issues, (Extreme case being so many objects the process of checking a single Boolean value on them is too much to handle (that'll be A LOT of objects))
Hope that helps.
Using the Mediator pattern in PureMVC, rather than putting listeners on every object, you could have a Mediator listen to the application instance for the events. Then inside the actual objects, send a bubbling event that bubbles up the display hierarchy to the application where the Mediator hears it. Then the mediator takes the appropriate action such as sending off a notification to trigger a command with some logic, perhaps. The target of the event, would of course be the item in your world that sent the event, so if the Command would need to manipulate or inspect that item, then just pass the event.target in the notification body. QED.
-=Cliff>