// route.H: event route

#ifndef _XRML_ROUTE_H_
#define _XRML_ROUTE_H_

#include "nodeInterface.H"

namespace xrml {

class route: public interfaceMemberRef {
  friend class routing_table;

  // reference to an interface member of a named node.
public:
  PoolDecl(route, "route")

  inline route(void) 
  {
    interfaceMemberRef::_init();
  }

  inline route(class SFNode* dstnode, class interfaceMember* dstifm) 
  { 
    interfaceMemberRef::_init(dstnode, dstifm); 
  }

  void instantiate(class Proto* master)
  {
    interfaceMember *oldrefifm = ref();

    // <subclass of SFNode>::instantiate() doesn't create new copies of named nodes. 
    // Instead it returns a pointer to the new instance in a PROTO namedNode table or
    // 'this' for named nodes outside PROTOs. There is also no problem when
    // instantiating a PROTO namedNode table itself, since named nodes can only
    // contain USE statements for previously defined named nodes and named nodes
    // appear in the order of their definition in the table.
    // See Proto::instantiate_implementation() and SFNode::instantiate().
    refnode = refnode->instantiate(master);

    // must both be eventIns or exposedFields, with same Id and identical
    // field value type
    assert((is_eventIn(ref()) && is_eventIn(oldrefifm)) ||
	   (is_exposedField(ref()) && is_exposedField(oldrefifm)));
    assert(fieldType(ref()->value) == fieldType(oldrefifm->value));
    assert(ref()->Id == oldrefifm->Id);
  }

  inline bool operator==(const route& r) const
  {
    return (r.refnode == refnode) && (r.refidx == refidx);
  }

  friend ostream& operator<<(ostream& s, route& r)
  {
    return s << r.refnode->name() << '.' << r.ref()->Id;
  }
};

} // namespace xrml

#endif /*_XRML_ROUTE_H_*/
