What to put in a reset method in a Poolable interface? I really confused what code should I put in there.
In the reset method you put code that will make sure the object in the pool is ready for re-use. The reset method is called when Pool.free is invoked and is used to guarantee that the object in the pool is in a known, safe state.
For example; if you, for some reason, had a pool of IntMap<String> (i.e. a map keyed on ints holding Strings) you might want to call clear on the IntMap<String> in the Poolables reset method to make sure that when someone gets a pooled map, it doesn't contain any items left behind by the last guy using that pooled instance.
Related
I just discovered nested functions in AS3 (yeah, late to the party) and am using them in a Flex project. I've always disliked having to use separate functions for essentially modal operations with eventListeners– adds clutter to code and separates operation logic, as well as not being able to easily reference local variables.
The example below for a user selecting a directory seems to work very well and is nice an compact but I am wondering if there are any issues I am not aware of with this approach. Also, with a non-modal operation (e.g. asynchronous like using a Loader), is it possible to use nested functions?
private var rootDirectory:File;
protected function rootBtn_clickHandler(event:MouseEvent):void
{
var tmp:File = File.desktopDirectory;
tmp.browseForDirectory("Set Project Folder");
tmp.addEventListener(Event.SELECT, onUserSelect);
tmp.addEventListener(Event.CANCEL, onUserCancel);
function onUserSelect(event:Event):void
{
tmp.removeEventListener(Event.SELECT, onUserSelect);
tmp.removeEventListener(Event.CANCEL, onUserCancel);
rootDirectory = event.target as File;
}
function onUserCancel(event:Event):void
{
tmp.removeEventListener(Event.SELECT, onUserSelect);
tmp.removeEventListener(Event.CANCEL, onUserCancel);
trace("user canceled");
}
}
There can be some caveats when using anonymous or nested functions.
The first and most important is garbage collection:
In your example, the only thing keeping your tmp object from being garbage collected is the SELECT and CANCEL listeners themselves. Since you are not setting the weak flag to true, this shouldn't be a problem, however, if you we're using the weak flag (tmp.addEventListener(Event.SELECT, onUserSelect,false,0,true)) then there is a decent change the tmp object would get garbage collected before the user SELECTS or CANCELS a file.
Also, it's imperative that you remove every listener that you attached in this way. You are doing that in your onUserCancel method, so it should be fine, but if you were not, then you would have a memory leak on your hands as every time your click handler ran, another instance of tmp would be created but it would never get garbage collected because of the listeners attached to it.
So to summarize, most people stay away from anonymous/nested methods in AS3 (and I generally/usually recommend that to people) because it's easy to create memory leaks or have your closures garbage collected by accident. There also may or not be performance differences, but I have never ran tests in that regard.
I'm new to programming and I've been checking a lot of game coding tutorials. I've noticed that on most of them they use custom events to trigger methods instead of calling a method directly.
What's the reasoning behind this practice? Why aren't they just calling the method?
For example:
We have two objects: A and B. A has method A.methodA() that B needs to use when X condition is triggered.
Why implement:
B dispatches an event to A that tells A to run A.methodA()
Instead of:
B uses A.methodA()
The main reason is separation of interests. When using events, class A doesn't need to know about the existence of class B (and vice versa).
Some benefits to this are:
Much easier unit testing (you can test Class A without class B)
Less chance of breaking your code when you change class A or B
Less references to other classes in your code, which reduces the potential for memory leaks
Cleaner code
More flexible/reusable code (a bunch of other classes could all listen/respond to the event without any additional code in the your dispatcher)
Typically in bigger applications using events will help abstract everything. When you have 15+ classes and they're all ditpatching events to a controller, it's a lot easier to figure out what's going on than reading through all different parts of the code to trace functions. Using callbacks begins to create spaghetti code.
However, direct function calls are going to be executed faster than events.
Personally, I use custom events simply for the ease of use. I can have one class dispatch an event when something happens (say an animation finishes or an error occurs in a download) and any number of other classes run any number of other functions based on that event. In addition, I code for reusability. The goal of each class is complete independence so that it can run in any project without needing other packages. So rather than have one class call a method of another class, I dispatch an event from the first class that the second class listens for and then run that method. Then when I need that first class for another project, I can just copy/paste it without having to modify it and without losing any functionality.
EDIT:
Also, it's worth noting that sometimes people do what you describe to get around having to pass in event arguments.
Say you have a button on the stage and you need to be able to click it, but you also need to be able to manually call that method. Some people don't realize you can pass in a null event and have only the single method. Or you can set it as a null default argument, see below:
private function onClickHandler( e:MouseEvent = null ):void{
//as long as you never reference "e" within this method, this method can be used both for MouseEvent listeners and manually calling it elsewhere in the code
}
That technique can help avoid having an event handler that only calls another method and nothing else. At this point in my programming, every single AS3 event handler I write sets the event argument to null by default. It just makes things easier later on.
You might want to read this.
And also note using the callback method allows you to pass parameters to it directly and not via a custom event model.
I built my own, very simplified, events dispatcher system. AS Event model is very powerful, but in 99% of situations you don't need that power. A simple callback with parameters fired as an event is more than enough. You can still retain the versatility from an event model, but don't need to write too many lines of code for, let's say, a simple button.
I can setup a simple event like this:
Buttonizer.autoButton(_buttQuit, this, "onPress");
public function onPressQuit(c:Sprite) {
// Execution goes here
}
You can build your own event model, it will make life simpler, and your code much more concise.
I am new to RubyMotion and trying to understand how object initialization works. Suppose a simple class with one class and one instance method:
class Something
def self.getSomething
BubbleWrap::HTTP.post("http://example.com") do |response|
p response
end
end
def getSomething
BubbleWrap::HTTP.post("http://example.com") do |response|
p response
end
end
end
Now, why does the following work:
Something.getSomething
And the next snippet not, well, sometimes (ran this snippet and the runtime crashed 8 out of 10 times).
something = Something.new
something.getSomething
I am doing it wrong. Any pointers in the right direction?
Use instance variables:
#something = Something.new
#something.getSomething
RubyMotion has a handful of bugs related to local variables and blocks. You're assigning to something and then calling something.getSomething, which then uses BubbleWrap's asynchronous HTTP.post method. The BubbleWrap HTTP block runs, but in the meantime, the method you're calling something.getSomething from has completed execution. Since something is a local variable, it gets garbage collected when the method exits. So when the HTTP request completes and the block is called, the block no longer exists.
You're probably seeing random inconsistent errors (and once in a while an actual working request) because each time, the memory location where the block was stored was reclaimed for something else (or once in a while, it wasn't reclaimed at all so the block is still there). None of this happens when you use an instance variable instead, because when the calling method finishes execution, the instance variable sticks around.
This behavior is definitely unexpected; I know a couple issues have been filed (myself included) to get this fixed.
I been using the WebService and Operation classes of Flex Framework for a while, and after some ups and downs (more downs than ups, haha) I'm in process of refactoring all its uses with some utility classes/wrappers.
After browsing a little of the code of mx.rpc.soap.Operation I noticed that when you use the method "send" and the web service is not ready then the call is queued to an internal array (pendingInvocations:Array in line 1142). But the funny thing is that the invocations in the queue are never called again.
This is a bug or there is something I'm doing wrong?
I'm considering extending mx.rpc.soap.Operation, overriding "send" and testing if there are invocation queued, calling invokeAllPending (a mx_internal method that pops all the queued invocations) my self.
But the other problem is that that method is mx_internal, so I don't know if Adobe is gonna change it any time soon.
Any advice?
Thanks in advance
It's not a bug. Take a look at the definition for AbstractWebService; it defines a method called unEnqueueCalls (which is right up near the top of the list of awkward method names that I've seen :)). This method loops through all the operations in the webservice and invokes the pending calls for each operation by calling that invokeAllPending method you found.
unEnqueueCalls is itself called from the WebService class, in the wsdlFault and wsdlHandler methods, one of which runs when your WSDL is finished loading.
So, everything is all accounted for; you don't need to override anything.
I want to write a SessionExtension that fires a 'Foo-created' event or 'Bar-created' event every time a new Foo or new Bar is committed to the database. However, once inside the after_commit method, I don't know where to find which entities have been committed. Where do I get this information?
The Session instance has attribute new, dirty, deleted holding added, updated and deleted objects respectively. They will be already empty when after_commit is executed, but they are available in after_flush. You can extent your own list of added instances for each flush in after_flush hook and use them for events and clear in after_commit.
Look at the Mapper Extension bits. It provides you before/after insert/update/delete hooks that you can place your code for this kind of thing.
http://www.sqlalchemy.org/docs/mappers.html?highlight=mapper%20extension#extending-mapper