00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef __JackConnectionManager__
00021 #define __JackConnectionManager__
00022
00023 #include "JackConstants.h"
00024 #include "JackActivationCount.h"
00025 #include <assert.h>
00026
00027 namespace Jack
00028 {
00029
00030 #define NO_PORT 0xFFFE
00031
00032 #define EMPTY 0xFFFD
00033 #define FREE 0xFFFC
00034
00035 typedef uint16_t jack_int_t;
00036
00037 struct JackClientControl;
00038
00039 typedef enum {
00040 NotTriggered,
00041 Triggered,
00042 Running,
00043 Finished,
00044 } jack_client_state_t;
00045
00050 template <int SIZE>
00051 class JackFixedArray
00052 {
00053
00054 private:
00055
00056 jack_int_t fTable[SIZE];
00057 uint32_t fCounter;
00058
00059 public:
00060
00061 JackFixedArray()
00062 {
00063 Init();
00064 }
00065
00066 virtual ~JackFixedArray()
00067 {}
00068
00069 void Init()
00070 {
00071 for (int i = 0; i < SIZE; i++)
00072 fTable[i] = EMPTY;
00073 fCounter = 0;
00074 }
00075
00076 bool AddItem(jack_int_t index)
00077 {
00078 for (int i = 0; i < SIZE; i++) {
00079 if (fTable[i] == EMPTY) {
00080 fTable[i] = index;
00081 fCounter++;
00082 return true;
00083 }
00084 }
00085 return false;
00086 }
00087
00088 bool RemoveItem(jack_int_t index)
00089 {
00090 for (int i = 0; i < SIZE; i++) {
00091 if (fTable[i] == index) {
00092 fCounter--;
00093
00094 if (i == SIZE - 1) {
00095 fTable[i] = EMPTY;
00096 } else {
00097 int j;
00098 for (j = i; j <= SIZE - 2 && fTable[j] != EMPTY; j++) {
00099 fTable[j] = fTable[j + 1];
00100 }
00101 fTable[j] = EMPTY;
00102 }
00103 return true;
00104 }
00105 }
00106 return false;
00107 }
00108
00109 jack_int_t GetItem(jack_int_t index) const
00110 {
00111 return (index < SIZE) ? fTable[index] : EMPTY;
00112 }
00113
00114 const jack_int_t* GetItems() const
00115 {
00116 return fTable;
00117 }
00118
00119 bool CheckItem(jack_int_t index) const
00120 {
00121 for (int i = 0; i < SIZE && fTable[i] != EMPTY; i++) {
00122 if (fTable[i] == index)
00123 return true;
00124 }
00125 return false;
00126 }
00127
00128 uint32_t GetItemCount() const
00129 {
00130 return fCounter;
00131 }
00132
00133 };
00134
00139 template <int SIZE>
00140 class JackFixedArray1 : public JackFixedArray<SIZE>
00141 {
00142 private:
00143
00144 bool fUsed;
00145
00146 public:
00147
00148 JackFixedArray1()
00149 {
00150 Init();
00151 }
00152
00153 virtual ~JackFixedArray1()
00154 {}
00155
00156 void Init()
00157 {
00158 JackFixedArray<SIZE>::Init();
00159 fUsed = false;
00160 }
00161
00162 bool IsAvailable()
00163 {
00164 if (fUsed) {
00165 return false;
00166 } else {
00167 fUsed = true;
00168 return true;
00169 }
00170 }
00171 };
00172
00177 template <int SIZE>
00178 class JackFixedMatrix
00179 {
00180 private:
00181
00182 jack_int_t fTable[SIZE][SIZE];
00183
00184 public:
00185
00186 JackFixedMatrix()
00187 {}
00188
00189 virtual ~JackFixedMatrix()
00190 {}
00191
00192 void Init(jack_int_t index)
00193 {
00194 for (int i = 0; i < SIZE; i++) {
00195 fTable[index][i] = 0;
00196 fTable[i][index] = 0;
00197 }
00198 }
00199
00200 const jack_int_t* GetItems(jack_int_t index) const
00201 {
00202 return fTable[index];
00203 }
00204
00205 jack_int_t IncItem(jack_int_t index1, jack_int_t index2)
00206 {
00207 fTable[index1][index2]++;
00208 return fTable[index1][index2];
00209 }
00210
00211 jack_int_t DecItem(jack_int_t index1, jack_int_t index2)
00212 {
00213 fTable[index1][index2]--;
00214 return fTable[index1][index2];
00215 }
00216
00217 jack_int_t GetItemCount(jack_int_t index1, jack_int_t index2) const
00218 {
00219 return fTable[index1][index2];
00220 }
00221
00225 void GetOutputTable(jack_int_t index, jack_int_t* output) const
00226 {
00227 int i, j;
00228
00229 for (i = 0; i < SIZE; i++)
00230 output[i] = EMPTY;
00231
00232 for (i = 0, j = 0; i < SIZE; i++) {
00233 if (fTable[index][i] > 0) {
00234 output[j] = i;
00235 j++;
00236 }
00237 }
00238 }
00239
00240 bool IsInsideTable(jack_int_t index, jack_int_t* output) const
00241 {
00242 for (int i = 0; i < SIZE && output[i] != EMPTY; i++) {
00243 if (output[i] == index)
00244 return true;
00245 }
00246 return false;
00247 }
00248
00249 };
00250
00255 template <int SIZE>
00256 class JackLoopFeedback
00257 {
00258 private:
00259
00260 int fTable[SIZE][3];
00261
00265 bool AddConnectionAux(int ref1, int ref2)
00266 {
00267 for (int i = 0; i < SIZE; i++) {
00268 if (fTable[i][0] == EMPTY) {
00269 fTable[i][0] = ref1;
00270 fTable[i][1] = ref2;
00271 fTable[i][2] = 1;
00272 JackLog("JackLoopFeedback::AddConnectionAux ref1 = %ld ref2 = %ld\n", ref1, ref2);
00273 return true;
00274 }
00275 }
00276 jack_error("Feedback table is full !!\n");
00277 return false;
00278 }
00279
00283 bool RemoveConnectionAux(int ref1, int ref2)
00284 {
00285 for (int i = 0; i < SIZE; i++) {
00286 if (fTable[i][0] == ref1 && fTable[i][1] == ref2) {
00287 fTable[i][0] = EMPTY;
00288 fTable[i][1] = EMPTY;
00289 fTable[i][2] = 0;
00290 JackLog("JackLoopFeedback::RemoveConnectionAux ref1 = %ld ref2 = %ld\n", ref1, ref2);
00291 return true;
00292 }
00293 }
00294 jack_error("Feedback connection not found\n");
00295 return false;
00296 }
00297
00298 int IncConnection(int index)
00299 {
00300 fTable[index][2]++;
00301 return fTable[index][2];
00302 }
00303
00304 int DecConnection(int index)
00305 {
00306 fTable[index][2]--;
00307 return fTable[index][2];
00308 }
00309
00310 public:
00311
00312 JackLoopFeedback()
00313 {
00314 Init();
00315 }
00316 virtual ~JackLoopFeedback()
00317 {}
00318
00319 void Init()
00320 {
00321 for (int i = 0; i < SIZE; i++) {
00322 fTable[i][0] = EMPTY;
00323 fTable[i][1] = EMPTY;
00324 fTable[i][2] = 0;
00325 }
00326 }
00327
00328 bool IncConnection(int ref1, int ref2)
00329 {
00330 int index = GetConnectionIndex(ref1, ref2);
00331
00332 if (index >= 0) {
00333 IncConnection(index);
00334 return true;
00335 } else {
00336 return AddConnectionAux(ref1, ref2);
00337 }
00338 }
00339
00340 bool DecConnection(int ref1, int ref2)
00341 {
00342 int index = GetConnectionIndex(ref1, ref2);
00343
00344 if (index >= 0) {
00345 JackLog("JackLoopFeedback::DecConnection ref1 = %ld ref2 = %ld index = %ld\n", ref1, ref2, index);
00346 return (DecConnection(index) == 0) ? RemoveConnectionAux(ref1, ref2) : true;
00347 } else {
00348 return false;
00349 }
00350 }
00351
00355 int GetConnectionIndex(int ref1, int ref2) const
00356 {
00357 for (int i = 0; i < SIZE; i++) {
00358 if (fTable[i][0] == ref1 && fTable[i][1] == ref2)
00359 return i;
00360 }
00361 return -1;
00362 }
00363
00364 };
00365
00370 struct JackClientTiming
00371 {
00372 jack_time_t fSignaledAt;
00373 jack_time_t fAwakeAt;
00374 jack_time_t fFinishedAt;
00375 jack_client_state_t fStatus;
00376
00377 JackClientTiming():fSignaledAt(0), fAwakeAt(0), fFinishedAt(0), fStatus(NotTriggered)
00378 {}
00379 ~JackClientTiming()
00380 {}
00381 };
00382
00397 class JackConnectionManager
00398 {
00399
00400 private:
00401
00402 JackFixedArray<CONNECTION_NUM> fConnection[PORT_NUM];
00403 JackFixedArray1<PORT_NUM_FOR_CLIENT> fInputPort[CLIENT_NUM];
00404 JackFixedArray<PORT_NUM_FOR_CLIENT> fOutputPort[CLIENT_NUM];
00405 JackFixedMatrix<CLIENT_NUM> fConnectionRef;
00406 JackActivationCount fInputCounter[CLIENT_NUM];
00407 JackLoopFeedback<CONNECTION_NUM> fLoopFeedback;
00409 bool IsLoopPathAux(int ref1, int ref2) const;
00410
00411
00412 public:
00413
00414 JackConnectionManager();
00415 virtual ~JackConnectionManager();
00416
00417
00418 int Connect(jack_port_id_t port_src, jack_port_id_t port_dst);
00419 int Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst);
00420 bool IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00421
00422 jack_int_t Connections(jack_port_id_t port_index) const;
00423 jack_port_id_t GetPort(jack_port_id_t port_index, int connection) const;
00424 const jack_int_t* GetConnections(jack_port_id_t port_index) const;
00425
00426 bool IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00427 bool DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00428 bool IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00429
00430 bool IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00431 void IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00432 void DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00433
00434
00435 int AddInputPort(int refnum, jack_port_id_t port_index);
00436 int AddOutputPort(int refnum, jack_port_id_t port_index);
00437
00438 int RemoveInputPort(int refnum, jack_port_id_t port_index);
00439 int RemoveOutputPort(int refnum, jack_port_id_t port_index);
00440
00441 const jack_int_t* GetInputPorts(int refnum);
00442 const jack_int_t* GetOutputPorts(int refnum);
00443
00444
00445 void InitRefNum(int refnum);
00446 int GetInputRefNum(jack_port_id_t port_index) const;
00447 int GetOutputRefNum(jack_port_id_t port_index) const;
00448
00449
00450 bool IsDirectConnection(int ref1, int ref2) const;
00451 void DirectConnect(int ref1, int ref2);
00452 void DirectDisconnect(int ref1, int ref2);
00453
00454 int GetActivation(int refnum) const;
00455
00456
00457 void ResetGraph(JackClientTiming* timing);
00458 int ResumeRefNum(JackClientControl* control, JackSynchro** table, JackClientTiming* timing);
00459 int SuspendRefNum(JackClientControl* control, JackSynchro** table, JackClientTiming* timing, long time_out_usec);
00460
00461 };
00462
00463 }
00464
00465 #endif
00466