Example event system in AS3


#1

Ok, I don’t want to unproductively argue abut how flash events system works as it started in this topic. If whole team of people can’t convince you than I don’t know what I could say.
So, as I prommised, I wrote example implementation in nude AS3 that mimics original flash.Events.
Here it is.

Structure:

The whole base of event system is 5 files (2 actually essential):

  • Event.as - base class for all events.
  • EventDispather.as - the “brain” of the system which manages listeners and event dispatching.
  • EventPahse.as - just 3 const for event phases.
  • IEventDispatcher.as - dispatcher interface. Not really necessary here but original EventDispatcher implements it and it’s really just “copy-paste” so…
  • eIternal.as - single line internal namespace declaretion used in events package.

And that’s it. It’s about 200 line of code and you already can use it just as you would do it with flash events.
It’s not full implementation but it gives core functionality and should give an idea on how this works. The code is not commented because it would take more time than actually writing the code and I would be basically rewriting the same thing you can read on adobe pages, while my point is only to just show you the mechanism.

So we probably want to test it but let first clarify some things…

What I understand as asynchronous code?

For me this means that when I have following code:

var v = 10;
trace(v); 

I cannot quaratee you that secound line will output 10 because there is some other context running in paraller that can change v to some other value.
This however never happens in flash, no matter if or what events you are using. If you can give me an example of something like this happening then I could agree that events are asynchronous but otherwise I uphold my sentence that:

Core Event system is synchronous.

But how you can have frame events and different timers running in parallel if events suppose to be synchronized you would ask?

Yes you can design different contexts running independently, with any technique you like, and use events to communicate between them, but this doesn’t mean than events themselves implement any kind of asynchronous context creation.

Dispatching an event simply works just as calling a function except you don’t do it directly and dispatcher can call any number of previously registered functions for you i.e.

basic.dispatchEvent(new Event(Event.CHANGE));
trace("This line will never be executed before all registered listeners return");

How timer class would look like?

package adnss.projects.evTest 
{
	import adnss.common.events.Event;
	import adnss.common.events.EventDispatcher;
	import flash.utils.setInterval;
	/**
	 * ...
	 * @author Audionysos
	 */
	public class Timer extends EventDispatcher
	{
		/**Current interval id.**/
		private var _currInt:uint;
		
		public function Timer() {}
		
		public function start(fps:Number) {
			_currInt = setInterval(dispatch,1000/fps);
		}
		
		private function dispatch() {
			this.dispatchEvent(new TimerEvent(TimerEvent.TIMER));
		}
	}

}

and now in your main class you can listen to this just as usual:

public function Main() {
	var frameRendering:Timer = new Timer();
	frameRendering.addEventListener(TimerEvent.TIMER, myRenderingLoop);
	frameRendering.start(30);
}

private function myRenderingLoop(e:TimerEvent):void {
	trace("Yo", someVarToChange++);
}  

You really need something like setIterval(). If you tell me that this is not included in Tamarin then I’m surprised - I thought it suppose to be native JS functionality.
How to implement setInterval in C? You tell me… The only thing I know at the moment is that in small microcontrollers you don’t care about such thing and simply write while(true) but you blocking whole core by that and this is whole another topic…

Again, the job of EventDispatcher is simple:

  • Hold all given functions references with association to event type that they suppose to be called on.
  • When someone call your dispatchEvent, search for all associations that match a given event type and call associated function.

And that’s it! All other things is just sugar to that.

Source

Download it here and extract.

The source contains also a little more complex example of using events - go to Main.as and read the doc.
Files structure is just copied piece of my setup so it could look weird but it’s simple.

  • flash/blank.fla - Adobe Flash CS 5.5 project file (simply open, ctrl+enter and you shoud see test result in “Output” view)
  • libs/adnss/common/events - The whole event system is located here.
  • liba/projects/evTest - test project code (Main.as here)

Cracking Up The Event Loop
#2

If everyone is telling you “you are wrong” that does not mean you are actually wrong.


Could you make your source code available online like Github or other repository ?


Also, I have a problem with that part

public function start(fps:Number) {
    _currInt = setInterval(dispatch,1000/fps);
}

You do realise that the setInterval() function is implemented internally with flash.utils.Timer ?

it is implemented like that

package flash.util
{
	import flash.events.*;
	import flash.display.*;
	import flash.system.*;
	
/**
 * @private
 * SetIntervalTimer is a private class used to implement
 * the setInterval, clearInterval, setTimeout and
 * clearTimeout functions.  It should not be documented,
 * and is internal to the flash.util package.
 */
class SetIntervalTimer extends Timer
{
	public function SetIntervalTimer(closure:Function,
									 delay:Number,
									 repeats:Boolean,
									 rest:Array)
	{
		super(delay, repeats ? 0 : 1);
		this.closure = closure;
		this.rest = rest;
		addEventListener(TimerEventType.TIMER, onTimer);
		start();

		id = intervals.length+1;
		intervals.push(this);
	}

	private function onTimer(event:Event):Void
	{
		closure.apply(null, rest);
	}

	static function clearInterval(id:uint):Void
	{
		id--;
		if (intervals[id] is SetIntervalTimer) {
			intervals[id].stop();
			delete intervals[id];
		}
	}

	var id:uint;
	private var closure:Function;
	private var rest:Array;
	
	private static var intervals:Array = [];
}

public function setInterval(closure:Function,
							delay:Number,
							... arguments):uint
{
	return new SetIntervalTimer(closure, delay, true, arguments).id;
}

So I don’t want to unproductively argue either but, to me, using setInterval() defeat the purpose of not using the native events.


ActionScript: The Definitive Guide
Chapter 10. Events and Event Handlers

10.1. Synchronous Code Execution

As a movie plays, the timeline’s playhead travels from frame to frame. Each time the playhead enters a new frame, the interpreter executes any code attached to that frame. After the code on a frame has been executed, the screen display is updated and sounds are played. Then, the playhead proceeds to the next frame.

For example, when we place code directly on frame 1 of a movie, that code executes before the content in frame 1 is displayed. If we place another block of code on a keyframe at frame 5 of the same movie, frames 1 through 4 will be displayed, then the code on frame 5 will be executed, then frame 5 will be displayed. The code executed on frames 1 and 5 is said to be executed synchronously because it happens in a linear, predictable fashion.

All code attached to the frames of a movie is executed synchronously. Even if some frames are played out of order due to a gotoAndPlay( ) or gotoAndStop( ) command, the code on each frame is executed in a predictable sequence, synchronized with the movement of the playhead.

and

10.2. Event-Based AsynchronousCode Execution

Some code does not execute in a predictable sequence. Instead, it executes when the ActionScript interpreter notices that one of a predetermined set of events has occurred. Many events involve some action by the user, such as clicking the mouse or pressing a key. Just as the playhead entering a new frame executes synchronous code attached to the frame, events can cause event-based code to execute. Event-based code (code that executes in response to an event) is said to be executed asynchronously because the triggering of events can occur at arbitrary times.

Synchronous programming requires us to dictate, in advance, the timing of our code’s execution. Asynchronous programming, on the other hand, gives us the ability to react dynamically to events as they occur. Asynchronous code execution is critical to ActionScript and to interactivity itself.

This chapter explores asynchronous (event-based) programming in Flash and catalogs the different events supported by ActionScript.

Everything that is generated by the system, or by the user, etc. is not predictable
like keyboard events, mouse events, touch events, etc.

Same for I/O with file system data, network data, etc.
for example: you can not predict when you will receive socket data.


#3

Yes, but I was saying that if you are wrong and 10 people culdn’t convincie you then it is unlikely that I will to it :wink:

Sorry, I’m not using any kind of repository now. But eventually I would use some, when it’s done. Is it that painfull to extract archive?

####10.1. Synchronous Code Execution

As a movie plays, the timeline’s playhead travels from frame to frame. Each time the playhead enters a new frame, the interpreter executes any code attached to that frame. After the code on a frame has been executed, the screen display is updated and sounds are played. Then, the playhead proceeds to the next frame.

For example, when we place code directly on frame 1 of a movie, that code executes before the content in frame 1 is displayed. If we place another block of code on a keyframe at frame 5 of the same movie, frames 1 through 4 will be displayed, then the code on frame 5 will be executed, then frame 5 will be displayed. The code executed on frames 1 and 5 is said to be executed synchronously because it happens in a linear, predictable fashion.

All code attached to the frames of a movie is executed synchronously. Even if some frames are played out of order due to a gotoAndPlay( ) or gotoAndStop( ) command, the code on each frame is executed in a predictable sequence, synchronized with the movement of the playhead.

Isn’t this referring to having AS3 code on MovieClip frames in Flash/Animate timeline?

####10.2. Event-Based AsynchronousCode Execution
Some code does not execute in a predictable sequence. Instead, it executes when the ActionScript interpreter notices that one of a predetermined set of events has occurred. Many events involve some action by the user, such as clicking the mouse or pressing a key. Just as the playhead entering a new frame executes synchronous code attached to the frame, events can cause event-based code to execute. Event-based code (code that executes in response to an event) is said to be executed asynchronously because the triggering of events can occur at arbitrary times.

Synchronous programming requires us to dictate, in advance, the timing of our code’s execution. Asynchronous programming, on the other hand, gives us the ability to react dynamically to events as they occur. Asynchronous code execution is critical to ActionScript and to interactivity itself.

This chapter explores asynchronous (event-based) programming in Flash and catalogs the different events supported by ActionScript.

How is this suppose to be contradictory with the thing I already said? Again, I don’t know what other words I could use:

Yes, And who said that user click is predictable?
It’s not predictable, but just beacuse you recieve an event when it happens that doesn’t mean the click is caused by the event.

Actually I didn’t. Where did you get this code from?
That’s interesting but it really doesn’t impact events model as Timer extends EventDispatcher only to dispatch events. That doesn’t mean events implement any kind of interval mechanism.
Show me how you can set an interval with only EventDispatcher class and I would believe you.

But no matter what is going on under the hood of FP, I just showed you how you can have interval and event as separate concepts. Did your run the code?

[quote=“zwetan, post:2, topic:611”]
So I don’t want to unproductively argue either but, to me, using setInterval() defeat the purpose of not using the native events.[/quote]

If you are asking me why I wanted to reimplement the Event model, the answer is simple:

  1. I want to have more control over it.
  2. To possibly improve performance
    • Like I mentioned earlier - I don’t see any reason why to create separate Event instances for each listener that are listening the same event.
    • I don’t see reason why (well, I have guess why, but the behaviour is not desired) when I’m redispatching the event that I’m currently receiving, it’s cloned.
    • I didn’t mentioned it but my version is actually using uint variable as an event’s type class instead of String.
    • etc.

#4

we are done here

if you don’t get what I’m saying at this point I see no purpose to continue

good luck :slight_smile:


#5

Sure, quote single sentence pulled out of context that makes me look stupid and end the conversation.

Well, then good luck for you too :slight_smile:


#6

OK you want context sure no problem

That’s interesting but it really doesn’t impact events model as Timer extends EventDispatcher only to dispatch events. That doesn’t mean events implement any kind of interval mechanism.

just that tell me you have no clues whatsoever how events are working

by using setInterval() in your code you are relying on the native event loop,
remove setInterval() and your event system stop working.

It is as simple as that but apparently you need some kind of proof to believe me.

I personally don’t care but you kind of came to me with
“look I gonna show you how to implement en event system that does not need the native events to work”

no, it doesn’t work like that
I did try to explain it to you but you are completely ignoring all of it

so …
¯\_(ツ)_/¯


#7

I’m am ignoring? I have a feeling that you only read half of things I write and other half you construct form your imagination…

So answer simple questions:

  1. From where setInterval() is called?
  2. What really stops working whe you remove it? EventDispatcher or rather the Timer?
  3. If you say that EventDispatcher then how is this possible that trace("cout:", i); is executed?

You are just confusing 2 separate concepts as one thing. The example is just to demonstrate that you can use the same event system in both synchronous and asynchronous contexts.

Saying that events are asynchronous is like saying that functions are asynchronous - because function is called when users press mouse button and it can happen at any time. Oh, and there is a mysterious “function loop” that handles calling functions in regular intervals and without this loop the functions itself cannot exist.

Do you see how ridiculous this sound? Sorry, but that is basically the same as thing you are saying.

You say I have no clue about how events work but so far I have code that could replace native events in most of places I’ve ever used custom events. And I spend much less time on this then on just trying to explain it to you…

Would you be happy if I would say that you are right and I’m wrong?


#8

I tell you what,

launch Adobe Scout, run your code
follow the setInterval() in the code stack

see

if you see some flash.events.* classes
like EventDispatcher, Event, TimerEvent, etc.

that would mean your event system has the native event system as a dependency

if at the contrary you see no flash.events.* classes
that would mean you successfully implemented a truly independent event system

it is a good experiment, at least to prove it to yourself :slight_smile:

so far I do believe that setInterval is using the native event system
eg. the interval is triggered by the main event loop

a bit like sayin’

Yo dawg, I know you like events
so I used events to implement events

I told ya right from the start that an event system was something complicated

anyway check it out in Adobe Scout, you will get all your answers there


#9

I never said that setInterval is not using events. It can use them but how this leads you to conclusion that my events use native events? You won’t find anywhere in my .events package, any use of flash API. Read my previous post again.

I don’t what to attack you but your try to make me look stupid on public forum…

I don’t know what is confusing you so much about it but It seem to me that you’ve lost any kind of concentration.
How you suppose to follow what I’m saing if you can’t even track what you do by yourself?
Look at your attempt of EventDispatcher implementation:

Do you seriously think there is some mysterious force that will set your obj to null between those lines?

Come on… Give yourself a break for few days, get some sleep. Accept the fact that we are fallible beings and your are not an exception. Read again our whole conversation. Slow down for a moment and try to really understand things and not just pick random guess. Don’t assume that everything that is not compatible with your belief is wrong.

If you have Flash/Animate, start debug session, stop the execution on first line and track every single instruction - Yes, you can stop execution even if you have setInterval involved and it really stops…
Read again our whole conversation. Delete your code of event’s and try implement it again from blank page.
Read again our whole conversation (I’m actually reading many things you write few time before I respond)

Then we can try to talk…


#10

nope :slight_smile:

I don’t need to talk to you
the same I don’t need to use your code
or to spend any more time on all that

all the fluff you are sending my way is, at best, a distraction

I made the mistake of spending time answering to you
instead of using that time to write more code, documenting code
and all the stuff I usually do with my time spent on open source projects


now for the sake of people that may have followed this convo
and may think WTF is going on here ?

it all started here
2017 Going Rogue

where Pawel showed interest into the Redtmaarin project
and where I pointed him to How To Contribute

then the conversation continued here
Some questions about Redtamarin

where Pawel mention

My point is that I’ve seen for example you mentioned about w reimplementing Events system

and propose

So If I would write my own event system I don’t see any reason to not share it so you wont waste time on this again, unless you really want to write everything by yourself

OK great, to me it look like someone who want to contribute to an open source project

and the convo continued in yet a 3rd thread here
Example event system in AS3

where Pawel claims

I wrote example implementation in nude AS3 that mimics original flash.Events.

and end up with

Download it here and extract.

someone did not not read the How To Contribute where we give a bunch of advices, for example

If you never worked with an open source project before, learn the basics of checkout, commit, merge, pull requests, diff, patch, etc. — we can not do that for you.

Pawel decided that it somehow does not apply to him, instead he put a *.rar file on mediafire and we have to “download and extract” and then he will help us understand.

and from there it has been all about arguing and deflecting

Could you make your source code available online like Github or other repository ?

Sorry, I’m not using any kind of repository now. But eventually I would use some, when it’s done. Is it that painfull to extract archive?

It’s not that it’s painful to do it, but first Pawel is completely ignoring the process and advice given to him, and second I personally not gonna open a *.rar file sent by some stranger because I do know all the bad things you can do with that (embedding payload in RAR/ZIP/JPG/PNG get you Virus RAT, KeyLogger, etc.).

Yeah it is about trust as pointed again in the “How To Contribute”

It is about trust
you have to make the effort for us to trust you
and to do that you need to listen, understand and probably learn

And when I see this type of behaviour, even if I don’t jump to the conclusion right away that “Pawel is a bad guy” and not even thinking he tried to send me a virus embedded into a *.rar file, I still see a tell.

A “tell” (like in poker) as some kind of behaviour I have already seen before, and that make me think of that How Open Source Projects Survive Poisonous People (Youtube).

And as a developer, even without going into the rar file, just looking at the few code examples in the post I saw that famous setInterval, and yeah because I decompiled numerous times playerglobal.abc and peek into that to get an idea at how native events were implemented I pointed that out.

Why would I spend the time to review some code that do not follow the process of diff/patch/PR when I already know that using setInterval is a dead-end because it uses Timer and the TimerEvent is based on the native event system, not really a good use of my time.

But I still tried to explain it to Pawel and here we are, call that poisonous, call that trolling, whatever …

first this

here Pawel is positioning himself as the “victim”, I’m apparently the bad guy who try to make him look stupid, ORLY?

and then follow this

that’s textbook poisonous behaviour.

I’m not sure what you are trying to do here Pawel, but it not gonna work.

again in the “How To Contribute”

It is about source code
sure we can talk, argue, whatever about how this or how that,
but at the end of the day what really matters is the code

You claim that your event system is mimicking the native event system and does not rely on it
OK, good on you, keep using your event system for whatever you want.

Me, I’m telling you I’m not gonna use it
and certainly not integrate it in the Redtamarin code base

Why? because we can not rely on setInterval or the native event system of Flash/AIR
we don’t have that in Redtamarin, we have to implement it from scratch
you are not contributing nor helping here

So, Pawel, you had my attention for some time, you don’t have it anymore
please do try to contribute in a positive way to any other community and/or open source project.

And again good luck :slight_smile:


#11

You’ve been rude to me since your second response so please don’t tell me about poisonous people…

Somehow you wrongly assumed that this example suppose to be contribution to Redtamarin.
It suppose to be showcase for people who wonder how event could be implemented under the hood.
Here is my summary of our coversation:

  • Me: Hey, I like the idea of your project. I see you need implementation of events. I got it on my TODO list also, I could give it some more priority and share it to you.

  • Zwetan: No, you can’t do It, you don’t know how it works.

  • Me: I can’t do it? …here it is! Look on this quick example of key event functionally.

  • Zwetan: You have no clue how it works, events can’t exist without intervals… Sorry, I’m not going to use your code.

Do you believe that getting help from me is your mercy towards me? I must disappoint you - I’m not going to cry for the fact that you don’t want use my code.

If you want to write it by your own it’s cool - implement asynchronisation in EventDispatcher and don’t forget to include other core functionalities like user interrupts and network connection in on huge class… Sure, you can do it but it’s going to be horrible design.


#12

zwetan, you could replace setInterval with new MovieClip / addFrameScript, no ?


#13

ah, crap, it was for red tamarin

The thing is implementing an event system natively in C/C++ can be complicated
look at issue #82 flash.events package and the subtopics, it can get very complicated real fast.

first problem
“as is” the AVM2 or redtamarin code context does not have a mechanism to handle frames,
there are some mention of it in the source code, but right now we have only one code context
which we can consider global or “only 1 frame”.

Flash/AIR can have different code context when moving from one frame to another,
that’s the Event.ENTER_FRAME, Events.EXIT_FRAME, etc.


#14

not really, I see all of this in the context of Redtamarin, and there, as much as there is no setInterval(), there is also no addFrameScript(), in fact there are no frames

all the niceties and automated stuff that the Flash Player is doing under the hood like addFrameScript()

see for example
Mommy, where do framescripts come from?

package DecompileMe_fla
{
    import flash.display.*;
 
    dynamic public class MainTimeline extends MovieClip
    {
 
        public function MainTimeline()
        {
            addFrameScript(0, frame1, 1, frame2, 2, frame3);
            return;
        }// end function
 
        function frame3()
        {
            var _loc_1:String;
            _loc_1.this["frame2"]();
            return;
        }// end function
 
        function frame1()
        {
            gotoAndStop(3);
            return;
        }// end function
 
        function frame2()
        {
            trace("I am a script on frame 2");
            return;
        }// end function
 
    }
}

we don’t have that in Redtamarin, we have to build it all from scratch

a lot of stuff is explained in greater details here
flash.events package #82