/// @file node.hh /// @author Joshua Petitt /// @author Stefan Schmitt /// @version 1.0 /// @date 2003-07 /// /// This file defines the Link and Node base classes. The classes hold no data, /// but allow the connection of nodes in a net structure. /// /// These classes are not really useful. They are just a kind of agenda for how /// to declare and implement other classes that interact in means of nodes and /// links, too. These examples, being sort of a "semantic" template, is for /// human brain use in opposition to a "syntactic" template for compiler use /// (the latter refering to the \c template keyword of C++). It is definitely /// possible to implement this as a syntactiv template, but it would be /// difficult to write and very ugly; just have a look at the STL source code /// and you'll know how ugly. /// /// The Node and Link classes could indeed be used as abstract base classes for /// other classes that interact using this scheme. But this would almost /// totally remove compile-time type checking, leading to some kind of /// Smalltalk-like dynamic typing and would thus involve excessive runtime type /// checking, which is costly in speed, memory, typing and programmer's brains. /// /// Remember: This is C++. Inheritance is \b not for code reuse. #ifndef NODE_HH #define NODE_HH #include "base/base.hh" #include "base/templates.hh" #include "base/constants.hh" /// THE NAMESPACE. namespace EyeMind { const unsigned LINK_LIST_SIZE = 4; ///< Number of Link in Links collection. class Node; // forward declaration /// Link Base Class. /// /// Each link, when created, is given a unique tag which can be used to /// identify a link. /// /// The Link also contains two pointers to Node objects, thus this class is a /// "link" between two end points, i.e. Nodes. /// /// To establish the link, use the operators: /// SourceNode >> Link >> TargetNode; /// or /// TargetNode << Link << SourceNode; /// /// @warning: This is just an example. Don't derive anything from this class, /// just copy the code you find useful into your own class. class Link : public Updatable { friend Node& LinkOutputToNode(Link& l, Node& o); friend Node& LinkInputToNode(Link& l, Node& i); friend Link& NodeOutputToLink(Node& n, Link& o); friend Link& NodeInputToLink(Node& n, Link& i); friend Link* DisconnectNodes(Node& s, Node& t); private: Node *in; ///< Input Node of Link. Node *out; ///< Output Node of Link. /// Reset in and out. void Null(){ in = NULL; out = NULL; } public: /// Default constructor; end points are NULLed. Link(); /// @name Attribute manipulation functions //@{ Node* In(){ return in; } ///< Returns input Node. Node* Out(){ return out; } ///< Returns output Node. //@} }; /// Links collection. typedef Array Links; /// Node Base Class. /// /// The Node is given a unique tag which can be used to identify the /// object in a collection. /// /// @warning: This is just an example. Don't derive anything from this class, /// just copy the code you find useful into your own class. class Node : public Tagged { friend Node& LinkOutputToNode(Link& l, Node& o); friend Node& LinkInputToNode(Link& l, Node& i); friend Link& NodeOutputToLink(Node& n, Link& o); friend Link& NodeInputToLink(Node& n, Link& i); friend Link* DisconnectNodes(Node& s, Node& t); protected: Links inlinks; ///< Input Links collection. Links outlinks; ///< Output Links collection. }; /// Connect Link output with target Node. Node& operator>>(Link& l, Node& o); /// Connect Link input with source Node. Node& operator<<(Link& l, Node& i); /// Add output Link to Node. Link& operator>>(Node& n, Link& o); /// Add input Link to Node. Link& operator<<(Node& n, Link& i); /// Disconnect this Node from other Node. Link* operator|(Node& s, Node& t); /// Connect Link output with target Node. Node& LinkOutputToNode(Link& l, Node& o); /// Connect Link input with source Node. Node& LinkInputToNode(Link& l, Node& i); /// Add output Link to Node. Link& NodeOutputToLink(Node& n, Link& o); /// Add input Link to Node. Link& NodeInputToLink(Node& n, Link& i); /// Disconnect this Node from other Node. /// Note: The Link object is not destroyed. /// @param s Source Node /// @param t Target Node to disconnect /// @returns Lingering Link* on success, NULL else /// @warning Uses iteration, so not thread safe (see warning in templates.h) Link* DisconnectNodes(Node& s, Node& t); }; // namespace EyeMind #endif //NODE_HH