// eventOut.C

#include "nodeInterface.H"
#include "world.H"

namespace xrml {

void eventOut::init(class eventOut *ref)
{
  init((char *)ref->Id, ref->value);
  timestamp = ref->timestamp;
}

interfaceMember* eventOut::clone(void)
{
  eventOut *e = new eventOut(*this);
  routing_table::clone(e);
  return e;
}

void eventOut::instantiate(class SFNode*, class Proto* master)
{
  routing_table::instantiate(master);
}

void eventOut::post(class SFNode *thisnode, const fieldValue& value)
{
  // no something like 'post_forward' here: posting is only along
  // backward links.
  if (!check_type(value))
    return;	// type mismatch

  this->value = value;	  // only the pointer to the value is copied.
  if (timestamp < thisnode->world->time)
    // route only once at each instance
    thisnode->world->postEvent(thisnode, this);

  timestamp = thisnode->world->time;
}

void eventOut::dispatch(void) const
{
  routing_table::dispatch(value);
}

void eventOut::add_route(class SFNode *dstnode, class interfaceMember *dstifm)
{
  routing_table::add(dstnode, dstifm);
}

ostream& eventOut::print(ostream& s)
{
  print_Id_value(s << "eventOut    ");
  routing_table::print(s);
  return s;
}

////////////////////////////////////////////////////////////////////
class eventOutLink: public eventOut, public link {
public:
  PoolDecl(eventOutLink, "eventOutLink")

  eventOutLink(void) {};

  inline eventOutLink(class SFNode* thisnode, class eventOut *thisifm, class SFNode *srcnode, class eventOut *srcifm)
  {
    eventOut::init(thisifm);
    link::init(srcnode, srcifm, thisnode, thisifm);
    value.assign(ref()->value);
  }

  virtual interfaceMember* clone(void)
  {
    eventOutLink *e = new eventOutLink(*this); 
    routing_table::clone(e);
    return e;
  }

  virtual void instantiate(class SFNode* thisnode, class Proto* enclosing_proto =0)
  {
    eventOut::instantiate(thisnode, enclosing_proto);
    link::instantiate(enclosing_proto, thisnode, this);
    value.assign(ref()->value);
  }

  virtual void post(class SFNode *thisnode, const fieldValue& value)
  {
    ref()->post(refnode, value);
    eventOut::post(thisnode, value);
  }
};

interfaceMember* eventOut::link_eventOut(class SFNode* thisnode, class SFNode* node, class eventOut* ifm)
{
  return new eventOutLink(thisnode, this, node, ifm);
}

PoolImpl(eventOut)
PoolImpl(eventOutLink)


} // namespace xrml
