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(): fSignaledAt(0), fAwakeAt(0), fFinishedAt(0), fStatus(NotTriggered)
00357 {}
00358 ~JackClientTiming()
00359 {}
00360
00361 } POST_PACKED_STRUCTURE;
00362
00377 class SERVER_EXPORT JackConnectionManager
00378 {
00379
00380 private:
00381
00382 JackFixedArray<CONNECTION_NUM_FOR_PORT> fConnection[PORT_NUM];
00383 JackFixedArray1<PORT_NUM_FOR_CLIENT> fInputPort[CLIENT_NUM];
00384 JackFixedArray<PORT_NUM_FOR_CLIENT> fOutputPort[CLIENT_NUM];
00385 JackFixedMatrix<CLIENT_NUM> fConnectionRef;
00386 JackActivationCount fInputCounter[CLIENT_NUM];
00387 JackLoopFeedback<CONNECTION_NUM_FOR_PORT> fLoopFeedback;
00389 bool IsLoopPathAux(int ref1, int ref2) const;
00390
00391 public:
00392
00393 JackConnectionManager();
00394 ~JackConnectionManager();
00395
00396
00397 int Connect(jack_port_id_t port_src, jack_port_id_t port_dst);
00398 int Disconnect(jack_port_id_t port_src, jack_port_id_t port_dst);
00399 bool IsConnected(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00400
00404 jack_int_t Connections(jack_port_id_t port_index) const
00405 {
00406 return fConnection[port_index].GetItemCount();
00407 }
00408
00409 jack_port_id_t GetPort(jack_port_id_t port_index, int connection) const
00410 {
00411 assert(connection < CONNECTION_NUM_FOR_PORT);
00412 return (jack_port_id_t)fConnection[port_index].GetItem(connection);
00413 }
00414
00415 const jack_int_t* GetConnections(jack_port_id_t port_index) const;
00416
00417 bool IncFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00418 bool DecFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00419 bool IsFeedbackConnection(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00420
00421 bool IsLoopPath(jack_port_id_t port_src, jack_port_id_t port_dst) const;
00422 void IncDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00423 void DecDirectConnection(jack_port_id_t port_src, jack_port_id_t port_dst);
00424
00425
00426 int AddInputPort(int refnum, jack_port_id_t port_index);
00427 int AddOutputPort(int refnum, jack_port_id_t port_index);
00428
00429 int RemoveInputPort(int refnum, jack_port_id_t port_index);
00430 int RemoveOutputPort(int refnum, jack_port_id_t port_index);
00431
00432 const jack_int_t* GetInputPorts(int refnum);
00433 const jack_int_t* GetOutputPorts(int refnum);
00434
00435
00436 void InitRefNum(int refnum);
00437 int GetInputRefNum(jack_port_id_t port_index) const;
00438 int GetOutputRefNum(jack_port_id_t port_index) const;
00439
00440
00441 bool IsDirectConnection(int ref1, int ref2) const;
00442 void DirectConnect(int ref1, int ref2);
00443 void DirectDisconnect(int ref1, int ref2);
00444
00445 int GetActivation(int refnum) const
00446 {
00447 return fInputCounter[refnum].GetValue();
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 } POST_PACKED_STRUCTURE;
00456
00457 }
00458
00459 #endif
00460