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 };
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
00160 template <int SIZE>
00161 class JackFixedMatrix
00162 {
00163 private:
00164
00165 jack_int_t fTable[SIZE][SIZE];
00166
00167 public:
00168
00169 JackFixedMatrix()
00170 {}
00171
00172 void Init(jack_int_t index)
00173 {
00174 for (int i = 0; i < SIZE; i++) {
00175 fTable[index][i] = 0;
00176 fTable[i][index] = 0;
00177 }
00178 }
00179
00180 const jack_int_t* GetItems(jack_int_t index) const
00181 {
00182 return fTable[index];
00183 }
00184
00185 jack_int_t IncItem(jack_int_t index1, jack_int_t index2)
00186 {
00187 fTable[index1][index2]++;
00188 return fTable[index1][index2];
00189 }
00190
00191 jack_int_t DecItem(jack_int_t index1, jack_int_t index2)
00192 {
00193 fTable[index1][index2]--;
00194 return fTable[index1][index2];
00195 }
00196
00197 jack_int_t GetItemCount(jack_int_t index1, jack_int_t index2) const
00198 {
00199 return fTable[index1][index2];
00200 }
00201
00205 void GetOutputTable(jack_int_t index, jack_int_t* output) const
00206 {
00207 int i, j;
00208
00209 for (i = 0; i < SIZE; i++)
00210 output[i] = EMPTY;
00211
00212 for (i = 0, j = 0; i < SIZE; i++) {
00213 if (fTable[index][i] > 0) {
00214 output[j] = i;
00215 j++;
00216 }
00217 }
00218 }
00219
00220 bool IsInsideTable(jack_int_t index, jack_int_t* output) const
00221 {
00222 for (int i = 0; i < SIZE && output[i] != EMPTY; i++) {
00223 if (output[i] == index)
00224 return true;
00225 }
00226 return false;
00227 }
00228
00229 };
00230
00235 template <int SIZE>
00236 class JackLoopFeedback
00237 {
00238 private:
00239
00240 int fTable[SIZE][3];
00241
00245 bool AddConnectionAux(int ref1, int ref2)
00246 {
00247 for (int i = 0; i < SIZE; i++) {
00248 if (fTable[i][0] == EMPTY) {
00249 fTable[i][0] = ref1;
00250 fTable[i][1] = ref2;
00251 fTable[i][2] = 1;
00252 jack_log("JackLoopFeedback::AddConnectionAux ref1 = %ld ref2 = %ld", ref1, ref2);
00253 return true;
00254 }
00255 }
00256 jack_error("Feedback table is full !!\n");
00257 return false;
00258 }
00259
00263 bool RemoveConnectionAux(int ref1, int ref2)
00264 {
00265 for (int i = 0; i < SIZE; i++) {
00266 if (fTable[i][0] == ref1 && fTable[i][1] == ref2) {
00267 fTable[i][0] = EMPTY;
00268 fTable[i][1] = EMPTY;
00269 fTable[i][2] = 0;
00270 jack_log("JackLoopFeedback::RemoveConnectionAux ref1 = %ld ref2 = %ld", ref1, ref2);
00271 return true;
00272 }
00273 }
00274 jack_error("Feedback connection not found\n");
00275 return false;
00276 }
00277
00278 int IncConnection(int index)
00279 {
00280 fTable[index][2]++;
00281 return fTable[index][2];
00282 }
00283
00284 int DecConnection(int index)
00285 {
00286 fTable[index][2]--;
00287 return fTable[index][2];
00288 }
00289
00290 public:
00291
00292 JackLoopFeedback()
00293 {
00294 Init();
00295 }
00296
00297 void Init()
00298 {
00299 for (int i = 0; i < SIZE; i++) {
00300 fTable[i][0] = EMPTY;
00301 fTable[i][1] = EMPTY;
00302 fTable[i][2] = 0;
00303 }
00304 }
00305
00306 bool IncConnection(int ref1, int ref2)
00307 {
00308 int index = GetConnectionIndex(ref1, ref2);
00309
00310 if (index >= 0) {
00311 IncConnection(index);
00312 return true;
00313 } else {
00314 return AddConnectionAux(ref1, ref2);
00315 }
00316 }
00317
00318 bool DecConnection(int ref1, int ref2)
00319 {
00320 int index = GetConnectionIndex(ref1, ref2);
00321
00322 if (index >= 0) {
00323 jack_log("JackLoopFeedback::DecConnection ref1 = %ld ref2 = %ld index = %ld", ref1, ref2, index);
00324 return (DecConnection(index) == 0) ? RemoveConnectionAux(ref1, ref2) : true;
00325 } else {
00326 return false;
00327 }
00328 }
00329
00333 int GetConnectionIndex(int ref1, int ref2) const
00334 {
00335 for (int i = 0; i < SIZE; i++) {
00336 if (fTable[i][0] == ref1 && fTable[i][1] == ref2)
00337 return i;
00338 }
00339 return -1;
00340 }
00341
00342 };
00343
00348 struct JackClientTiming
00349 {
00350 jack_time_t fSignaledAt;
00351 jack_time_t fAwakeAt;
00352 jack_time_t fFinishedAt;
00353 jack_client_state_t fStatus;
00354
00355 JackClientTiming(): fSignaledAt(0), fAwakeAt(0), fFinishedAt(0), fStatus(NotTriggered)
00356 {}
00357 ~JackClientTiming()
00358 {}
00359 };
00360
00375 class SERVER_EXPORT JackConnectionManager
00376 {
00377
00378 private:
00379
00380 JackFixedArray<CONNECTION_NUM_FOR_PORT> fConnection[PORT_NUM];
00381 JackFixedArray1<PORT_NUM_FOR_CLIENT> fInputPort[CLIENT_NUM];
00382 JackFixedArray<PORT_NUM_FOR_CLIENT> fOutputPort[CLIENT_NUM];
00383 JackFixedMatrix<CLIENT_NUM> fConnectionRef;
00384 JackActivationCount fInputCounter[CLIENT_NUM];
00385 JackLoopFeedback<CONNECTION_NUM_FOR_PORT> fLoopFeedback;
00387 bool IsLoopPathAux(int ref1, int ref2) const;
00388
00389 public:
00390
00391 JackConnectionManager();
00392 ~JackConnectionManager();
00393
00394
00395 int Connect(jack_port_id_t port_src, jack_port_id_t port_dst);
00396 int Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst);
00397 bool IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00398
00402 jack_int_t Connections(jack_port_id_t port_index) const
00403 {
00404 return fConnection[port_index].GetItemCount();
00405 }
00406
00407 jack_port_id_t GetPort(jack_port_id_t port_index, int connection) const
00408 {
00409 assert(connection < CONNECTION_NUM_FOR_PORT);
00410 return (jack_port_id_t)fConnection[port_index].GetItem(connection);
00411 }
00412
00413 const jack_int_t* GetConnections(jack_port_id_t port_index) const;
00414
00415 bool IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00416 bool DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00417 bool IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00418
00419 bool IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00420 void IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00421 void DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00422
00423
00424 int AddInputPort(int refnum, jack_port_id_t port_index);
00425 int AddOutputPort(int refnum, jack_port_id_t port_index);
00426
00427 int RemoveInputPort(int refnum, jack_port_id_t port_index);
00428 int RemoveOutputPort(int refnum, jack_port_id_t port_index);
00429
00430 const jack_int_t* GetInputPorts(int refnum);
00431 const jack_int_t* GetOutputPorts(int refnum);
00432
00433
00434 void InitRefNum(int refnum);
00435 int GetInputRefNum(jack_port_id_t port_index) const;
00436 int GetOutputRefNum(jack_port_id_t port_index) const;
00437
00438
00439 bool IsDirectConnection(int ref1, int ref2) const;
00440 void DirectConnect(int ref1, int ref2);
00441 void DirectDisconnect(int ref1, int ref2);
00442
00443 int GetActivation(int refnum) const
00444 {
00445 return fInputCounter[refnum].GetValue();
00446 }
00447
00448
00449
00450
00451 void ResetGraph(JackClientTiming* timing);
00452 int ResumeRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing);
00453 int SuspendRefNum(JackClientControl* control, JackSynchro* table, JackClientTiming* timing, long time_out_usec);
00454 };
00455
00456 }
00457
00458 #endif
00459