/*****************************************************************************
 * File:  sys_init.c
 *
 * Description:
 * Main entrance and parameters of the wild thing...
 *
 * Notice:
 *   (C) Copyright 1999, 2000 ROX Software, Inc.
 *   All rights reserved.
 *
 * Model Compiler:  MC3020 V1.3.0
 *
 * Warnings:
 *   !!! THIS IS AN AUTO-GENERATED FILE. PLEASE DO NOT EDIT. !!!
 ****************************************************************************/

#include <stdlib.h>
#include "sys_init.h"
#include "e_mechs.h"
#include "e_events.h"
#include "e_objset.h"
#include "sys_user_co.h"
#include "A_dom_init.h"
#include "EXP_dom_init.h"

/*****************************************************************************
 * system-level domain dispatcher table
 * This table contains pointers to dispatcher tables for each of
 * the OOA domains generated for this system.
 ****************************************************************************/
static const DomainDispatcher_t DomainDispatcherTable[ 3 ] =
{
  0,
  (DomainDispatcher_t) A_DomainDispatcher,
  (DomainDispatcher_t) EXP_DomainDispatcher
};

extern void RunApplicationInitSequence( void );

static bool run_flag = true;

/*****************************************************************************
 * main process
 ****************************************************************************/
int
main ( int argc, char * argv[] )
{
  OoaEvent_t * event;

  /* Execute user supplied system initialization. */
  UserInitializationCallout();

  /* Execute generated system initialization phase. */
  SystemLevelInitialization();

  /* Execute OOA domain specific initialization phase(s). */
  ApplicationLevelInitialization();

  /* Execute application analysis initialization phase(s). */
  UserPreOoaInitializationCallout();   /* User supplied pre-init.  */
  RunApplicationInitSequence();        /* OOA init object states.  */
  UserPostOoaInitializationCallout();  /* User supplied post-init. */

  /* Start consuming events and dispatching background processes. */
  while ( run_flag )
  {
    /* Dispatch an OOA self directed event.  */
    if ( ( event = DequeueOoaSelfEvent() ) != 0 )
    {
      ( *DomainDispatcherTable[ GetEventDestDomainNumber( event ) ] )( event );
      Escher_DeleteOoaEvent( event );
    }  /* end self */
    else
    /* Dispatch one OOA non-self directed event.  */
    if ( ( event = DequeueOoaNonSelfEvent() ) != 0 )
    {
      ( *DomainDispatcherTable[ GetEventDestDomainNumber( event ) ] )( event );
      if ( GetFsmReleasesEvent( event ) ) {
        Escher_DeleteOoaEvent( event );
      }
    }  /* end non-self */

    /* Launch (interrupt) bridge actions that occurred during state.  */
    DispatchInterleaveBridge();

    /* User supplied background processing callout. */
    UserBackgroundProcessingCallout();
  }

  /* Shutdown phasing */
  UserPreShutdownCallout();
  ApplicationLevelShutdown();
  SystemLevelShutdown();
  UserPostShutdownCallout();

  return 0;
}
 
/*****************************************************************************
 * SystemLevelInitialization
 ****************************************************************************/
void
SystemLevelInitialization()
{
  /* Initialize the container pool. */
  Escher_SetFactoryInit();

  /* Initialize OOA event pool and queues. */
  InitializeOoaEventPool();
  InitializeOoaNonSelfEventQueue();
  InitializeOoaSelfEventQueue();
}

/*****************************************************************************
 * ApplicationLevelInitialization
 ****************************************************************************/
void
ApplicationLevelInitialization()
{
   /* Initialize all the domains */
  IntializeDomain_A();
  IntializeDomain_EXP();
}

/*****************************************************************************
 * SystemLevelShutdown
 ****************************************************************************/
void
SystemLevelShutdown()
{}

/*****************************************************************************
 * ApplicationLevelShutdown
 ****************************************************************************/
void
ApplicationLevelShutdown()
{
   /* Shutdown all the domains */
  ShutdownDomain_A();
  ShutdownDomain_EXP();
}

typedef void ( * interleaved_bridge_t )( void );
static interleaved_bridge_t interleaved_bridges[ SYS_MAX_INTERLEAVED_BRIDGES ];
static unsigned char interleaved_bridges_tail = 0;
/*****************************************************************************
 * InterleaveBridge
 * Post a bridge routine for execution after any executing state
 * action completes.
 * Protect the data structures from being clobbered by another context
 * by disabling interrupts around the data access.
 ****************************************************************************/
void
InterleaveBridge( void (vfp)(void) )
{
  /* disable interrupts */
  if ( interleaved_bridges_tail < SYS_MAX_INTERLEAVED_BRIDGES ) 
  {
    interleaved_bridges[ interleaved_bridges_tail++ ] = vfp;
  }
  /* enable interrupts */
}

/*****************************************************************************
 * DispatchInterleaveBridge
 * Sequentially execute each of the bridge routines that have been
 * posted during the most recent executing state action.
 * Protect the data structures from being clobbered by another context
 * by disabling interrupts around the data access.
 ****************************************************************************/
void
DispatchInterleaveBridge()
{
  unsigned char i = 0;
  /* disable interrupts */
  while ( i < interleaved_bridges_tail )
  {
    /* enable interrupts */
    interleaved_bridges[ i++ ]();  /* Bridge runs with interrupts enabled.  */
    /* disable interrupts */
  }
  interleaved_bridges_tail = 0;
  /* enable interrupts */
}