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