Does ActionScript have an equivalent of a "core dump"? - actionscript-3

Here's my situation: I'm working on an AS3-based game and I'd like to have a "Report a problem!" function within the game so that users can submit feedback to me.
When my user reports a problem, I'd like to get as much information as I can about the state of their game; basically what objects are in memory, what the values are of all those variables inside all those objects; essentially the same information I can get when I hit a breakpoint in the debugger.
Is there a simple way of doing this? I'm afraid that I'll spend several days trying to write a bunch of functions that gets all this information for me, only to have somebody tell me afterwards, "Oh, why didn't you just call ASUtils.getSnapshot()"?

There is no generic way in AS3 to dump the state of your variables, but there are several things we do that you might find useful:
Capture a log of recent click activity. Use stage event listener to log clicks and trace the object "path" up the parent chain to the stage. The object path is just all the DisplayObject names, like: screenMain.dialogBuyItem.buttonBuy
Capture a screenshot, reduce it to a small thumbnail, JPEG encode it, and upload it to your server along with their feedback. We also do this when there is an exception (see #4). as3corelib has JPEG encoding functions in com/adobe/images
Write a command-line pearl or PHP script you can run on your AS3 code before you publish it that will inject call tracing at the top of each function call. This allows call history to be logged. While it's not as good as a full stack, it will give you some indication of what your code has been doing recently.
Trap asserts and unhandled exceptions and log them to your server with click activity and call history trace. Unhandled exception listeners are new in flash 10.1, but most users have this feature. You can check for that support and add a listener like this:
// Check for the presence of the Flash 10.1 global Error event (exception) handler class.
// If it exists, we'll listen for it and it will allow us to report errors to our server.
if ( loaderInfo.hasOwnProperty( 'uncaughtErrorEvents' ) )
loaderInfo.uncaughtErrorEvents.addEventListener( "uncaughtError", onUncaughtError ); // UncaughtErrorEvent.UNCAUGHT_ERROR
If you have global state variables that you want to log with feedback, you can write a function to dump them to a string for uploading with the user feedback. While you can enumerate class and object properties using for each, this only works for public members. Google around and you'll find some functions people have written to dump objects and array data recursively using this enumeration trick.

i'd like to add it as a comment, but don't want to lose code formatting
this is what i'm using to trace complex objects:
private function parseObject(o:Object, prefix:String = '>'):String {
var retStr:String = '';
for (var s:String in o) {
retStr += prefix + s + ' = ' + o[s] + '\n';
if (typeof(o[s]) == 'object') {
retStr += parseObject(o[s], prefix + '>');
}
}
return retStr;
}
hope it'd be helpful

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/

Why is native .bind() so slow?

I recently came across this issue. For a project I'm working on, we were using .bind() way too often and it actually hit the performance quite hard considering that we only have 16ms for the rendering loop to do things.
So I did some jsperf and noticed that calling a bound function (besides of the extra garbage) is way slower than calling an unbound function or using .call on a function.
I literally changed every piece of code to avoid bindings and to use .call/.apply instead. Ding this i not only spawned less functions but also increased the performance of my app a great deal.
However, I was unsatisfied with this and wrote a new way of binding functions.
https://github.com/SebastianNette/FastBind
This is overwriting the native bind method with a .call/.apply approach.
And it runs 96% faster.
Doing some testings on nodejs is came to these results:
Calling a bound function is 20 times slower than calling an unbound function.
Calling a bound function with my own approach takes only 2 times the time of the unbound call.
So I was wondering what is wrong with the native binding function. Why does it behave like that? And which would be the best way to deal with that issue.
Most of my app code is now written like that:
var scope = this;
this.boundFn = function(a,b,c) { return scope.fn(a,b,c); };
Or even
this.callback = fn;
this.context = context;
this.callback.call(this.context);
I do prefer the latter because it doesn't spawn any new functions. However, sometimes I just do have to bind. (handlers, timers, etc).
My educated guess is that it makes a clone of the object you are using but replaces the underlying prototype of object. Instead of using a generic precompiled object from the page rendered code it now has to take two things:
The passed variable thats to be come this. analyse it, clone it. then inject the specified function thats to be called into the new object. Then execute the function in the new object. afterwards if no longer called clean it up.
The more complex and more scoping loops an object has the long the bind will take because the engine needs to traverse the scope tree of all functions and parameters to see what needs to be copied.
You are already using scoping, which I strongly advice. It is less memory intense and the engine does not have to copy the objects and then call the functions. And you get the added benefit that you can access properties from both objects.
In my experience binding is never truly needed. Just use setters and getters for properties, otherwise the scoped variables won't always change in the main object.
Take for example this snippet
function domagic() {
this.myproperty = "Hello ";
}
domagic.prototype = {
perform:function(){
var that = this;
var hello = "World";
setTimeout(function(){
// this in this contect is whatever runs timeout. not domagic
// I use this for jQuery and my own objects to get best
// of both worlds, but I always post a comment in a scope
// to remind myself what this and that refers to.
window.alert(that.myproperty+hello);
that.set("Goodbye ");
},2000);
},
set : function(what) {
this.myproperty = what;
}
};
magic = new domagic();
magic.perform();
setTimeout(function(){magic.perform();},2000);

Adobe AIR Sqlite assync transactions

Here is the problem that I want to implement a solution, I have some data that needs to be writen in a database,data comes from network and it could arrive in "parallel", also for performance reasons the code is using async connection. The problem is that I have some bugs in my implementation ,I want to rewrite this code so it also uses transactions and rolloback,handle all possible errors and the code should be clean and easy to understand.
I am unable to find example code to read to get inspired or something to use directly, looking on what others done would help a lot.
So anyone know or has such example code?
I think I need to write some code that will allow me to chain this methods :begin->execute->commit->end transaction and in case of errors rollback
Update
what I want to find or implement is something like
Update2 so where things get confusing is when you want to insert an array of stuff, you will need to use a loop and then use the execute method async, and then when it succeds insert the next element and so on, this makes it a little more complicated especialy if I want to abstract this ito have all this section of code in a single place and not all over my code.
function executeAssyncAsTransaction(statement:SqlStatement,responder:Responder):void{
//step 1 begin transaction
//step 2 execute
//step 3 commit
//step 4 end transaction
//step 5 handle errors and rollback
//use responders above no event listeners
}
I think I know how to implement this but I know that there is a chance I do it wrong (my current implementation that is in production crashes sometimes on some machines so I I know is hard to write 100% error free code)
I am, also thinking to implement a queue that will store my statements if needed(if database is busy) so I don't get an error and have to try again later
Use event listeners, error and callback functions in Adobe Air for JavaScript like this:
var conn = new air.SQLConnection();
conn.addEventListener(air.SQLEvent.OPEN, openHandler);
conn.addEventListener(air.SQLErrorEvent.ERROR, errorHandler);
// The database file is in the application storage directory
var folder = air.File.applicationStorageDirectory;
var dbFile = folder.resolvePath("DBSample.db");
conn.openAsync(dbFile);
function openHandler(event)
{
air.trace("the database was created successfully");
}
function errorHandler(event)
{
air.trace("Error message:", event.error.message);
air.trace("Details:", event.error.details);
}
For ActionScript read these ressources:
http://de.slideshare.net/peterelst/introduction-to-sqlite-in-adobe-air-1627545

Loading an XML in ActionScript 3 before an event listener happens

I'm trying to fill some data from an xml feed we made into my Flash movie. The main action of this is in the constructor for MediaElementJS's .as file.
Anyway, the main problem is that I keep reading there is no way to load a URL synchronously in AS3 (which i still find hard to believe). This constructor calls both parse('url') and a function addEventListener(EVENT.ADDED_TO_STAGE, initializeAds);
Now the ads need info from the XML but the XML aint ready yet. I tried to call the ads at the end of the XML parser when I knew it would be prepped but it messes them up and the ad values never change from their defaults..
Oh wherefor art thou actionscript locking mechanism..
So is there anyway to preload data from a URL?
CODE:
public function LoadXML(e:Event):void
{
removeEventListener(Event.COMPLETE, LoadXML);
var xmlData:XML = new XML(e.target.data);
episodeData.pre.type = xmlData.episode.pre.ad.#type;
episodeData.pre.url = xmlData.episode.pre.ad.text();
episodeData.video = Number(xmlData.episode.video.#id); /*************** I CAN'T REMEMBER ***********/
episodeData.pageTitle = xmlData.episode.video.#pagetitle;
episodeData.title = xmlData.episode.video.#title;
episodeData.source = xmlData.episode.video.source.text();
episodeData.post.type=xmlData.episode.post.ad.#type;
episodeData.post.url=xmlData.episode.post.ad.text();
episodeData.nextEpisode=xmlData.episode.post.nextepisode.text(); //if not empty redirect to this
xmlLoading = false;
//THIS IS WHERE I TRIED TO CALL THE FUNCTION I NEED TO LOAD LATER
}
public function parse()
{
var xmlLoader:URLLoader = new URLLoader();
//var xmlData:XML = new XML();
xmlLoader.load(new URLRequest(rootURL + '/episode.aspx?associd=' + _episode));
//xmlLoader.addEventListener(Event.COMPLETE, processXML);
xmlLoader.addEventListener(Event.COMPLETE, LoadXML);
}
I've tried it with a static URL address and whatnot of course but no dice.
The code in the constructor works if I dynamically assign a static value but if I try chaining to events together to get the dynamic value and dynamic assignment it crunches.
In the constructor, definitely runs both by themselves:
parse();
// Google IMA EventListener
addEventListener(Event.ADDED_TO_STAGE, initialize);
Loading URLs is always asynchronous, so add the event listener in the response function for the URL loader.
Now your question sounds like you tried that but had some problem, so post that code and let us take a look.
Edit START
When I have multiple asynchronous calls that happen and I need something to happen after both of them are done I usually use booleans to store if each one has happened yet, then in a third function they both call I check both the booleans.
Here's how I'd do that:
protected function viewnavigatorapplication1_preinitializeHandler(event:FlexEvent):void
{
var loader1:Loader = new Loader();
var loader2:Loader = new Loader();
loader1.addEventListener(Event.COMPLETE, loader1_completeHandler);
loader1.load(new URLRequest("http://www.whitehouse.gov"));
loader2.addEventListener(Event.COMPLETE, loader2_completeHandler);
loader2.load(new URLRequest("http://www.nasa.gov"));
}
private function loader1_completeHandler():void
{
loader1Done = true;
//Maybe do some stuff here
moveOn();
}
private function loader2_completeHandler():void
{
loader2Done=true;
//Maybe do some stuff here
moveOn();
}
private function moveOn():void
{
if(!loader1Done||!loader2Done)
return;
//Do whatever needs to be done once both asynchronous events have completed
}
If this isn't your problem I think you need to provide more of the code in place of the comments that indicate other things happen, because it is a bit unclear.
For example I'm not sure what you mean by "The code in the constructor works if I dynamically assign a static value but if I try chaining to events together to get the dynamic value and dynamic assignment it crunches." Also since there's no example of the data or what the rootURL is there's no way to debug from here to understand what's going wrong.
Since there's no error we would need to be able to re-compile some portion of your code locally to give any better feedback.
Edit END
Blocking or synchronous calls are a horrible idea with regard to network communications due to the lack of reliability of networks and/or servers. If a front end application locked up to wait for a response before doing any other processing it would result in a horrible user experience, this is why there is no synchronous remote calls.
What happens with a synchronous call when the server bombs out, the client remains locked even though no response will result, the user can't interact with anything else in the front-end because it's waiting for said response which will never come? It's much better that remote calls of any sort are done in an asynchronous fashion, the same is true with local disk access in Java (or otherwise) where using asynchronous non-blocking calls is generally a better way to go to allow the other processes within an application to continue regardless of the state or use on the disk.
What you're doing should work just fine, you make a call to a remote service, it responds with some result and hits your "listener" or "callback" function then you want to do something with the results you can call another function, and the data is there.
It sounds to me like the only thing that's not happening is updates after the fact aren't being reflected in the UI, this is probably due to a lack of Bindable metadata/event dispatching for the properties. Have you inspected the result in the event that returns, have you put breakpoints in the method that is meant to be called after the data has returned? What you're doing is completely possible and it even looks like you have most of it right, but there's definitely something your doing wrong that's resulting in you not being able to make this work. If you can explain the behavior a bit clearer that will help, also what do you do here:
//THIS IS WHERE I TRIED TO CALL THE FUNCTION I NEED TO LOAD LATER

Asynchronous loading / error handling

Let's say that I have a bunch of objects (thumbnails in a matrix for example) and I need to load some data files for all of those over the network (HTTP). So each thumbnail has the thumbnail image itself and an xml file for instance.
There's a number of things that can go wrong from IO errors to bad URLs to badly formatted XML and so on. The question is what is the best / most elegant / most robust way of organizing all of this. What I usually end up doing is having a load manager that tells the
child objects to start loading and then monitors the loading. The child objects have listeners for IO errors and HTTP status events. When all children have loaded everything (with some possible failures) something is done (the thumbnails are shown or whatever).
I was thinking that there has to be a better way of doing this, something that would allow me to maybe use throw clauses when errors occur. Throwing something from the listener isn't going to do much good of course. So what to do. Have a local flag(s) in the child objects and abort if something fails or what?
I am using AS3 but the question should be pretty much the same for other languages, at least for object oriented ones.
Just to be clear I'm not looking for any program code, just general ideas on a design pattern. I also realise that because of the asynchronous load I'm tied in to event handling at least in the child objects.
i use a "queue" package which is able to deal with all sorts of asyncronous operations. the nice thing is you can nest these operations (composite pattern) and create quite complex stuff easily. if events occur you can catch them either at the root as they "bubble up the queue tree) or directly where they originate, depending on the listeners you add.
interface Qable extends IEventDispatcher {
function start()
function stop()
}
interface Q extends Qable {
function add(item:Qable):Q
function remove(item:Qable):Q
...
}
var q1: Q = new Q
q1.add(new Qable(...))
q1.add(new Qable(...))
var q : Q = new Q
q.addEventListener(Event.COMPLETE, onComplete)
q.addEventListener(Event.ERROR, onError)
q.add(new Qable(...))
q.add(new Qable(...)).addEventListener(Event.Error, onItemXError)
q.add(m1)
q.start()