00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <basix/port.hpp>
00014 #include <basix/string.hpp>
00015 #include <basix/vector.hpp>
00016 #include <basix/identifiers.hpp>
00017
00019
00020 namespace mmx {
00021
00022
00023
00024
00025
00026 class composite_port_rep: public port_rep {
00027 vector<port> ps;
00028 vector<string> names;
00029
00030 public:
00031 syntactic expression () const {
00032 vector<syntactic> v;
00033 for (nat i=0; i<N(ps); i++)
00034 v << syn (GEN_TYPE, syntactic (names[i]), flatten (ps[i]));
00035 return syn ("composite_port", v);
00036 }
00037
00038 bool is_output_port () {
00039 for (nat i=0; i<N(ps); i++)
00040 if (mmx::is_output_port (ps[i]))
00041 return true;
00042 return false;
00043 }
00044 bool is_input_port () {
00045 for (nat i=0; i<N(ps); i++)
00046 if (mmx::is_input_port (ps[i]))
00047 return true;
00048 return false;
00049 }
00050 bool error_flag () {
00051 for (nat i=0; i<N(ps); i++)
00052 if (mmx::error_flag (ps[i]))
00053 return true;
00054 return false;
00055 }
00056 string error_message () {
00057 for (nat i=0; i<N(ps); i++)
00058 if (mmx::error_flag (ps[i]))
00059 return mmx::error_message (ps[i]);
00060 return "";
00061 }
00062 bool busy () {
00063 for (nat i=0; i<N(ps); i++)
00064 if (mmx::busy (ps[i]))
00065 return true;
00066 return false;
00067 }
00068 nat can_write () {
00069 nat r= (nat) (-1);
00070 for (nat i=0; i<N(ps); i++)
00071 if (mmx::is_output_port (ps[i]))
00072 r= min (r, mmx::can_write (ps[i]));
00073 return r;
00074 }
00075 nat can_read () {
00076 nat r= 0;
00077 for (nat i=0; i<N(ps); i++)
00078 if (mmx::is_input_port (ps[i]))
00079 r += mmx::can_read (ps[i]);
00080 return r;
00081 }
00082 void write (const char* s, nat n) {
00083 for (nat i=0; i<N(ps); i++)
00084 if (mmx::is_output_port (ps[i]))
00085 mmx::write (ps[i], s, n);
00086 }
00087 void read (char* s, nat n) {
00088 while (n > 0)
00089 for (nat i=0; i<N(ps); i++)
00090 if (n > 0 && mmx::is_input_port (ps[i])) {
00091 nat k= min (n, mmx::can_read (ps[i]));
00092 if (k > 0) mmx::read (ps[i], s, k);
00093 s += k;
00094 n -= k;
00095 }
00096 ASSERT (n == 0, "read failed");
00097 }
00098 void flush () {
00099 for (nat i=0; i<N(ps); i++)
00100 if (mmx::is_output_port (ps[i]))
00101 mmx::flush (ps[i]);
00102 }
00103 bool wait (int msecs) {
00104 for (nat i=0; i<N(ps); i++)
00105 if (mmx::is_input_port (ps[i])) {
00106 nat delay= min (msecs, 1);
00107 if (mmx::wait (ps[i], delay)) return true;
00108 msecs -= delay;
00109 }
00110 return false;
00111 }
00112 port component (const string& name) {
00113 for (nat i=0; i<N(ps); i++)
00114 if (name == names[i])
00115 return ps[i];
00116 ERROR ("port not found");
00117 }
00118
00119 public:
00120 inline composite_port_rep (const vector<port>& p2, const vector<string>& n2):
00121 ps (p2), names (n2) {}
00122 };
00123
00124
00125
00126
00127
00128 port
00129 composite_port (const vector<port>& ps, const vector<string>& names) {
00130 ASSERT (N(ps) == N(names), "lengths do not match");
00131 return (port_rep*) new composite_port_rep (ps, names);
00132 }
00133
00134 port
00135 composite_port (const vector<port>& ps) {
00136 nat i, n= N(ps);
00137 vector<string> names= fill<string> (n);
00138 for (i=0; i<n; i++) names[i]= as_string (i);
00139 return composite_port (ps, names);
00140 }
00141
00142 }