<'
# Copyright (c) 2011-2015, 2017, 2025-2026 LAAS/CNRS
# All rights reserved.
#
# Redistribution and use  in source  and binary  forms,  with or without
# modification, are permitted provided that the following conditions are
# met:
#
#   1. Redistributions of  source  code must retain the  above copyright
#      notice and this list of conditions.
#   2. Redistributions in binary form must reproduce the above copyright
#      notice and  this list of  conditions in the  documentation and/or
#      other materials provided with the distribution.
#
#                                      Anthony Mallet on Thu Mar  2 2012
#

args components
lang c
'>
#ifndef H_GENOM_ACTIVITY
#define H_GENOM_ACTIVITY

#include <assert.h>
#include <stddef.h>

#include "activity-data.h"		/* must be provided by template */
#include "parameters-c.h"

/* forward declarations */
struct genom_activity_data;
<'foreach c $components {'>
struct genom_<"[$c name]">_exec_task;
struct genom_<"[$c name]">_component;
<'}'>

#ifndef GENOM_MAX_ACTIVITIES
# define GENOM_MAX_ACTIVITIES	(16)	/* arbitrary */
#endif


/* --- generic activity ---------------------------------------------------- */

enum genom_activity_status {
  ACT_VOID,	/* nothing */
  ACT_INIT,	/* in control task codels */
  ACT_RUN,	/* managed by exec task, running */
  ACT_STOP,	/* managed by exec task, stopping */
  ACT_ETHER	/* result available for control task */
};

enum genom_activity_event {
  ACTEVT_EXEC  = 1<<0,	/* some codels were run */
  ACTEVT_MORE  = 1<<1,	/* more codels need to run */
  ACTEVT_ETHER = 1<<2,	/* some activity reached ether */
};

struct genom_activity {
  int sid;				/* service number (-1 perm act) */
  int aid;				/* activity number */
  void *task;				/* task or NULL (ctrl) */
  struct genom_activity_data mw;	/* template-specific data */

  enum genom_activity_status status;	/* current phase */
  int start, stop, pause;		/* status change request */
  genom_event state;			/* current FSM state or exception */

  const void *exdetail;			/* exception info, if any */
  const char *interruptedby;
};

static inline void
genom_tinit_activity(struct genom_activity *a)
{
  assert(a->status == ACT_VOID);
  a->status = ACT_INIT;
  a->start = a->stop = a->pause = 0;
}

static inline void
genom_tfini_activity(struct genom_activity *a)
{
  assert(a->status != ACT_VOID);
  a->status = ACT_VOID;
}

<'foreach c $components {'>
<'  set comp [$c name]'>
<'  foreach s [$c services] {'>
/* <"[--- $comp =========================================================]"> */


/* <"[--- [$s kind] [$s name] -------------------------------------------]"> */

/* activity data */
struct genom_<"$comp">_activity_<"[$s name]"> {
  struct genom_activity h;		/* common data */
  void (*donecb)(			/* reply function */
    struct genom_<"$comp">_activity_<"[$s name]"> *,
    struct genom_<"$comp">_component *);
  struct genom_<"$comp">_svc_<"[$s name]">_params params; /* service params */
};

static inline void
genom_tinit_<"$comp">_activity_<"[$s name]">(
  struct genom_<"$comp">_activity_<"[$s name]"> *a)
{
  genom_tinit_activity(&a->h);
  a->donecb = NULL;
  genom_tinit_<"$comp">_svc_<"[$s name]">_params(&a->params);
}

static inline void
genom_tfini_<"$comp">_activity_<"[$s name]">(
  struct genom_<"$comp">_activity_<"[$s name]"> *a)
{
  genom_tfini_activity(&a->h);
  genom_tfini_<"$comp">_svc_<"[$s name]">_params(&a->params);
}

<'  }'>

/* <"[--- $comp activities ----------------------------------------------]"> */

union genom_<"$comp">_activity_any {
  struct genom_activity any;
<'  foreach s [$c services] {'>
  struct genom_<"$comp">_activity_<"[$s name]"> <"[$s name]">_;
<'  }'>
};

struct genom_<"$comp">_activities {
  union genom_<"$comp">_activity_any a[GENOM_MAX_ACTIVITIES];
  struct genom_activity *permanent;	/* points inside above array */
};

int	genom_<"$comp">_activities_init(
  struct genom_<"$comp">_activities *activities);
int	genom_<"$comp">_activity_alloc(
  struct genom_<"$comp">_activities *activities);
int	genom_<"$comp">_activities_startup(
  struct genom_<"$comp">_component *self);
int	genom_<"$comp">_activities_ctrl(
  struct genom_<"$comp">_component *self);
enum genom_activity_event
	genom_<"$comp">_activities_exec(
          struct genom_<"$comp">_exec_task *task, int ontick,
          enum genom_activity_status (*invoke)(
            union genom_<"$comp">_activity_any *,
            struct genom_<"$comp">_component *),
          struct genom_<"$comp">_component *self);
void	genom_<"$comp">_activities_shutdown(
  struct genom_<"$comp">_component *self);
void	genom_<"$comp">_activity_report(
  union genom_<"$comp">_activity_any *a, struct genom_<"$comp">_component *self);
int	genom_<"$comp">_interrupt_other(struct genom_activity *a,
                struct genom_<"$comp">_component *self);

<'}'>

#endif /* H_GENOM_ACTIVITY */
