-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement events (google code Issue 4) #46
Comments
what we currently have (alpha quality but working)
quickly implemented only in AS3 we basically use an infinite loop while( true )
{
// loop
} that we pause for N seconds we tested it with timers and it works fine while( running )
{
elapsed = getTimer() - started;
if( timerPending )
{
handleTimers();
}
sleep( 1000 / frequency );
frame++;
tick();
} |
following this logic we can add more to obtain a more complex loop while ( sleepuntil( nextEventTime ) OR externalEventOccured() ) {
...
if ( timerPending ) { // AS2 Intervals, AS3 Timers
handleTimers();
nextEventTime = nextTimerTime();
}
if ( localConnectionPending ) {
handleLocalConnection();
nextEventTime = min(nextEventTime , nextLocalConnectionTime());
}
if ( videoFrameDue ) {
decodeVideoFrame();
nextEventTime = min(nextEventTime , nextVideoFrameTime());
}
if ( audioBufferEmpty ) {
refillAudioBuffer();
nextEventTime = min(nextEventTime , nextAudioRebufferTime());
}
if ( nextSWFFrameDue ) {
parseSWFFrame();
if ( actionScriptInSWFFrame ) {
executeActionScript();
}
nextEventTime = min(nextEventTime , nextFrameTime());
}
if ( needsToUpdateScreen ) {
updateScreen();
}
...
} have cleaner events class, and all would be working fine but it would work only if you call that means if you want to use it would be nice to make it smarter and have the program wait |
so we focus on the command-line With Flash/AIR you would use workers Inside the command-line we can block forever
even worst, depending where you "block forever" for ex: trace( "hello world" );
var count:uint = 0;
while( true )
{
if( count > 10 )
{
exit( 0 );
}
count++;
}
// dead code
trace( "this will never happen" );
// this code will execute
Runtime.goAsync();
// this code may never execute we can document |
we could use the boot process or at least provide some configurations for that for ex: function autoAsync():void
{
if( Runtime.events.length > 0 )
{
Runtime.goAsync();
}
}
Program.atExit( autoAsync );
// from there write your code
// if somewhere you use only one addEventListener()
// then onExit() your program will automatically run goAsync() |
use what we learned from spitfire the source code is not open yet but we learned
how to build a more efficient event loop
we learned that an "infinite loop" can be controlled
from that we could deduce that if we sleep at least and if during each loop you keep track of the total number of frames you can calculate the private function _calcFPS( frames:uint, time:Number ):Number
{
var fps:Number;
fps = (frames/time) * 1000;
fps = int(fps*100)/100;
return fps;
} and define the public function set minDesiredFPS( value:uint ):void
{
if( value > 0 )
{
_minDesiredFPS = value;
_sleepTime = (maxFramePerSecond / (_minDesiredFPS - adjustFrame));
}
} eg. if you want a 24 FPS, you need how to mix event loop and workers If each event loop can control its own FPS that means when we use workers worker1 run at 24fps and child worker2 run at 8fps etc. but there we have another problem as we need to synchronise the threads (or workers) here what happen with a simple trace() call
see this line By locking the mutex you assure that for a trace() call you would do that _mutex.lock();
trace( message );
_mutex.unlock(); that way you are sure everything run smooth and synchronised
how to communicate between workers Remember with redtamarin we do not have events by default To do that we defined a our very dumb implementation reuse each you use it this way
it is a basic FIFO (First In, First Out)
it's basic, only simple types would be supported (eg. don't pass around a |
much more work is needed but so far we need to focus on
|
Hi edit: (document inlined)
|
Hey, First thing is about the google forum, it gonna change, all discussion should go on the Github issues. For the current
Before going into your proposal let underline some Redtamarin principle we try to follow
and few more like
On top of that, last month or something I worked on the server sockets and made Looking at your proposal you are under the impression that making this event loop native C++ would make everything faster by default, I don't completely agree with that. Sure C/C++ implementations are fast, but you can perfectly keep the whole logic in AS3 Let's take 2 examples:
I understand your proposal, people like the AS3 event system, they also like Node.js I get that, I want that too, but I'm not ready to sacrifice other things so I would say: "you don't want Redtamarin to be like Node.js" To answer your proposal
Now here few things that have not been made available yet in the Redtamarin API We have native timers, there are there, just not available in AS3 so you can have something like that
a dumb blocking timer in an "inifinite" loop but with a native timer you could have
and that would not be blocking, it use microseconds (even if not guaranteed) it's not bad at all you could even reuse Or even create a child worker just to run your event loop on the side For the record, I did some tests with a dumb blocking loop based on Also with Workers, the implementation in Redtamarin is not connected to events So, if I go into all those details is because I went trough those different road and yeah I know I put the "challenge" maybe a bit too high but considering your proposal, even if I appreciate a lot the proposal in itself but this for example I'm open to discussion but if it goes toward but please go ahead, maybe describe a bit more what you need ? |
Hi |
yep, it's possible, I did some tests on a concurrent socket server here some numbers
with that you can basically tell a loop class to either target a particular FPS
That's basically because we are blocking by default eg.
which is what I was calling the "way of doing"
It is possible, but there is another problem, from where in the program flow you always run goAsync worst case scenario is having some code in the middle of the flow if you want to call it right from the beginning to be sure that all events will be taken into account and if you want to call it at end, you can use
It can be done from the boot process without C++ well... we would probably need to add some support in the AS3 side for example:
so for now it's pretty basic, it would need to check an env var, or a file or other kind of entry Now, it's not really the real problem. boot.as
user code
or even simpler, in the My point is native timers could allow us to have a loop that is not blocking (I need to test that particular case) now about
we can not do that as it will block the program flow and so prevent us think also about case where your program block but it's not really an event or testing from the start of a program if we have command line arguments
interesting so I would say if you need that "right now" if you can wait a bit, let's say "about 2 months", supposed I can manage to have this right now one thing missing in the sockets C API is a way to go asynchronous
well you fit one of my use case ;) that's about what I'm working on right now but it is in the prototype phase
So to start with workers, the simple setup for concurrent socket connections This I tested, provided your main worker keep running your main server class will look like this
the main logic would be
in "condition to create child" it could anything really the child logic would be
now you need to mix that with socket connections
that's where it get complicated, because well all server loop are complicated usually on and you just add that id into an array, and your main loop You don't need to use workers, you can do it all like that but what happen if when a client connect and ¥ou need this client to do an action so an evil user could just connect and wait forever to DoS your server that's why you want to use Workers, so instead of blocking inside your main loop But now the evil is in the details, in fact you have 2 loop and for example if you need to deal with client timeout but if you wanted to deal with a client timeout from client side now the last part is being able to communicate between all those workers it is a bit crude but it works but the problem with that is you can not share data but you could as well create a connection between 2 child if you needed to so I basically pasted some prototype code, I'm working on improving all that |
Wow, thanks for all that! |
yes, and in fact because you also have AMF serialisation / deserialisation
not really, a socket server loop is a very good basic argument to promote the use of events I'm still in "R&D" for non-blocking main loop, I'll post here if I found something also, not for big/huge changes but Redtamarin is now considered in production mode |
FYI just on the use of events/loops for sockets (client-only for now), I've got this working with a single Worker that's handling all the connections and receiving the data, meant I needed it to put all sockets non-blocking (as I didn't want a worker per socket) so there was a tweak needed to get this working (no fcntl implementation). Out of interest, where we need a higher-level API to make it platform independent, are you okay with that being added to the C.sys.socket package? Currently I'm just hacking a bit in |
closed in favour of the meta issue #82 flash.events package |
https://code.google.com/p/redtamarin/issues/detail?id=4
implement the full event stacks based on W3C
goal:
have the same event system than Flash/AIR
but also allow to add a little more
so we gonna do that but cheat a little ;)
more details a bit later
The text was updated successfully, but these errors were encountered: