/* $Id: SignalEvent,v 1.1.1.1 2008/11/28 17:57:26 kiesling Exp $ -*-c-mode-*-*/

/*
  This file is part of ctalk.
  Copyright  2005-2008  Robert Kiesling, ctalk@ctalklang.org.
  Permission is granted to copy this software provided that this copyright
  notice is included in all source code modules.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*/

/*
 *   SignalEvent Class
 */

Event class SignalEvent;

SignalEvent classVariable pendingEvents List NULL;
SignalEvent classVariable signalEventClassInitDone Integer 0;

SignalEvent instanceVariable processID Integer 0;
SignalEvent instanceVariable sigNo Integer 0;
SignalEvent instanceVariable text String NULL;

SignalEvent classMethod classInit (void) {

  OBJECT *classObject, *classInitVar, *__pendingEventsVar, 
    *tmp_var;

  if (self signalEventClassInitDone)
    methodReturnNULL

  classObject = __ctalkGetClass ("SignalEvent");

  /*
   *  Ctalk might initialize the pendingEvents List with 
   *  at least a value instance variable.  Remove the 
   *  instance variables so pendingEvents behaves
   *  like a normal List.
   */
  
  if ((__pendingEventsVar = 
       __ctalkGetClassVariable (classObject, "pendingEvents", FALSE))
      == NULL)
    methodReturnNULL

  for (tmp_var = __pendingEventsVar -> instancevars; 
       tmp_var && tmp_var -> next; tmp_var = tmp_var -> next)
     ;
  if (tmp_var) {
    do {
      if (tmp_var -> prev) {
	tmp_var = tmp_var -> prev;
	__objRefCntSet (&(tmp_var -> next), 0);
	__ctalkDeleteObject (tmp_var -> next);
      }
      tmp_var = tmp_var -> prev;
    } while (tmp_var && (tmp_var != __pendingEventsVar -> instancevars));
    __objRefCntSet (&(__pendingEventsVar -> instancevars), 0);
    __ctalkDeleteObject (__pendingEventsVar -> instancevars);
    __pendingEventsVar -> instancevars = NULL;
  }

  classInitVar = 
    __ctalkCreateObjectInit ("signalEventClassInitDone", "Integer",
				"Magnitude",
				classObject -> scope, "1");
  __ctalkAddClassVariable (classObject, "signalEventClassInitDone", classInitVar);

  methodReturnNULL
}

SignalEvent instanceMethod new (char *__signalEventName) {
 
  OBJECT *__pendingEventList, *__class_object;

  SignalEvent super new __signalEventName;

  __ctalkInstanceVarsFromClassObject (__signalEventName);

  SignalEvent classInit;

  methodReturnObject(__signalEventName)
}

SignalEvent instanceMethod queueEvent (void) {

  OBJECT *__self_object, *__pendingEventList, *__t;

  __self_object = __ctalk_self_internal ();

  __pendingEventList = SignalEvent pendingEvents;

  for (__t = __pendingEventList; __t && __t -> next; __t = __t -> next)
    ;

  __t -> next = __self_object;
  __self_object -> prev = __t;
}

SignalEvent instanceMethod nextEvent (void) {

  OBJECT *__pendingEventList, *__t;

  __pendingEventList = SignalEvent pendingEvents;


  if (!__pendingEventList -> instancevars)
    methodReturnNULL

  if ((__pendingEventList -> instancevars -> next == NULL) &&
      (__pendingEventList -> instancevars -> prev == NULL)) {
    __t = __pendingEventList -> instancevars;
    __pendingEventList -> instancevars = NULL;
    return __t;
  }
    
  for (__t = __pendingEventList -> instancevars; __t && __t -> next; 
       __t = __t -> next) {
    if (!strcmp (__t -> __o_classname, "SignalEvent")) {
      if (__t -> next) { __t -> next -> prev = __t -> prev; }
      if (__t -> prev) {__t -> prev -> next = __t -> next; }
      __t -> next = __t -> prev = NULL;
      return __t;
    }
  }

  methodReturnNULL
}

SignalEvent instanceMethod = set_value (SignalEvent __event) {
  OBJECT *__self_object, *__pid_var, *__signo_var, *__data_var;

  __self_object = __ctalk_self_internal ();

  __signo_var = __ctalkGetInstanceVariable (__event, "sigNo", FALSE);
  __pid_var = __ctalkGetInstanceVariable (__event, "pid", FALSE);
  __data_var = __ctalkGetInstanceVariable (__event, "data", FALSE);
  if (__signo_var) 
	__ctalkAddInstanceVariable (__self_object, "sigNo", __signo_var);
  if (__pid_var)
	__ctalkAddInstanceVariable (__self_object, "pid", __pid_var);
  if (__data_var)
  	__ctalkAddInstanceVariable (__self_object, "data", __data_var);

  methodReturnSelf
}

SignalEvent instanceMethod getPID (void) {

  self addInstanceVariable "processID", getpid ();

  methodReturnSelf
}

SignalEvent instanceMethod pending (void) {

  OBJECT *__pendingEventList, *__t;

  returnObjectClass Integer;

  __pendingEventList = SignalEvent pendingEvents;

  for (__t = __pendingEventList -> instancevars; __t; __t = __t -> next) {
    if (!strcmp (__t -> __o_classname, "SignalEvent")) {
      methodReturnTrue
    }
  }
  
  methodReturnFalse
}

