Showing posts with label as3. Show all posts
Showing posts with label as3. Show all posts

Friday, December 19, 2014

#AS3 KeyboardHandler

(i've posted this as a comment in Starling bug report from a user)

for performance crucial sections such as keyboard interaction i would not use anything but callbacks.
the flash event system, and the alternatives such as signals are nice for higher level management, but they can't really beat callbacks for performance. what Starling does with the enhanced events is also fast, but here is my point.
the virtual machine and the garbage collector already provide you with the flexibility of one of the core features - everything is an Object including Function.
"functors" or function pointers is something that even languages like C++ don't handle that well, so you really should take advantage of this low level, yet still high level feature.
since the only way in flash to see if a key is pressed is via the KeyboardEvent, use that and build a callback system on top of it. only maintain the stage events and propagate manually not display objects but rather objects of interest.
check this concept i wrote quickly:
  • KeyboardHandler is a state machine that tracks keyboard isDown states for a keyCode and calls your registered callback.
  • it uses the native stage
  • it's super fast
  • it's worker safe
  • you can stop it at any time using "enabled = false"
  • it does call event.preventDefault(), event.stopImmediatePropagation(), but you can mod that yourself or simply call "enabled = false" when needed.
  • once a key is down it no longer registers as down until it up, this forces you to write your key logic smart.
  • if you don't track a key state yourself (which would be faster) at any time you can call supportedKeyIsDown(...) to see if a key is currently down. this allows easy checks for key combinations e.g ALT + SHIFT + LEFT.

Tuesday, September 10, 2013

#flash cs6 compiler bug

i have to work with tools like the one mentioned in the title. here is a bug that only happens if you assign code to a frame in the (main) timeline. target version is 12.0.0.481 and could be fixed in later interations.

you can try the following:
// Array can be used here instead, for 'list'
var list:Vector.<String> = Vector.<String>(["hello", "world"]);
trace(list); // hello,world
var vlen:uint = list.length;
trace(vlen); // 2
const clen:uint = vlen; // this works but 'vlen' is zero at this point
trace(clen); // 0
const len:uint = list.length; // list is a null object reference

results in:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Untitled_fla::MainTimeline()

what happens here is that the as3 compiler tries to play smart and traverses for 'const' declarations, and once it finds 'len' it decided to assign a value to the address where it will be stored in the 'constant pool' and then to be referenced by bytecode. but since 'list' is not a 'const' declaration itself the object is simply not constructed yet and 'list' is a null reference.


same does not happen if:

- 'const list:...' is used, but one may not want that
- if the same code is written in an external document class instead on the timeline

if this is by design it may cause compatibility issues with class written code and simply confuse developers. after all, constant declarations after variable declarations should make perfect sense. in general, i wouldn't recommend writing anything more important on timeline frames, but use classes with ENTER_FRAME listeners or attempt to use addFrameScript() on MovieClip instances instead.
--

Monday, January 28, 2013

#starling framework video tutorials

here are a nice set of video tutorials by +Hemanth Sharma to get you started with the starling framework:
http://youtu.be/RTvhZ8wbJaQ

if you don't use proprietary software like "flex builder", mind that you can set everything on the command line using the flex tools "mxmlc", "adl", "adb". i'm sure there are examples on how to do that online. flex is open source as is now maintained by the "apache software foundation".

--

Thursday, August 23, 2012

#threading and concurrency in flash player 11.4

the new flash player (as of 11.4) apparently now supports threads (and concurrency), exposed to the API via the Worker* / MessageChannel family of classes. the approach they took is actually similar to channels in GO, which is nice.

API examples:
Worker class

one slight inconvenience is that each time a worker / thread is created it has to exist in a separate SWF (ByteArray). this can be avoided if the actual SWF is created/loaded in/from memory.

a cool new feature, but it might be a little bit delayed in comparison to lets say Java, which became C/C++ like syntax multithreaded / "API exposed", i believe, since 1996 with JDK 1.0.

--

Thursday, June 28, 2012

#as3: callbacks for inter-object communication


[post is pending for a syntax/typo check]

in an almost non-coercive attempt, here goes a short explanation of something that has already been covered by people, perhaps much more competent than me on the specific subject. if you, at one point decided to tackle performance in as3 programming, you may have eventually bumped into the subject of memory management and whether to use the event system proposed by language specification.


the as3 event system is flawed, but certainly not that bad

going to low level programming as a distant reference, an event system does not exist until you create one as model or until the operation system's client library, somehow imposes one to you. there are various topics on this subject if the as3 event system is good or not, but it is certainly widely used, yet language experts seem to criticize it a lot, thus there are alternatives like: as3-signals, fingers, cjsignals.

when are callbacks a better alternative

in short, a callback is a function called by another function, when desired to pass an end result of some sort. when there are multiple instances of objects with hierarchy and inheritance, the as3 language specification suggest usage of the event system for communication between such. each time an event is dispatched memory is allocated for it to occupy and also there are possibly other function calls, assignments and overhead. even if garbage collection is as3 does a good job (to the extend you may not notice memory increase), why use the event system for really simple tasks in the first place?

consider a couple of display objects A, B, where A is parent to B (B instantiated in A).
the obvious way to communicate B -> A, would be to dispatch some sort of an event, signal or message (depending on the library you are using), but how about not creating any overhead and simply passing a data object, local to method in B as a parameter to method in A. if the object is small enough (and if AVM2 does a good job when doing stack handling) the lifetime of the object will span only trough the two methods and nothing will be ever allocated in memory (heap allocation). so basically what we are telling the VM (and before that the MIR optimizer and such) by doing this is in the rough lines of:

...
call method in B (call = )
do calculation in method (probably using the so called "local registers")
pack result into an object
push object on the stack
grab offset of method in A via a reference
call method in A (call = )
do calculation with the object (callproperty)

so no allocation and no overhead by multiple calls...but also, now consider having thousands of B instances.

here is an example using a "Delegate" object:

as3Delegate.zip


note that i advise against using "singleton" classes for inter-object communication with callbacks, unless such objects are "singletons" them self or there are no multiple instance considerations.

dynamic allocation of "enterFrame" callbacks

events such as ENTER_FRAME, that are called many times need allocation of many objects. i've read a couple of post related to the possibility of writing a different "enterFrame" and the authors have considered the method of creating a two frame MovieClip, which is basically stack-only dispatch of the event with callbacks, yet they don't find any memory or speed benefits. this is mostly, as mentioned due to the fact the GC in AVM2 is quite efficient and also due to the fact that modern machines are ridiculously fast:

http://alecmce.com/as3/replacing-enter_frame
http://blog.int3ractive.com/2010/07/myth-buster-enterframe-event.html

here is a small alternative (EnterFrame.as), which creates the two frame MovieClip dynamically instead of using library or meta data and has a much cleaner interface:

EnterFrameTest.zip

the code is based on ClipFactory by Denis Kolyako. ClipFactory is a nifty trick that creates a SWF in memory, appends a class which extends a MovieClip with a number of frames, loads the SWF, which then allows the class to be instantiated and addFrameScript() used on the frames.

EnterFrame has stop(), start(), setCallback(somemethod)


there are some drawbacks-to-callbacks

- not possible to make this work for native events such as mouse and keyboard actions, since as3 uses the event model strictly and does not provide alternatives. the criticism which was present in as2 due to a sparse implementation has turned into a restriction in as3.
- having only one centralised model for inter object communication is never a bad thing.
- closely related to the previous note, code obfuscation can become an issue when using callbacks, due to every programmer having a different naming conversation (this is a problem which an event / signal / message system certainly can solve quite well).


any event model does not cause stalls until proven guilty

and that pretty much sums it up, considering the cpu power available on the market currently. if you do not wish to optimize your message / event / signal passing method you can pretty much stay with the defaults, by proposal and if you find the interface comfortable enough, of course. in fact modern cpu are so fast that you may be hardly able to profile any code execution in research, thus leaving you with the question - "is it really worth it to even bother?".

--