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
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
00206 void GetOutputTable(jack_int_t index, jack_int_t* output) const
00207 {
00208 int i, j;
00209
00210 for (i = 0; i < SIZE; i++)
00211 output[i] = EMPTY;
00212
00213 for (i = 0, j = 0; i < SIZE; i++) {
00214 if (fTable[index][i] > 0) {
00215 output[j] = i;
00216 j++;
00217 }
00218 }
00219 }
00220
00221 bool IsInsideTable(jack_int_t index, jack_int_t* output) const
00222 {
00223 for (int i = 0; i < SIZE && output[i] != EMPTY; i++) {
00224 if (output[i] == index)
00225 return true;
00226 }
00227 return false;
00228 }
00229
00230 } POST_PACKED_STRUCTURE;
00231
00236 template <int SIZE>
00237 class JackLoopFeedback
00238 {
00239 private:
00240
00241 int fTable[SIZE][3];
00242
00246 bool AddConnectionAux(int ref1, int ref2)
00247 {
00248 for (int i = 0; i < SIZE; i++) {
00249 if (fTable[i][0] == EMPTY) {
00250 fTable[i][0] = ref1;
00251 fTable[i][1] = ref2;
00252 fTable[i][2] = 1;
00253 jack_log("JackLoopFeedback::AddConnectionAux ref1 = %ld ref2 = %ld", ref1, ref2);
00254 return true;
00255 }
00256 }
00257 jack_error("Feedback table is full !!\n");
00258 return false;
00259 }
00260
00264 bool RemoveConnectionAux(int ref1, int ref2)
00265 {
00266 for (int i = 0; i < SIZE; i++) {
00267 if (fTable[i][0] == ref1 && fTable[i][1] == ref2) {
00268 fTable[i][0] = EMPTY;
00269 fTable[i][1] = EMPTY;
00270 fTable[i][2] = 0;
00271 jack_log("JackLoopFeedback::RemoveConnectionAux ref1 = %ld ref2 = %ld", ref1, ref2);
00272 return true;
00273 }
00274 }
00275 jack_error("Feedback connection not found\n");
00276 return false;
00277 }
00278
00279 int IncConnection(int index)
00280 {
00281 fTable[index][2]++;
00282 return fTable[index][2];
00283 }
00284
00285 int DecConnection(int index)
00286 {
00287 fTable[index][2]--;
00288 return fTable[index][2];
00289 }
00290
00291 public:
00292
00293 JackLoopFeedback()
00294 {
00295 Init();
00296 }
00297
00298 void Init()
00299 {
00300 for (int i = 0; i < SIZE; i++) {
00301 fTable[i][0] = EMPTY;
00302 fTable[i][1] = EMPTY;
00303 fTable[i][2] = 0;
00304 }
00305 }
00306
00307 bool IncConnection(int ref1, int ref2)
00308 {
00309 int index = GetConnectionIndex(ref1, ref2);
00310
00311 if (index >= 0) {
00312 IncConnection(index);
00313 return true;
00314 } else {
00315 return AddConnectionAux(ref1, ref2);
00316 }
00317 }
00318
00319 bool DecConnection(int ref1, int ref2)
00320 {
00321 int index = GetConnectionIndex(ref1, ref2);
00322
00323 if (index >= 0) {
00324 jack_log("JackLoopFeedback::DecConnection ref1 = %ld ref2 = %ld index = %ld", ref1, ref2, index);
00325 return (DecConnection(index) == 0) ? RemoveConnectionAux(ref1, ref2) : true;
00326 } else {
00327 return false;
00328 }
00329 }
00330
00334 int GetConnectionIndex(int ref1, int ref2) const
00335 {
00336 for (int i = 0; i < SIZE; i++) {
00337 if (fTable[i][0] == ref1 && fTable[i][1] == ref2)
00338 return i;
00339 }
00340 return -1;
00341 }
00342
00343 } POST_PACKED_STRUCTURE;
00344
00349 struct JackClientTiming
00350 {
00351 jack_time_t fSignaledAt;
00352 jack_time_t fAwakeAt;
00353 jack_time_t fFinishedAt;
00354 jack_client_state_t fStatus;
00355
00356 JackClientTiming()
00357 {
00358 Init();
00359 }
00360 ~JackClientTiming()
00361 {}
00362
00363 void Init()
00364 {
00365 fSignaledAt = 0;
00366 fAwakeAt = 0;
00367 fFinishedAt = 0;
00368 fStatus = NotTriggered;
00369 }
00370
00371 } POST_PACKED_STRUCTURE;
00372
00387 class SERVER_EXPORT JackConnectionManager
00388 {
00389
00390 private:
00391
00392 JackFixedArray<CONNECTION_NUM_FOR_PORT> fConnection[PORT_NUM_MAX];
00393 JackFixedArray1<PORT_NUM_FOR_CLIENT> fInputPort[CLIENT_NUM];
00394 JackFixedArray<PORT_NUM_FOR_CLIENT> fOutputPort[CLIENT_NUM];
00395 JackFixedMatrix<CLIENT_NUM> fConnectionRef;
00396 JackActivationCount fInputCounter[CLIENT_NUM];
00397 JackLoopFeedback<CONNECTION_NUM_FOR_PORT> fLoopFeedback;
00399 bool IsLoopPathAux(int ref1, int ref2) const;
00400
00401 public:
00402
00403 JackConnectionManager();
00404 ~JackConnectionManager();
00405
00406
00407 int Connect(jack_port_id_t port_src, jack_port_id_t port_dst);
00408 int Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst);
00409 bool IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00410
00414 jack_int_t Connections(jack_port_id_t port_index) const
00415 {
00416 return fConnection[port_index].GetItemCount();
00417 }
00418
00419 jack_port_id_t GetPort(jack_port_id_t port_index, int connection) const
00420 {
00421 assert(connection < CONNECTION_NUM_FOR_PORT);
00422 return (jack_port_id_t)fConnection[port_index].GetItem(connection);
00423 }
00424
00425 const jack_int_t* GetConnections(jack_port_id_t port_index) const;
00426
00427 bool IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00428 bool DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00429 bool IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00430
00431 bool IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00432 void IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00433 void DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00434
00435
00436 int AddInputPort(int refnum, jack_port_id_t port_index);
00437 int AddOutputPort(int refnum, jack_port_id_t port_index);
00438
00439 int RemoveInputPort(int refnum, jack_port_id_t port_index);
00440 int RemoveOutputPort(int refnum, jack_port_id_t port_index);
00441
00442 const jack_int_t* GetInputPorts(int refnum);
00443 const jack_int_t* GetOutputPorts(int refnum);
00444
00445
00446 void InitRefNum(int refnum);
00447 int GetInputRefNum(jack_port_id_t port_index) const;
00448 int GetOutputRefNum(jack_port_id_t port_index) const;
00449
00450
00451 bool IsDirectConnection(int ref1, int ref2) const;
00452 void DirectConnect(int ref1, int ref2);
00453 void DirectDisconnect(int ref1, int ref2);
00454
00455 int GetActivation(int refnum) const
00456 {
00457 return fInputCounter[refnum].GetValue();
00458 }
00459
00460
00461 void ResetGraph(JackClientTiming* timing);
00462 int ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing);
00463 int SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec);
00464
00465 } POST_PACKED_STRUCTURE;
00466
00467 }
00468
00469 #endif
00470