
#ifndef PLS_DATAFLOW_INTERNAL_NODE_H_
#define PLS_DATAFLOW_INTERNAL_NODE_H_

#include "build_state.h"
#include "token.h"

namespace pls {
namespace dataflow {
namespace internal {

/**
 * Represents a single piece included in a dataflow graph.
 * This can be anything connected to form the dataflow that requires
 * memory during invocation and is present in the connected flow graph.
 */
class node {
  template<typename INS, typename OUTS>
  friend
  class graph;

 public:
  virtual int num_successors() const = 0;
  virtual node *successor_at(int pos) const = 0;

  virtual int instance_buffer_size() const = 0;
  virtual void init_instance_buffer(void *memory) const = 0;
  virtual void clean_up_instance_buffer(void *memory) const = 0;

  virtual bool is_fully_connected() const = 0;

  template<typename M>
  M *get_invocation(invocation_info invocation) {
    return invocation.template get_instance_buffer<M>(memory_index_);
  }

 private:
  int memory_index_{0};
  node *direct_successor_{nullptr};
  build_state build_state_{build_state::fresh};
};

}
}
}

#endif //PLS_DATAFLOW_INTERNAL_NODE_H_
