Dymanic Components

Step08: Moving Data

Component.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#pragma once
#include <string>
#include "Wire.h"

class Component {
    public:
        Component(std::string n, int val);
        std::string get_name();
        friend class Wire;
    private:
        std::string name;
        int data;

        int read(int val);
        int write( void );
};


Component.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include "Component.h"

Component::Component( std::string n, int val ) {
    data = val;
    name = n;
}

// send data somewhere
int Component::write( void ) {
    return data;
}

// receive data from somewhere
int Component::read( int val ) {
    return data = val;
}

std::string Component::get_name( void ) {
    return name;
}
Component.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include "Component.h"
#include "Wire.h"

class Machine {
    public:
        Machine( void );
        void build( void );
        void run( void );
        friend class wire;
    private:
        std::string machine_def;
        // parts needed
        Component *parts[10];
        Wire *wires[10];
        int part_count;
        int wire_count;

        Component *find_part( std::string name );
};

Machine.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
#include <fstream>
#include "Machine.h"
#include "Component.h"
#include "Wire.h"

Machine::Machine( void ) {
    machine_def = "cycsi.hdl";
}

Component *Machine::find_part( std::string name ) {
        for( int i=0; i<part_count; i++ ) {
                    if( parts[i]->get_name() == name ) return parts[i];
                        }
            return NULL;
}

void Machine::build( void ) {
    std::fstream fin;
    std::string token, in_token, out_token;

    fin.open(machine_def);
    if(!fin) {
        std::cout << "no machine def found. Aborting..." << std::endl;
        exit(EXIT_FAILURE);
    }
    while( fin >> token)  {
        // load all component parts
        if( token == "PARTS" ) {
            std::cout << "begin part definitions" << std::endl;
            fin >> token;   // component name
            while( token != "END" ) {
                parts[part_count++] = new Component( token, 0 );
                std::cout << "\t" << token << std::endl;
                fin >> token;   // colon
                fin >> token; // type
                fin >> token; // next symbol
            }
            std::cout << "end part definitions" << std::endl;
        } else if( token == "CONNECTIONS" ) {
            // wire up all connections with wires
            std::cout << "begin connection definitions" << std::endl;
            fin >> token;
            while( token != "END" ) {
                in_token = token.substr(0,token.find("."));
                wires[wire_count] = new Wire();
                std::cout << "\t" << in_token;
                fin >> token;   // "->" symbol
                fin >> token; // type
                out_token = token.substr(0,token.find("."));
                std::cout << "->";
                // create this connection
                std::cout << out_token << std::endl;
                wires[wire_count]->attach_in(find_part( in_token ));
                wires[wire_count]->attach_out(find_part( out_token ));
                wire_count++;
                fin >> token; // next symbol
            }
            std::cout << "end connection definitions" << std::endl;
        } else {
            std::cout <<  "\t" <<
                token <<
                std::endl;
        }
    }
    std::cout << "Machine constructed using:" << std::endl;
    std::cout << "\t" << part_count << " components" << std::endl;
    std::cout << "\t" << wire_count << " wires" << std::endl;
}

void Machine::run( void ) {
    int max_ticks = 10;
    for( int time = 0; time < max_ticks; time++ ) {
        for(int w = 0; w < wire_count; w++ ) {
            std::cout << "t" << time << ": ";
            wires[w]->tick();
        }
    }
}
Wire.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include <string>

class Component;

class Wire {
    public:
        Wire();
        void attach_in(Component *c_in);
        void attach_out(Component *c_out);
        void tick( void );
    private:
        int data;
        Component *in;
        Component *out;
        std::string source, dest;
        void read(void);
        void write( void );
};


Wire.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <string>
#include "Wire.h"
#include "Component.h"

// constructor
Wire::Wire( void ) {
    data = -1;
    in = NULL;
    out = NULL;
}

// Accessor
void Wire::read(void) {
    // fetch wire value from input side
    data = in->write();
    source = in->get_name();
}

void Wire::write( void ) {
    // deliver wire value to output side
    dest = out->get_name();
    out->write();
    std::cout << source << "-(" << 
        data << ")->" << dest << std::endl;
}

void Wire::attach_in(Component *c_in) {
    in = c_in;
}

void Wire::attach_out(Component *c_out) {
    out = c_out;
}

void Wire::tick( void ) {
    read();
    write();
}
main.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#include <iostream>
#include "Machine.h"

Machine m;

int main( int argc, char *argv[] ) {
    std::cout << "ex1: exchanging data" << std::endl;
    std::cout << "running ..." << std::endl;

    m.build();

    // make the data move
    m.run();

    std::cout << "done!" << std::endl;
}

Note

You should commit this version of the code now. Tag it as version v.0.8.0

Step08: Moving Data

Component.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#pragma once
#include <string>
#include "Wire.h"

class Component {
    public:
        Component(std::string n, int val);
        friend class Wire;
        std::string get_name();
    private:
        std::string name;
        int data;

        int read(int val);
        int write( void );
};


Component.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include "Component.h"

Component::Component( std::string n, int val ) {
    data = val;
    name = n;
}

// send data somewhere
int Component::write( void ) {
    return data;
}

// receive data from somewhere
int Component::read( int val ) {
    return data = val;
}

std::string Component::get_name( void ) {
    return name;
}
Component.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include "Component.h"
#include "Wire.h"

class Machine {
    public:
        Machine( void );
        void build( void );
        void run( void );
        friend class wire;
    private:
        std::string machine_def;
        // parts needed
        Component *parts[10];
        Wire *wires[10];
        int part_count;
        int wire_count;

        Component *find_part( std::string name );
};

Machine.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
#include <fstream>
#include "Machine.h"
#include "Component.h"
#include "Wire.h"

Machine::Machine( void ) {
    machine_def = "cycsi.hdl";
}

Component *Machine::find_part( std::string name ) {
        for( int i=0; i<part_count; i++ ) {
                    if( parts[i]->get_name() == name ) return parts[i];
                        }
            return NULL;
}

void Machine::build( void ) {
    std::fstream fin;
    std::string token, in_token, out_token;

    fin.open(machine_def);
    if(!fin) {
        std::cout << "no machine def found. Aborting..." << std::endl;
        exit(EXIT_FAILURE);
    }
    while( fin >> token)  {
        // load all component parts
        if( token == "PARTS" ) {
            std::cout << "begin part definitions" << std::endl;
            fin >> token;   // component name
            while( token != "END" ) {
                parts[part_count++] = new Component( token, 0 );
                std::cout << "\t" << token << std::endl;
                fin >> token; // colon
                fin >> token; // type
                fin >> token; // next symbol
            }
            std::cout << "end part definitions" << std::endl;
        } else if( token == "CONNECTIONS" ) {
            // wire up all connections with wires
            std::cout << "begin connection definitions" << std::endl;
            fin >> token;
            while( token != "END" ) {
                in_token = token.substr(0,token.find("."));
                wires[wire_count] = new Wire();
                std::cout << "\t" << in_token;
                fin >> token;   // "->" symbol
                fin >> token; // type
                out_token = token.substr(0,token.find("."));
                std::cout << "->";
                // create this connection
                std::cout << out_token << std::endl;
                wires[wire_count]->attach_in(find_part( in_token ));
                wires[wire_count]->attach_out(find_part( out_token ));
                wire_count++;
                fin >> token; // next symbol
            }
            std::cout << "end connection definitions" << std::endl;
        } else {
            std::cout <<  "\t" <<
                token <<
                std::endl;
        }
    }
    std::cout << "Machine constructed using:" << std::endl;
    std::cout << "\t" << part_count << " components" << std::endl;
    std::cout << "\t" << wire_count << " wires" << std::endl;
}

void Machine::run( void ) {
    int max_ticks = 10;
    for( int time = 0; time < max_ticks; time++ ) {
        for(int w = 0; w < wire_count; w++ ) {
            std::cout << "t" << time << ": ";
            wires[w]->tick();
        }
    }
}
Wire.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include <string>

class Component;

class Wire {
    public:
        Wire();
        void attach_in(Component *c_in);
        void attach_out(Component *c_out);
        void tick( void );
    private:
        int data;
        Component *in;
        Component *out;
        std::string source, dest;
        void read(void);
        void write( void );
};


Wire.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <string>
#include "Wire.h"
#include "Component.h"

// constructor
Wire::Wire( void ) {
    data = -1;
    in = NULL;
    out = NULL;
}

// Accessor
void Wire::read(void) {
    // fetch wire value from input side
    data = in->write();
    source = in->get_name();
}

void Wire::write( void ) {
    // deliver wire value to output side
    dest = out->get_name();
    out->write();
    std::cout << source << "-(" << 
        data << ")->" << dest << std::endl;
}

void Wire::attach_in(Component *c_in) {
    in = c_in;
}

void Wire::attach_out(Component *c_out) {
    out = c_out;
}

void Wire::tick( void ) {
    read();
    write();
}
main.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <iostream>
#include "Machine.h"

Machine m;

int main( int argc, char *argv[] ) {
    std::cout << "ex1: exchanging data" << std::endl;
    std::cout << "running ..." << std::endl;

    // build the machine from a file
    m.build();

    // make the data move
    m.run();

    std::cout << "done!" << std::endl;
}

Note

You should commit this version of the code now. Tag it as version v.0.9.0

Step10: Moving Data

Component.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#pragma once
#include <string>
#include "Wire.h"

class Component {
    public:
        Component(std::string n, int val);
        friend class Wire;
        std::string get_name();
        bool tick( void );
    private:
        std::string name;
        int data;
        bool changed;

        int read(int val);
        int write( void );
};


Component.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include "Component.h"

Component::Component( std::string n, int val ) {
    data = val;
    name = n;
    changed = false;
}

// send data somewhere
int Component::write( void ) {
    return data;
}

// receive data from somewhere
int Component::read( int val ) {
    changed = val != data;
    return data = val;
}

std::string Component::get_name( void ) {
    return name;
}

bool Component::tick( void ) {
    std::cout << "\t" << name;
    if(changed) {
        std::cout << " got new data" << std::endl;
    } else {
        std::cout << " no action" << std::endl;
    }
    return changed;
}

Component.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#pragma once
#include "Component.h"
#include "Wire.h"

class Machine {
    public:
        Machine( void );
        void build( void );
        void run( void );
        friend class wire;
    private:
        std::string machine_def;
        // parts needed
        Component *parts[10];
        Wire *wires[10];
        int part_count;
        int wire_count;

        Component *find_part( std::string name );
};

Machine.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <fstream>
#include "Machine.h"
#include "Component.h"
#include "Wire.h"

Machine::Machine( void ) {
    machine_def = "cycsi.hdl";
}

Component *Machine::find_part( std::string name ) {
        for( int i=0; i<part_count; i++ ) {
                    if( parts[i]->get_name() == name ) return parts[i];
                        }
            return NULL;
}

void Machine::build( void ) {
    std::fstream fin;
    std::string token, in_token, out_token;

    fin.open(machine_def);
    if(!fin) {
        std::cout << "no machine def found. Aborting..." << std::endl;
        exit(EXIT_FAILURE);
    }
    while( fin >> token)  {
        // load all component parts
        if( token == "PARTS" ) {
            std::cout << "begin part definitions" << std::endl;
            fin >> token;   // component name
            while( token != "END" ) {
                parts[part_count++] = new Component( token, 0 );
                std::cout << "\t" << token << std::endl;
                fin >> token;   // colon
                fin >> token; // type
                fin >> token; // next symbol
            }
            std::cout << "end part definitions" << std::endl;
        } else if( token == "CONNECTIONS" ) {
            // wire up all connections with wires
            std::cout << "begin connection definitions" << std::endl;
            fin >> token;
            while( token != "END" ) {
                in_token = token.substr(0,token.find("."));
                wires[wire_count] = new Wire();
                std::cout << "\t" << in_token;
                fin >> token;   // "->" symbol
                fin >> token; // type
                out_token = token.substr(0,token.find("."));
                std::cout << "->";
                // create this connection
                std::cout << out_token << std::endl;
                wires[wire_count]->attach_in(find_part( in_token ));
                wires[wire_count]->attach_out(find_part( out_token ));
                wire_count++;
                fin >> token; // next symbol
            }
            std::cout << "end connection definitions" << std::endl;
        } else {
            std::cout <<  "\t" <<
                token <<
                std::endl;
        }
    }
    std::cout << "Machine constructed using:" << std::endl;
    std::cout << "\t" << part_count << " components" << std::endl;
    std::cout << "\t" << wire_count << " wires" << std::endl;
}

void Machine::run( void ) {
    int max_ticks = 10;
    bool clock = true;
    for( int time = 0; time < max_ticks; time++ ) {
        bool stable = true;
        std::cout << "t" << time << ": " << std::endl;
        // tick - check the parts
        for(int c=0; c < part_count; c++ ) {
            if(parts[c]->tick()) stable = false;;
        }
        clock = !clock;
        // tock - check the wires
        for(int w = 0; w < wire_count; w++ ) {
            if(wires[w]->tick()) stable = false;;
        }
        clock = !clock;
        if(stable) break;
    }
}
Wire.h
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#pragma once
#include <string>

class Component;

class Wire {
    public:
        Wire();
        void attach_in(Component *c_in);
        void attach_out(Component *c_out);
        bool tick( void );
    private:
        int data;
        int check_val;
        bool changed;
        Component *in;
        Component *out;
        std::string source, dest;
        void read(void);
        void write( void );
};


Wire.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <string>
#include "Wire.h"
#include "Component.h"

#define UNKNOWN -1

// constructor
Wire::Wire( void ) {
    data = UNKNOWN;
    check_val = UNKNOWN;
    in = NULL;
    out = NULL;
    changed = false;
}

// Accessor
void Wire::read(void) {
    // fetch wire value from input side
    check_val = in->write();
    source = in->get_name();
    changed = check_val != data;
}

void Wire::write( void ) {
    // deliver wire value to output side
    dest = out->get_name();
    if(changed) { // we neeed to notify the output side
        data = check_val;
        out->write();
    } // otherwise do nothing!
}

void Wire::attach_in(Component *c_in) {
    in = c_in;
}

void Wire::attach_out(Component *c_out) {
    out = c_out;
}

bool Wire::tick( void ) {
    std::cout << "\twire:";
    read();
    write();
    std::cout << source << "-(" << 
        data << ")->" << dest;
    if(changed) std::cout <<"(changed)";
    std::cout << std::endl;
    return changed;
}
main.cpp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <iostream>
#include "Machine.h"

Machine m;

int main( int argc, char *argv[] ) {
    std::cout << "ex1: exchanging data" << std::endl;
    std::cout << "running ..." << std::endl;

    // build the machine from a file
    m.build();

    // make the data move
    m.run();

    std::cout << "done!" << std::endl;
}

Note

You should commit this version of the code now. Tag it as version v.0.10.0