Actionscript: SharedObject and addEventListener - actionscript-3

Could someone explain when does local SharedObject triggers event handlers added via addEventListener?
I have tried and it doesn't trigger, after flushing.
For example i have two object.swf both in separate browser tabs.
I'm adding data inside object.swf on one tab and want event to be triggered in object.swf from another tab.
Is it possible with native functionality and without remote type of SharedObject?
Ofc i could write infinite loop and check local storage for changes, but it's the last solution i would like to implement. :D
I was reading docs and played with example over there, but it doesn't trigger event, even if it is added before flushing.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/SharedObject.html
Thanks.

Only remote shared objects dispatch events. If you want to communicate between two swfs, try LocalConnection instead. http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/LocalConnection.html

Related

Trigger code after passing all checks in MM01 but before DB commit?

I have checked some of the MM01 userexits but does not suffice what I need to happen.
My enhancement should only be triggered once material is already extended, preferably after save to DB. I used this EXIT_SAPLMGMU_001 but it is triggering my enhancement upon saving not after save.
You might want to try a different approach and use the Workflow eventing system (SWETYPV) to either start an entire Workflow or simply register a custom event handler once the material has been created.

Application_Launching timing

What exactly is the timing/thread of the Application_Launching method on WP8? Specifically, in relation to the UI loading/rendering sequence?
I have an app where some global init is being done within Application_Launching. I'm getting a crash report from a method that's called during data binding on the start page's XAML; the crash is consistent with said global init not taking place.
EDIT: I'm calling a native (C++) method which is reading a file into a mallocated memory block in a global variable that's initialized to null. Said variable is dumped as a part of crash reporting; I've got a report where it's null.
Pasting the code would be rather pointless IMHO.
When starting the app, the Launching event is raised. However, the app can later be put in a dormant state, in a process that is called "tombstoning". When a tombstoned app is resumed, it won't raise the Launching event but the Activated event instead. It's very likely that you forgot to handle that case.
To test it easily, go in the properties of your Windows Phone project, in the Debug tab, and check the "Tombstone upon deactivation while debugging" option. From there, every time the app is deactivated while the debugger is attached (typically, when pressing the home button on the emulator), the app will be tombstoned, and you can make sure that it resumes properly when switching back to it.
I've got another theory. It's not about the library being loaded at the wrong time, it's about the library being unloaded. Since almost all of my native functions are static and the state is global, there are no active native objects, and the COM subsystem has a zero ref count on the module. As per COM rules, modules like that are fair game for unloading anytime. On a subsequent native function call, the library is reloaded, but the global state is gone.
From the next version, I'll keep one live native object for the app's lifetime. We'll see if the crash comes back.

Test if local database (websql) contains desired new fields, and add them if not

I'm building a crossplatform HTML/Javascript app for iOS and Android using PhoneGap and jQueryMobile, and I am upgrading my app with (among others) a few new fields in one table of the local database (localdatabase/websql).
The challenge
I want to make sure that when the database is expanded with the new table fields, the existing user data, the user data will not be removed or become locked in an inaccesible older version of the database.
The background:
My app has a local database of the user's data (incomes and expenses, plus a few settings). These data need to be persitent, and the way to go, back when I started, was using the HTML5 localDatabase functionality, since that is both persistent, and available for the iOS and Android browsers as well as for most desktop browsers.
I am using a Javascript plugin/library/thingy called persistenceJS to make dealing with the localdb a little easier. But my question is not really specific to persistenceJS.
I am working on a new version of the app, which makes uses of a few new fields in the Settings table. So when these users download the new app and run it, it must test if their Settings table contains this field or not, and if not it must create the field.
How do I do this testing? I see two lines of thought:
Use the database label... that's used in the openDatabase function. This seems to be used by some developers to store a version number.
My trouble with this option is I only know how to use openDatabase to, well, open a database (and create a new one if none exists), and run a callback specifically if the database did not yet exist.
So if I open the table while specifying something like "v2" in the label, will it create a new table? If so, will it copy the old table's values into the new one?
Check for the existence of the table fields...
I could use openDatabase and then test for the existence of the table fields. If they don't, I could add them. The test would be run every time a user opens their app, which seems a little primitive.
By the way:
I know webSQL/localDb has been deprecated by the overlords, but it's still my tool and I want to stick to it for now.
I've found the answer here: http://blog.maxaller.name/2010/03/html5-web-sql-database-intro-to-versioning-and-migrations/.
Basically, you just apply the changeVersion method with the old and the new version label. If you didn't have a label, then the old label is "". While relabeling, webSQL quietly applies the new schema to the old database. Which in my case means adding the new fields.
The tutorial I linked to is really awesome (and so is the functionality).
I'm adding another answer because I've learned more about localDb opendatabase and migrating it.
As a reminder, openDatabase takes these parameters:
name - (string) name of the database
version label - (string) the version you want to open
display label - (string) a pretty useless display name that seems to be used nowhere
max size - (int) largest safe size is 5 * 1024 * 1024
newly created -= (function) to be fired if the db did not previously exist
It's wisest to assign the output of openDatabase to a variable. I.e.
myapp.db = openDatabase('mydb','','My database',5*1024*1024,newlyCreatedCallback);
First off, it seems wise to make use of the 'newly created' callback that's available as the fifth argument of openDatabase. It will fire only if there was no database with the parameters you specified. To prevent this callback from firing when your database did already exist, make sure you have the name, display label and maximum size set to exactly the values that were used to first create the database.
The reason to do this is that if the database was first created, you know for sure that you will not need to do any migrations. You can go straight to a function that adds tables and fields. I recommend using persistenceJS, a tool that helps you read and manipulate the local database.
Before calling openDatabase, it's wise to use jQuery to create a custom event 'dbopen' whose handler will execute migrations. This handler can be triggered by two events. The first is the 'newly created' callback we just discussed. The second is a setInterval that you define after call openDatabase. The interval must check for the existence of the myapp.db variable that you assigned the openDatabase output to.
The reason to create the dbopen custom event is that if you added a 'newly created' callback which triggers a whole bunch of events and continues the flow of your code afterwards, you will want a similar process for the 'not newly created' scenario. There is no callback for openDatabase that does this, so you will have to manually detect the creation of the local database and trigger 'dbopen' as soon as it has come into existence.
I use a window.setInterval for this. Make sure that you create the custom 'dbopen' event using jquery's .one() function, which will fire at most once. Otherwise if the database was newly created, you will fire the open event once when the 'newly created' callback fires, and once when the myapp.db variable comes into existence.

Restart flash on click

I'm trying to restart my flash piece with a restart button. I use gotoAndPlay(0), but nothing happens. I'm sure the click event handler is being called because I used a trace statement to verify.
rs.addEventListener(MouseEvent.CLICK, restart);
function restart(event:MouseEvent):void {
gotoAndPlay(0);
}
The first frame is frame 1, not 0.
Not sure why adobe decided against making frames zero-based, but they did :/
If you have added objects to the stage, like buttons or graphics, but never actually used the stage's timeline, the stage will start and stay at the first frame. So 'gotoAndPlay' wont work in this case. It would be only useful to restart an animation anyway, as it won't reset any code on its own.
You need to decide what parts you actually want to reset and what parts you can keep. You probably don't want to remove assets from memory you loaded at the beginning just to download them again. Some objects may be kept, others should be removed.
As far as I know there is no easy way to reset a flash application, other than maybe reloading the whole page. Here are some general steps to 'reset' an application by hand:
Create a method for your initialization code:
object creation, adding to the display list, adding event listeners.
On a click: remove all objects from the stage, remove all their event listeners.
Call the initialization method again.
Ideally you set the references in your init method to a new variable so the old ones can be garbage collected. Depending on the code structure you may have to manually set some to null. Make sure you don't keep any references to objects you don't need any more.

Design Pattern to require multiple events before executing method?

There are many times that I've needed to execute some code after a number of events have fired, and I've come up with counters and such but I feel there must be a better way.
For example, say five files need to be loaded, after which a UI component will become active.
If I set up a counter that increments each time a file is requested, then decrements each time one has loaded, I run the risk that the first two or three files may somehow get completely loaded before my code gets around to requesting the fourth and fifth, which would mean that my counter would be at zero when I still have two files to load, thus allowing the UI component to be prematurely activated.
There are some cases where you could know the number that need to be loaded before the requests go out, but it's possible that the first file contains the paths (and therefore the number of) files. (And this file-loading scenario is only an example of the pattern I'm trying to explain.)
Does anyone have an elegant solution for this? (Does my description make sense?) Thanks!
You could do something with a task framework like spicelib
Using that as an example
Create a FileRecursionLoadTask which grabs a file and completes when that file and any references it makes are loaded.
Add each FileRecursionLoadTask to a SequentialTaskGroup.
When the TaskGroup is completed, then you know all of the file loads have completed.
There are also plenty of other task frameworks which you might like better. For example, Spring ActionScript also has one.
Before executing a request, store a reference (a unique request uri, the loader object or a special command object) in a list. When a loader has finished, remove that object and call a function that checks if there are remaining active tasks in the list.
This isn't specific to file requests nor request in general, it can be used for anything that needs to wait for multiple actions to finish. Multiple list can be used to process multiple types of action at the same time. The object stored in the list could be implemented as a command object, which could provide more information about the task. This is called command pattern.
If you're doing just loading, like Jacob, I would also suggest a library that handles loading
If the case of a more complicated situation like mixing loaders and other event listeners, I would suggest using an event that fires whenever there is any change to any of the dependencies. In addition all the objects/classes would have a state.
Then I would create a listener adding function for the class that would need to do the function or initiate it, that would have 3 parameters
object with event dispatcher (assuming they all use the same update event) ie. assetLoader
name of object state ie. headerLoaded
state value's desired ie. true
the function would add the listener to a chain of listeners, and any time any of the listeners fires, all objects would check if the state value.
This would allow for regression as well (like when a user presses a button, the content starts loading, but then the user presses cancel, even if all the assets load, the state of one object would be false, thus not allowing the item to complete) If you were using counters, it would be the equivalent to adding instead of subtracting, but much more reliable.
Looking for a design pattern? Try the command pattern (http://johnlindquist.com/2010/09/09/patterncraft-command-pattern/)
(The video is a great example of what command pattern is and how it works - using Starcraft as an example.
The implementation is that you queue your load commands so that they do not execute out of order, and you can add the enable or disable commands to your command que. So the command pattern will play back your commands something like: load, load, load, enable ui item, load, load, enable another item
Good luck