2.NODE.H
/**
* Represents a data element in an output vector file. Processing nodes
* (Node) process elements of this type.
*代表output vector 中的一个数据元素。处理节点是处理这类型的数据
* @see Node, Channel, Port
*/
struct Datum
{
double x; ///< usually t simulation time
double y; ///< usually the value at t
};
/**
* Connection point of channels in processing nodes.
*信道中处理节点的连接点
* @see Datum, Node, Channel
*/
class Port
{
private:
Node *ownernode;
Channel *chan;
public:
Port(Node *owner) {ownernode = owner; chan = 0;}
Port(const Port& p) {ownernode = p.ownernode; chan = p.chan;}
~Port() {}
void setChannel(Channel *channel) {ASSERT(!chan); chan = channel;}
Node *node() {return ownernode;}
Channel *channel() const {return chan;}
Channel *operator()() const {ASSERT(chan); return chan;}
};
/**
* Processing node. Processing nodes can be connected via ports and channels
* to form a data flow network.
*
* @see DataflowManager, Port, Channel, Datum, NodeType
*/
class Node
{
friend class DataflowManager;
private:
DataflowManager *mgr;
NodeType *nodetype;
bool alreadyfinished;
部分重要的函数:
/** Execution and scheduling */
//@{
/**
* Do some amount of work, then return
*/
virtual void process() = 0;
/**
* Are more invocations if process() necessary()?
*/
virtual bool finished() const = 0;
/**
* Provided it has not finished() yet, can process() be invoked
* right now? (finished() is called first -- isReady() is only
* invoked if finished() returns false. So isReady() doesn't need
* to check for eof.)
*/
virtual bool isReady() const = 0;
//@}
/**
* Invoked by the dataflow manager when the node's finished() first
* returns true. It sets a status flag so that further invocations
* of finished() can be avoided.
*/
void setAlreadyFinished() {alreadyfinished = true;}
/**
* Used by the dataflow manager. Returns true if setAlreadyFinished()
* has already been invoked.
*/
bool alreadyFinished() {return alreadyfinished;}
3.CHANNEL.H
这个文件基本上是模拟生产者和消费者问题写的。
/**
* Does buffering between two processing nodes (Node).
*
* @see Node, Port, Datum,Datum的定义是在node.h中
*/
class Channel
{
private:
// note: a Channel should *never* hold a pointer back to its Ports
// because ports may be copied after having been assigned to channels
// (e.g. in VectorFileReader which uses std::vector). Node ptrs are OK.
std::deque<Datum> buffer; //注意,如果这里定义的是std::deque<Datum *>buffer的话,删除时要小心(删除容器中的指针是一个必须非常小心的事情
Node *producernode;
Node *consumernode;
bool producerfinished;
bool consumerfinished;
public:
Node *producerNode() const {return producernode;}
void setProducerNode(Node *node) {producernode = node;}
Node *consumerNode() const {return consumernode;}
void setConsumerNode(Node *node) {consumernode = node;}
/**
* Returns ptr to the first buffered data item (next one to be read), or NULL
*/
const Datum *peek() const
{
if (buffer.size()==0)
return NULL;
return &(buffer.front());
}
int Channel::read(Datum *a, int max)
{
ASSERT(!consumerfinished);
int n = buffer.size();
if (n>max)
n = max;
for (int i=0; i<n; i++)
{
a[i] = buffer.front();
buffer.pop_front();
}
return n;
}
void Channel::write(Datum *a, int n)
{
ASSERT(!producerfinished);
if (consumerfinished)
return; // discard data if consumer finished
for (int i=0; i<n; i++)
buffer.push_back(a[i]);
}
/**
* Returns true if producer has already called close() which means
* there won't be any more data except those already in the buffer
*/
bool closing() {return producerfinished;}
/**
* Returns true if close() has been called and there's no buffered data
*/
bool eof() {return producerfinished && length()==0;}
/**
* Called by the producer to declare it will not write any more --
* if also there's no more buffered data (length()==0), that means EOF.
*/
void close() {producerfinished=true;}
/**
* Called when consumer has finished. Causes channel to ignore
* further writes (discard any data written).
*/
void consumerClose() {buffer.clear();consumerfinished=true;}
/**
* Returns true when the consumer has closed the channel, that is,
* it will not read any more data from the channel.
*/
bool consumerClosed() {return consumerfinished;}
/**
* Number of currently buffered items.
*/
int length() {return buffer.size();}
};
4.NODETYPE
class Node;
class Port;
typedef std::map<std::string,std::string> StringMap; //这是一个全局变量
/**
* Describes properties of a node class.
*
* @see Node, NodeTypeRegistry
*/
class NodeType
{
protected:
void checkAttrNames(const StringMap& attr) const
{
StringMap allowedAttrs;
getAttributes(allowedAttrs);
// are there illegal attributes?
for (StringMap::const_iterator it=attrs.begin(); it!=attrs.end(); ++it)
{
const char *attr = it->first.c_str();
StringMap::iterator j = allowedAttrs.find(attr);
if (j==allowedAttrs.end())
throw new Exception("illegal attribute `%s'", attr);
}
// do we have all attributes?
for (StringMap::const_iterator i=allowedAttrs.begin(); i!=allowedAttrs.end(); ++i)
{
const char *attr = i->first.c_str();
StringMap::const_iterator it = attrs.find(attr);
if (it==attrs.end())
throw new Exception("missing attribute `%s'", attr);
}
public:
NodeType() {}
virtual ~NodeType() {}
/**
* Returns type name as displayed on the UI (e.g. "mean" or "winavg")
*返回显示在UI上的类型的名字
*/
virtual const char *name() const = 0;
/**
* Returns the category of the node (source, sink, filter, etc.)
* 返回节点类型的种类(比如source, sink, filter等等)
*/
virtual const char *category() const = 0;
/**
* Returns the description of the node (this can be displayed on the UI.)
*/
virtual const char *description() const = 0;
/**
* Returns true if this node should appear in the UI.
* 如果节点是显示在UI上的,那么返回真
*/
virtual bool isHidden() const = 0;
/**
* Fills the string map with attribute names and their descriptions.
*/
virtual void getAttributes(StringMap& attrs) const = 0;
/**
* Fills the string map with attribute names and their default values.
* (Doesn't necessarily supply default value for every attribute).
*/
virtual void getAttrDefaults(StringMap& attrs) const {}
/**
* Throws exception if something is not OK. The message in the
* exception is shown to the user.
*/
virtual void validateAttrValues(const StringMap& attrs) const {}
/**
* Create a node instance of this type.
*/
virtual Node *create(DataflowManager *, StringMap& attrs) const = 0;
/**
* Get the named port of the give node instance.
*/
virtual Port *getPort(Node *node, const char *portname) const = 0;
};