Author Topic: [v2.0]EventLibrary(ELIB) + musicdemo sample  (Read 9743 times)

0 Members and 1 Guest are viewing this topic.

Offline Conle

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2203
[v2.0]EventLibrary(ELIB) + musicdemo sample
« on: November 24, 2009, 11:25:24 PM »
Event Library is an advanced message system that can handle multiple events & callbacks
using stacks with fixed size.

Can be used by both apps & games where a complex message system is required.

I have added 3 samples(including ChillyWilly's Genesis music demo using ELIB) for coders
to see that this system is really stable & works.


Elib features ->
-Open source
-Does not uses any library at all(it's super portable!)
-Does not use function stacks
-Supports effects
-All important code is inlined using macros
-Static function allocator
-Stack based execution of commands
-No sorting or pointless data copying at runtime
-Can be used with platforms with limited hardware
-Supports debug handlers
-Configurable stacks
-Execution sync timer
-Supports custom handlers for input listener/host and timer
-Does not allocate/copy buffers  at runtime.
-Can convert values to proper message handlers
-Supports # amount of arguments per cycle ( # = defined in header )
-Supports # amount of total events per cycle ( # =  can be changed at runtime )
-The code is efficient and will not cause trouble to an existing project
-Efficient message system and even listener that gives you full control of the events
-Uses index ids for direct access to objects
-Fixed loops to active object's range


Native types/events/messages/defined types->


/*ELIB-Result*/
#define ELR_NEGATIVE (0)
#define ELR_POSITIVE (1)
#define ELR_ABORT (2)
#define ELR_QUIT (3)
#define ELR_COMPLETED_CYCLE (4)
#define ELR_INVALID (255)

/*ELIB-Type*/
#define ELT_SIGNAL (5)
#define ELT_EXCLUSIVE (6)

/*ELIB-Descriptor*/
#define ELD_CALLBACK (7)
#define ELD_INPUT_EVENT ( 8 )
#define ELD_MESSAGE (9)
#define ELD_MUTED (254)

/*ELIB-Key states*/
#define ELK_PRESSED (10)
#define ELK_RELEASED (11)

/*ELIB-Effects*/
#define ELF_FOCUS (12)
#define ELF_DELAY (13)
#define ELF_TIMED (14)
#define ELF_UNFOCUS (15)

/*ELIB-Constants*/
#define ELC_NEG (-1)


Data types ->
ELIB_Event,
ELIB_Effect,
ELIB_Input,
ELIB_Callback,
ELIB_Configuration,
ELIB_PublicConfiguration,
ELIB_PrivateConfiguration,
ELIB_FunctionArgumentStack,
ELIB_Regs,
ELIB_Runtime.


How to enable debug callback ->
Add this : #define ELIB_BUILD_WITH_DEBUG_CB on top of elib.h &rebuild


Code licence ->
MIT/X11


Credits->
ELIB & samples :: Conleon
MusicDemo :: ChillyWilly(Joe Fenton) & St├ęphane Dallongeville
MusicDemo ELIB events : Conleon

Minimal example ->
http://www.neoflash.com/forum/index.php/topic,5839.msg42025.html#msg42025

Downloads->
See the attachment
« Last Edit: July 17, 2011, 10:14:54 PM by Conle »

Offline Dr.neo

  • Administrator
  • Hero Member
  • *****
  • Posts: 3827
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #1 on: November 24, 2009, 11:51:24 PM »
cool, it's a great lib indeed!  >:D
In my world,have 0 and 1 only ......Matrix World......

Offline Conle

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2203
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #2 on: November 25, 2009, 12:07:39 AM »
Thanks  :D !

I also forgot to mention that "rom.bin" is the compiled rom of ChillyWilly's MD Music demo using elib for events.

The demo uses both block stacks & a batch of raw dynamic events for testing porpuses of course.
« Last Edit: November 25, 2009, 12:10:03 AM by Conle »

Offline ChillyWilly

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1751
  • Just a coding machine.
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #3 on: November 25, 2009, 01:03:39 AM »
 Nice! This is definitely one for the devkit.  ~sm-42.gif~

Offline Conle

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2203
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #4 on: November 25, 2009, 02:34:00 AM »
Nice! This is definitely one for the devkit.  ~sm-42.gif~

Cool :) !
Just need to balance something in the code first  ::sm-08.gif::

Offline Conle

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2203
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #5 on: November 26, 2009, 01:46:08 AM »
An update  ~sm-42.gif~

Like i said few days ago , i'm already working on the proper version  ^-^.

Here is a little example that shows how powerful this system is ->

Code: [Select]
ELIB_Configuration config;
config.iterationsPerCycle = 8;/*8 iterations / cycle*/
config.keyRepeat = ELR_POSITIVE; /*Key repeat?*/
config.syncTime = 60;/*60hz*/
config.handlerCB = myEventHandler;/*you can handle all events*/
config.timerCB = myTimer;
#ifndef ELIB_COMPILATION_MODE_SUPER_OPTIMIZED
config.debugCB = myDebugHandler;
config.targetCycles = 0;
#endif


if(ELIB_Init(&config) == ELR_POSITIVE)
{
/*test messages*/
ELIB_PushKey( UPKEY , ELK_PRESSED );
ELIB_PushKey( LEFTKEY , ELK_PRESSED );

ELIB_Effect effect;
effect.style = ELD_TIMED;
effect.value = 8;

ELIB_PushSignal(LEVEL_UP,myLevelUpHandler,&effect);
ELIB_PushExclusive(MONSTER_ATTACK,myMonsterAttackHandler,NULL);
ELIB_PushMessage(WAKE_UP);

ELIB_Effect effect2;
effect.style = ELD_TIMED;
effect.value = 16;

ELIB_PushTimed(QUEST_PICK_ALL_COINS_IN_16s,myQuestCallback,&effect2);

ELIB_Run();
}

This version contains all optimizations & its very stack-friendly.
It should be ready soon.

Of course you can send events at runtime.This is just a sample  ~sm-34.gif~
 ~sm-45.gif~

Oh and yes , this doesn't need both event listener & handler.
You can send events however you like without limits.
« Last Edit: November 26, 2009, 01:49:38 AM by Conle »

Offline Conle

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2203
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #6 on: November 26, 2009, 05:10:58 PM »
I have almost finished stackless generated code  ~sm-42.gif~.

Stackless means , that you can compile the library using a special define that will
remove all arguments/return values from Push*() functions and you can use some
dummy arguments of the configuration structure manually to set the internal arguments.

Also the library does not push anything to the stack at runtime.Everything is defined in the configuration structure , then the library uses that pointer for the internal tasks.

 ::sm-13.gif:: ::sm-12.gif:: ::sm-08.gif::

Offline Conle

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2203
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #7 on: November 30, 2009, 05:15:36 PM »
Here's some more information while im working on the proper version.

I did a test run , and here is some statistics....

Program :
Test sync

Description:
The program contains 1 static function callback( ELD_CALLBACK -> ELT_EXCLUSIVE ).
In this callback im pushing to the stack 16 events(signals) per call using ELIB_PushSignal()( ELD_CALLBACK -> ELT_SIGNAL ).
The stack size is 64(bytes => *sizeof(event structure)) long.

Statistics:
Code: [Select]
Sync/Time since last cycle/Iterations per Cycle/Program counter/Target PC/End PC/Stack pointer

SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0000, TPC = $0008 , EPC = $002a , SP = $0029
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0008, TPC = $0010 , EPC = $0039 , SP = $0007
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0010, TPC = $0018 , EPC = $0039 , SP = $000f
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0018, TPC = $0020 , EPC = $0039 , SP = $0017
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0020, TPC = $0028 , EPC = $0039 , SP = $001f
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0028, TPC = $0030 , EPC = $0039 , SP = $0027
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0030, TPC = $0038 , EPC = $0039 , SP = $002f
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0038, TPC = $0039 , EPC = $0039 , SP = $0037
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0000, TPC = $0008 , EPC = $0039 , SP = $0038
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0000, TPC = $0008 , EPC = $0008 , SP = $0007
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0008, TPC = $0010 , EPC = $0017 , SP = $0007
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0010, TPC = $0017 , EPC = $0017 , SP = $000f
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0000, TPC = $0008 , EPC = $0017 , SP = $0016
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0008, TPC = $0010 , EPC = $0026 , SP = $0007
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0010, TPC = $0018 , EPC = $0026 , SP = $000f
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0018, TPC = $0020 , EPC = $0026 , SP = $0017
SYNC = 160% , T = 0.006100 ,  IC = $08 , PC = $0020, TPC = $0026 , EPC = $0026 , SP = $001f

Explanation:
Cycle sync time is 60.

When sync is >= 100% it means that there is no delay at all.

And how does it runs so fast?
This is happening because the system never does full loops.Instead , it iterates only N times ( n = I/C ).

Take a look at PC and TPC.
On each cycle it is looping only between PC->PC + IC range until PC >= EPC.

And i have found another workaround to prevent sorting. The system moves the stack pointer to a muted
event instantly & that way we don't need sorting or to loop through the entries.

The last thing is , that im not using stack arguments for functions.Instead the system
uses its own "stack" and just copies over handles to the buffer.
« Last Edit: November 30, 2009, 05:23:35 PM by Conle »

Offline ChillyWilly

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1751
  • Just a coding machine.
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #8 on: December 01, 2009, 01:07:11 AM »
Interesting. The next version should be a hum dinger!

Offline Conle

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2203
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #9 on: December 01, 2009, 03:09:16 AM »
Well i have worked very hard on this library , you'll see what i mean soon  ~sm-42.gif~.

Basically the core functions are all inline macros since the library doesn't use functions/function stack arguments at all.

Yes im a bit crazy with speed , but this library aims for hardware with very limited cpu resources too. ::sm-11.gif::

By the way , i've written again the code for your music demo app.
To get an idea of what it can do , see this code ->

Code: [Select]
static void joyEvent(u16 joy, u16 changed, u16 state)
{
    //myData its just a normal structure passed as "user data"
    if (changed & state & BUTTON_START)
ELIB_PushMessage(config,PAUSE_RESUME);

    if (changed & state & BUTTON_A)
ELIB_PushMessage(config,STOP);

    if (changed & state & BUTTON_C)
ELIB_PushMessage(config,VSYNC);

    if ((changed & state & BUTTON_UP) && !(state & BUTTON_B))
    {
        sendAudio = 1;

myData.address = &Song1;
myData.length = &SSong1;
myData.pan = AUDIO_PAN_CENTER;
    }
    else if ((changed & state & BUTTON_RIGHT) && !(state & BUTTON_B))
    {
        sendAudio = 1;

myData.address = &Song2;
myData.length = &SSong2;
myData.pan = AUDIO_PAN_CENTER;
    }
    else if ((changed & state & BUTTON_DOWN) && !(state & BUTTON_B))
    {
        sendAudio = 1;

myData.address = &Song3;
myData.length = &SSong3;
myData.pan = AUDIO_PAN_CENTER;
    }
    else if ((changed & state & BUTTON_LEFT) && !(state & BUTTON_B))
    {
        sendAudio = 1;

myData.address = &Song4;
myData.length = &SSong4;
myData.pan = AUDIO_PAN_CENTER;
    }
    else if ((changed & state & BUTTON_UP) && (state & BUTTON_B))
    {
        sendAudio = 1;

myData.address = Song5;
myData.length = SSong5;
myData.pan = AUDIO_PAN_CENTER;
    }
    else if ((changed & state & BUTTON_RIGHT) && (state & BUTTON_B))
    {
        sendAudio = 1;

myData.address = &Song6;
myData.length = &SSong6;
myData.pan = AUDIO_PAN_CENTER;
    }
    else if ((changed & state & BUTTON_DOWN) && (state & BUTTON_B))
    {
        sendAudio = 1;

myData.address = &Song7;
myData.length = &SSong7;
myData.pan = AUDIO_PAN_CENTER;
    }
    else if ((changed & state & BUTTON_LEFT) && (state & BUTTON_B))
    {
        sendAudio = 1;

myData.address = &Song8;
myData.length = &SSong8;
myData.pan = AUDIO_PAN_CENTER;
    }

    if(sendAudio)
        ELIB_PushMessageEx(config,PLAY,&myData);
}

And here is how it handles the commands ->
Code: [Select]
ELIB_Handle eventHandler(ELIB_Event* event)
{
if(!event)
return ELR_NEGATIVE;

switch(event->type)
{
default:
return ELR_POSITIVE;

case ELD_MESSAGE:
{
switch(event->callback.message)
{
case PAUSE_RESUME:
{
paused = paused ? 0 : 1;
pausePlayback(paused);
return ELR_POSITIVE;
}

case STOP:
{
stopPlayback();
return ELR_POSITIVE;
}

case VSYNC:
{
vsync_on = vsync_on ? 0 : 1;
return ELR_POSITIVE;
}

case PLAY:
{
ELIB_MyUserData* data =  (ELIB_MyUserData*)event->userData;

stopPlayback();
startPlayback(*data->address, *data->length , data->pan);

return ELR_POSITIVE;
}

}

return ELR_POSITIVE;
}

case ELD_INPUT_EVENT:
{
/*Since keys are only executing specific events , we dont need to push keys!*/
/*if(event->key.state == ELK_PRESSED)
{
switch(event->key.code)
{
case ...
}
}*/
return ELR_POSITIVE;
}
}

return ELR_POSITIVE;
}

No matter how many events you push the program will never lag.
I've tried to call the render function as a signal( ->gets demoted instantly ) pushed on every frame and there is no difference at all.
« Last Edit: December 01, 2009, 03:11:22 AM by Conle »

Offline ChillyWilly

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1751
  • Just a coding machine.
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #10 on: December 01, 2009, 03:17:39 AM »
Yeah, that's really nice.  8)

Once you think it's ready, maybe we can work that into the menu. That would make the button handling cleaner (among other things).

Offline Conle

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2203
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #11 on: December 01, 2009, 03:28:26 AM »
Sure  :D.
It needs some more work but hopefully it should be available by the end of the week.
 ::sm-08.gif::

If you want to see some code (for suggestions etc) let me know  :)

Offline Conle

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2203
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #12 on: December 01, 2009, 10:41:34 PM »
Okay , here is a test version with a quick demo.

I have also included ChillyWilly's MD Music demo source file modified in order to
support ELIB & to look a bit better :D.
« Last Edit: December 07, 2009, 12:49:33 AM by Conle »

Offline ChillyWilly

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1751
  • Just a coding machine.
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #13 on: December 02, 2009, 02:10:13 AM »
I'll try to look this over today.  ::sm-29.gif::

Offline Conle

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2203
Re: EventLibrary(ELIB) + musicdemo sample
« Reply #14 on: December 02, 2009, 02:52:55 AM »
I'll try to look this over today.  ::sm-29.gif::

Just a little information on how it works ->

There is a small stack of events.
Events  can be callback or message-type events or anything custom event type.
Because the system supports "static functions" , there is a function rellocator index pointer , that pushes ELT_EXLUSIVE callbacks on the very bottom of the stack.

The stack pointer will not move beyond the static allocator's index , because this section is reserved and "sorts"(not really) the static functions only when they are pushed/popped to have both a stack & a static table in 1 single event table.

When you push an exclusive function , it is a bit expensive call if you have many messages because it involves swapping and some jumps, so push them when you create the interface or when you have to load some content.

Callback Signals/messages/keys can be sent instantly without limits.They get called/demoted instantly & move the stack pointer.

Each event is treated as an object that gets demoted/promoted depends
the case.

The loop is starting from the last -> first object to serve this porpuse.
Each cycle cannot call more than N(->config.Private.maxIterationsPerCycle) instructions.

The last address is moving to the very bottom of the stack pointer on each
"pop" but will never pass the static allocator.

The system does not "call" any function nor using the function stack.
All the critical code is inlined in macros & using the active configuration stack.

Now you're going to ask if its really just an event library.
The answer is no , its just a system that you can "push/pop"(not manually) events while doing some tasks just like a very basic cpu/state machine optimized just for this task.

 ~sm-41.gif~
« Last Edit: December 02, 2009, 03:05:41 AM by Conle »