Jack2 1.9.7

JackConnectionManager.h

00001 /*
00002 Copyright (C) 2004-2008 Grame
00003 
00004 This program is free software; you can redistribute it and/or modify
00005 it under the terms of the GNU Lesser General Public License as published by
00006 the Free Software Foundation; either version 2.1 of the License, or
00007 (at your option) any later version.
00008 
00009 This program is distributed in the hope that it will be useful,
00010 but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 GNU Lesser General Public License for more details.
00013 
00014 You should have received a copy of the GNU Lesser General Public License
00015 along with this program; if not, write to the Free Software
00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
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                     // Shift all indexes
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) { // Feedback connection is already added, increment counter
00332                 IncConnection(index);
00333                 return true;
00334             } else {
00335                 return AddConnectionAux(ref1, ref2); // Add the feedback connection
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         // Connections management
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         // Ports management
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         // Client management
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         // Connect/Disconnect 2 refnum "directly"
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         // Graph
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 } // end of namespace
00487 
00488 #endif
00489 

Generated for Jack2 by doxygen 1.7.3