@startuml !theme plain skinparam linetype ortho skinparam classAttributeIconSize 0 class main { main(int argc, char** argv) : int open_input(int argc, char** argv) : istream* } hide main circle class Node { /' (also ConcreteObserver) '/ Node() #Node(const char* type) #output : Net* {abstract} clone() : Node* {abstract} level() : SignalLevel #max_inputs : int #min_inputs : int #inputs : vector accept(NodeVisitor& visitor) : void addInput(Net*) : void setOutput(Net*) : void sim() : void update() : void } class Net { /' (also ConcreteSubject) '/ Net() getLevel() : SignalLevel setLevel(SignalLevel) : void } class Subject { size() : int attach(Observer* obs) : void detach(Observer*) : void notify() : void } interface Observer { {abstract} update() : void } class GateAnd { GateAnd() clone() : GateAnd* #level() : SignalLevel } class GateNand { clone() : GateNand* #level() : SignalLevel } class GateNor { clone() : GateNor* #level() : SignalLevel } class GateNot { GateNot() GateNot(const GateNot* prototype) clone() : GateNot* } class GateOr { GateOr() GateOr(const GateOr* prototype) clone() : GateOr* #level() : SignalLevel } class GateXor { GateXor() GateXor(const GateXor* prototype) clone() : GateXor* } class NodeInput { NodeInput() } enum SignalLevel { LOW HIGH UNDEFINED } class NodeInputLow { clone() : NodeInputLow* #level() : SignalLevel } class NodeInputHigh { clone() : NodeInputHigh* #level() : SignalLevel } class NodeOutput { NodeOutput() NodeOutput(const NodeOutput* prototype) clone() : NodeOutput* level() : SignalLevel accept(NodeVisitor& visitor) : void setOutput(Net*) : void sim() : void } class NodeOutputVisitor { NodeOutputVisitor() level : SignalLevel output_node : bool visit(Node& node) : void visit(NodeOutput& node) : void } interface NodeVisitor { {abstract} visit(NodeOutput& node) : void {abstract} visit(Node& node) : void } exception Exception { Exception(const char* fmt, ...) #Exception() #error : char* what() : char* #va_format(va_list args, const char* fmt) : void } exception CircuitException { CircuitException(const char* fmt, ...) node : Node* } exception ParserException { ParserException(const char* fmt, ...) } class NodeException { NodeException(Node* node, const char* fmt) } class Parser { Parser() Parser(Circuit& circuit) {static} filter(char* input) : size_t parse(string input) : void parse(istream input) : void set_circuit(Circuit& circuit) : void } class NodeFactory { NodeFactory() {static} create(string type) : Node* {static} has_type(const char* type) : bool {static} has_type(string type) : bool } class Circuit { Circuit() result() : string create(string label, vector nodes) : void new_net(string src, vector dests) : void new_node(string label, string type) : void sim() : void } class LoopDetection { LoopDetection() add_connection(string src, const vector& dests) : void } main --* Parser main --* Circuit main -- CircuitException main -- ParserException NodeOutputVisitor --|> NodeVisitor NodeVisitor <-[dashed] Node NodeVisitor <-[dashed] NodeOutput NodeOutputVisitor <--up Circuit LoopDetection <-- Circuit Net -- SignalLevel Node -- SignalLevel GateAnd <|-- GateNand GateOr <|-- GateNor Node <|--- GateAnd Node <|--- GateNot Node <|--- GateOr Node <|--- GateXor Node <|--- NodeOutput Node <|--- NodeInput NodeInput <|-- NodeInputLow NodeInput <|-- NodeInputHigh Subject <|--down Net Observer <|-[dashed]down-Node Observer -right Subject Node -right> Net Exception <|-- CircuitException Exception <|-- ParserException CircuitException <|-- NodeException Parser -[dashed]> Circuit ParserException - Parser CircuitException -left Circuit NodeException -left- Node NodeFactory -[dashed]> Node NodeFactory <-[dashed]- Node Circuit ---> Net Circuit ---> Node @enduml