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 "JackError.h"
00026 #include "JackCompilerDeps.h"
00027 #include <vector>
00028 #include <assert.h>
00029
00030 namespace Jack
00031 {
00032
00033 struct JackClientControl;
00034
00039 template <int SIZE>
00040 class JackFixedArray
00041 {
00042
00043 private:
00044
00045 jack_int_t fTable[SIZE];
00046 uint32_t fCounter;
00047
00048 public:
00049
00050 JackFixedArray()
00051 {
00052 Init();
00053 }
00054
00055 void Init()
00056 {
00057 for (int i = 0; i < SIZE; i++)
00058 fTable[i] = EMPTY;
00059 fCounter = 0;
00060 }
00061
00062 bool AddItem(jack_int_t index)
00063 {
00064 for (int i = 0; i < SIZE; i++) {
00065 if (fTable[i] == EMPTY) {
00066 fTable[i] = index;
00067 fCounter++;
00068 return true;
00069 }
00070 }
00071 return false;
00072 }
00073
00074 bool RemoveItem(jack_int_t index)
00075 {
00076 for (int i = 0; i < SIZE; i++) {
00077 if (fTable[i] == index) {
00078 fCounter--;
00079
00080 if (i == SIZE - 1) {
00081 fTable[i] = EMPTY;
00082 } else {
00083 int j;
00084 for (j = i; j <= SIZE - 2 && fTable[j] != EMPTY; j++) {
00085 fTable[j] = fTable[j + 1];
00086 }
00087 fTable[j] = EMPTY;
00088 }
00089 return true;
00090 }
00091 }
00092 return false;
00093 }
00094
00095 jack_int_t GetItem(jack_int_t index) const
00096 {
00097 return (index < SIZE) ? fTable[index] : EMPTY;
00098 }
00099
00100 const jack_int_t* GetItems() const
00101 {
00102 return fTable;
00103 }
00104
00105 bool CheckItem(jack_int_t index) const
00106 {
00107 for (int i = 0; i < SIZE && fTable[i] != EMPTY; i++) {
00108 if (fTable[i] == index)
00109 return true;
00110 }
00111 return false;
00112 }
00113
00114 uint32_t GetItemCount() const
00115 {
00116 return fCounter;
00117 }
00118
00119 } POST_PACKED_STRUCTURE;
00120
00125 template <int SIZE>
00126 class JackFixedArray1 : public JackFixedArray<SIZE>
00127 {
00128 private:
00129
00130 bool fUsed;
00131
00132 public:
00133
00134 JackFixedArray1()
00135 {
00136 Init();
00137 }
00138
00139 void Init()
00140 {
00141 JackFixedArray<SIZE>::Init();
00142 fUsed = false;
00143 }
00144
00145 bool IsAvailable()
00146 {
00147 if (fUsed) {
00148 return false;
00149 } else {
00150 fUsed = true;
00151 return true;
00152 }
00153 }
00154
00155 } POST_PACKED_STRUCTURE;
00156
00161 template <int SIZE>
00162 class JackFixedMatrix
00163 {
00164 private:
00165
00166 jack_int_t fTable[SIZE][SIZE];
00167
00168 public:
00169
00170 JackFixedMatrix()
00171 {}
00172
00173 void Init(jack_int_t index)
00174 {
00175 for (int i = 0; i < SIZE; i++) {
00176 fTable[index][i] = 0;
00177 fTable[i][index] = 0;
00178 }
00179 }
00180
00181 const jack_int_t* GetItems(jack_int_t index) const
00182 {
00183 return fTable[index];
00184 }
00185
00186 jack_int_t IncItem(jack_int_t index1, jack_int_t index2)
00187 {
00188 fTable[index1][index2]++;
00189 return fTable[index1][index2];
00190 }
00191
00192 jack_int_t DecItem(jack_int_t index1, jack_int_t index2)
00193 {
00194 fTable[index1][index2]--;
00195 return fTable[index1][index2];
00196 }
00197
00198 jack_int_t GetItemCount(jack_int_t index1, jack_int_t index2) const
00199 {
00200 return fTable[index1][index2];
00201 }
00202
00203 void ClearItem(jack_int_t index1, jack_int_t index2)
00204 {
00205 fTable[index1][index2] = 0;
00206 }
00207
00211 void GetOutputTable(jack_int_t index, jack_int_t* output) const
00212 {
00213 int i, j;
00214
00215 for (i = 0; i < SIZE; i++)
00216 output[i] = EMPTY;
00217
00218 for (i = 0, j = 0; i < SIZE; i++) {
00219 if (fTable[index][i] > 0) {
00220 output[j] = i;
00221 j++;
00222 }
00223 }
00224 }
00225
00226 void GetOutputTable1(jack_int_t index, jack_int_t* output) const
00227 {
00228 for (int i = 0; i < SIZE; i++) {
00229 output[i] = fTable[i][index];
00230 }
00231 }
00232
00233 bool IsInsideTable(jack_int_t index, jack_int_t* output) const
00234 {
00235 for (int i = 0; i < SIZE && output[i] != EMPTY; i++) {
00236 if (output[i] == index)
00237 return true;
00238 }
00239 return false;
00240 }
00241
00242 void Copy(JackFixedMatrix& copy)
00243 {
00244 for (int i = 0; i < SIZE; i++) {
00245 memcpy(copy.fTable[i], fTable[i], sizeof(jack_int_t) * SIZE);
00246 }
00247 }
00248
00249
00250 } POST_PACKED_STRUCTURE;
00251
00256 template <int SIZE>
00257 class JackLoopFeedback
00258 {
00259 private:
00260
00261 int fTable[SIZE][3];
00262
00266 bool AddConnectionAux(int ref1, int ref2)
00267 {
00268 for (int i = 0; i < SIZE; i++) {
00269 if (fTable[i][0] == EMPTY) {
00270 fTable[i][0] = ref1;
00271 fTable[i][1] = ref2;
00272 fTable[i][2] = 1;
00273 jack_log("JackLoopFeedback::AddConnectionAux ref1 = %ld ref2 = %ld", ref1, ref2);
00274 return true;
00275 }
00276 }
00277 jack_error("Feedback table is full !!\n");
00278 return false;
00279 }
00280
00284 bool RemoveConnectionAux(int ref1, int ref2)
00285 {
00286 for (int i = 0; i < SIZE; i++) {
00287 if (fTable[i][0] == ref1 && fTable[i][1] == ref2) {
00288 fTable[i][0] = EMPTY;
00289 fTable[i][1] = EMPTY;
00290 fTable[i][2] = 0;
00291 jack_log("JackLoopFeedback::RemoveConnectionAux ref1 = %ld ref2 = %ld", ref1, ref2);
00292 return true;
00293 }
00294 }
00295 jack_error("Feedback connection not found\n");
00296 return false;
00297 }
00298
00299 int IncConnection(int index)
00300 {
00301 fTable[index][2]++;
00302 return fTable[index][2];
00303 }
00304
00305 int DecConnection(int index)
00306 {
00307 fTable[index][2]--;
00308 return fTable[index][2];
00309 }
00310
00311 public:
00312
00313 JackLoopFeedback()
00314 {
00315 Init();
00316 }
00317
00318 void Init()
00319 {
00320 for (int i = 0; i < SIZE; i++) {
00321 fTable[i][0] = EMPTY;
00322 fTable[i][1] = EMPTY;
00323 fTable[i][2] = 0;
00324 }
00325 }
00326
00327 bool IncConnection(int ref1, int ref2)
00328 {
00329 int index = GetConnectionIndex(ref1, ref2);
00330
00331 if (index >= 0) {
00332 IncConnection(index);
00333 return true;
00334 } else {
00335 return AddConnectionAux(ref1, ref2);
00336 }
00337 }
00338
00339 bool DecConnection(int ref1, int ref2)
00340 {
00341 int index = GetConnectionIndex(ref1, ref2);
00342
00343 if (index >= 0) {
00344 jack_log("JackLoopFeedback::DecConnection ref1 = %ld ref2 = %ld index = %ld", ref1, ref2, index);
00345 return (DecConnection(index) == 0) ? RemoveConnectionAux(ref1, ref2) : true;
00346 } else {
00347 return false;
00348 }
00349 }
00350
00354 int GetConnectionIndex(int ref1, int ref2) const
00355 {
00356 for (int i = 0; i < SIZE; i++) {
00357 if (fTable[i][0] == ref1 && fTable[i][1] == ref2)
00358 return i;
00359 }
00360 return -1;
00361 }
00362
00363 } POST_PACKED_STRUCTURE;
00364
00369 struct JackClientTiming
00370 {
00371 jack_time_t fSignaledAt;
00372 jack_time_t fAwakeAt;
00373 jack_time_t fFinishedAt;
00374 jack_client_state_t fStatus;
00375
00376 JackClientTiming()
00377 {
00378 Init();
00379 }
00380 ~JackClientTiming()
00381 {}
00382
00383 void Init()
00384 {
00385 fSignaledAt = 0;
00386 fAwakeAt = 0;
00387 fFinishedAt = 0;
00388 fStatus = NotTriggered;
00389 }
00390
00391 } POST_PACKED_STRUCTURE;
00392
00405 class SERVER_EXPORT JackConnectionManager
00406 {
00407
00408 private:
00409
00410 JackFixedArray<CONNECTION_NUM_FOR_PORT> fConnection[PORT_NUM_MAX];
00411 JackFixedArray1<PORT_NUM_FOR_CLIENT> fInputPort[CLIENT_NUM];
00412 JackFixedArray<PORT_NUM_FOR_CLIENT> fOutputPort[CLIENT_NUM];
00413 JackFixedMatrix<CLIENT_NUM> fConnectionRef;
00414 JackActivationCount fInputCounter[CLIENT_NUM];
00415 JackLoopFeedback<CONNECTION_NUM_FOR_PORT> fLoopFeedback;
00417 bool IsLoopPathAux(int ref1, int ref2) const;
00418
00419 public:
00420
00421 JackConnectionManager();
00422 ~JackConnectionManager();
00423
00424
00425 int Connect(jack_port_id_t port_src, jack_port_id_t port_dst);
00426 int Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst);
00427 bool IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00428
00432 jack_int_t Connections(jack_port_id_t port_index) const
00433 {
00434 return fConnection[port_index].GetItemCount();
00435 }
00436
00437 jack_port_id_t GetPort(jack_port_id_t port_index, int connection) const
00438 {
00439 assert(connection < CONNECTION_NUM_FOR_PORT);
00440 return (jack_port_id_t)fConnection[port_index].GetItem(connection);
00441 }
00442
00443 const jack_int_t* GetConnections(jack_port_id_t port_index) const;
00444
00445 bool IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00446 bool DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00447 bool IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00448
00449 bool IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00450 void IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00451 void DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00452
00453
00454 int AddInputPort(int refnum, jack_port_id_t port_index);
00455 int AddOutputPort(int refnum, jack_port_id_t port_index);
00456
00457 int RemoveInputPort(int refnum, jack_port_id_t port_index);
00458 int RemoveOutputPort(int refnum, jack_port_id_t port_index);
00459
00460 const jack_int_t* GetInputPorts(int refnum);
00461 const jack_int_t* GetOutputPorts(int refnum);
00462
00463
00464 void InitRefNum(int refnum);
00465 int GetInputRefNum(jack_port_id_t port_index) const;
00466 int GetOutputRefNum(jack_port_id_t port_index) const;
00467
00468
00469 bool IsDirectConnection(int ref1, int ref2) const;
00470 void DirectConnect(int ref1, int ref2);
00471 void DirectDisconnect(int ref1, int ref2);
00472
00473 int GetActivation(int refnum) const
00474 {
00475 return fInputCounter[refnum].GetValue();
00476 }
00477
00478
00479 void ResetGraph(JackClientTiming* timing);
00480 int ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing);
00481 int SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec);
00482 void TopologicalSort(std::vector<jack_int_t>& sorted);
00483
00484 } POST_PACKED_STRUCTURE;
00485
00486 }
00487
00488 #endif
00489