int ListApplyToEach (list_t list, int ascending, ListApplicationFunc funcToApply, void *callbackData) { int result = 0, index; if (!list || !funcToApply) goto Error; if (ascending) { for (index = 1; index <= ListNumItems (list); index++) { result = funcToApply (index, ListGetPtrToItem (list, index), callbackData); if (result < 0) goto Error; } } else { for (index = ListNumItems (list); index > 0 && index <= ListNumItems (list); index--) { result = funcToApply (index, ListGetPtrToItem (list, index), callbackData); if (result < 0) goto Error; } } Error: return result; }
/* * list1 = list1 + list2 */ int ListAppend (list_t list1, list_t list2) { int numItemsL1, numItemsL2; if (!list2) return 1; if (!list1) return 0; if ((*list1)->itemSize != (*list2)->itemSize) return 0; numItemsL1 = ListNumItems (list1); numItemsL2 = ListNumItems (list2); if (numItemsL2 == 0) return 1; if (!SetHandleSize ((Handle) list1, sizeof (ListStruct) + (numItemsL1 + numItemsL2) * (*list1)->itemSize)) { return 0; } (*list1)->numItems = numItemsL1 + numItemsL2; (*list1)->listSize = numItemsL1 + numItemsL2; memmove (ITEMPTR (list1, numItemsL1), ITEMPTR (list2, 0), numItemsL2 * (*list2)->itemSize); return 1; }
void setRobotCommand(ROBOT* rb,RTANK_ID rid, COMMAND_TYPE type) { if(testBit(sys->hsAuto,RB)>0) { MessagePopup("Robot is auto","Robot is auto!"); return; } if(testBit(rb->hsBusyStatus,RB) > 0) { MessagePopup("Robot is busy","Robot is busy!"); return; } if(testBit(rb->hsHomeStatus,RB) == 0 && type != HOME_COMMAND) { MessagePopup("Robot is not home","Robot is not home!"); return; } if(ListNumItems(rb->cmdList)) { MessagePopup("Robot is busy","Robot is busy!"); return; } ROBOT_COMMAND cmd; cmd.type = type; cmd.tid = sys->rtk[rid].tid; cmd.rid = rid; cmd.status = MANUAL_STATUS; ListInsertItem(rb->cmdList,&cmd, END_OF_LIST); }
/// HIFN Disconnects a Source VChan from all its Sink VChans static BOOL disconnectSourceVChan (SourceVChan_type* srcVChan) { if (!srcVChan) return FALSE; SinkVChan_type* sinkVChan = NULL; for (size_t i = 1; i <= ListNumItems(srcVChan->sinkVChans); i++) { sinkVChan = *(SinkVChan_type**)ListGetPtrToItem(srcVChan->sinkVChans, i); sinkVChan->sourceVChan = NULL; // if Sink VChan is open, close it if (sinkVChan->baseClass.isOpen) { sinkVChan->baseClass.isOpen = VChan_Closed; if (sinkVChan->baseClass.VChanStateChangeCBFptr) (*sinkVChan->baseClass.VChanStateChangeCBFptr) ((VChan_type*)sinkVChan, sinkVChan->baseClass.VChanOwner, sinkVChan->baseClass.isOpen); } } ListClear(srcVChan->sinkVChans); // if Source VChan is open, close it if (srcVChan->baseClass.isOpen) { srcVChan->baseClass.isOpen = VChan_Closed; if (srcVChan->baseClass.VChanStateChangeCBFptr) (*srcVChan->baseClass.VChanStateChangeCBFptr) ((VChan_type*)srcVChan, srcVChan->baseClass.VChanOwner, srcVChan->baseClass.isOpen); } return TRUE; }
/* * copy is only as large as necessary */ list_t ListCopy (list_t originalList) { list_t tempList = NULL; int numItems; if (!originalList) return NULL; tempList = ListCreate ((*originalList)->itemSize); if (tempList) { numItems = ListNumItems (originalList); if (!SetHandleSize ((Handle) tempList, sizeof (ListStruct) + numItems * (*tempList)->itemSize)) { ListDispose (tempList); return NULL; } (*tempList)->numItems = (*originalList)->numItems; (*tempList)->listSize = (*originalList)->numItems; (*tempList)->itemSize = (*originalList)->itemSize; (*tempList)->percentIncrease = (*originalList)->percentIncrease; (*tempList)->minNumItemsIncrease = (*originalList)->minNumItemsIncrease; memcpy (ITEMPTR (tempList, 0), ITEMPTR (originalList, 0), numItems * (*tempList)->itemSize); } return tempList; }
static BOOL SourceVChanIsConnected (SourceVChan_type* srcVChan) { if (ListNumItems(srcVChan->sinkVChans)) return TRUE; else return FALSE; }
int console_assign (int file, char *devname) { int flag, i; /* Check for valid file */ switch (file) { case stdin: flag = DEV_FLAGS_INPUT; break; case stdout: case stderr: flag = DEV_FLAGS_OUTPUT; break; default: return -1; } /* Check for valid device name */ for (i = 1; i <= ListNumItems (devlist); i++) { device_t *dev = ListGetPtrToItem (devlist, i); if (strcmp (devname, dev->name) == 0) { if (dev->flags & flag) return console_setfile (file, dev); return -1; } } return -1; }
int do_coninfo (cmd_tbl_t * cmd, int flag, int argc, char *argv[]) { int i, l; /* Scan for valid output and input devices */ puts ("List of available devices:\n"); for (i = 1; i <= ListNumItems (devlist); i++) { device_t *dev = ListGetPtrToItem (devlist, i); printf ("%-8s %08x %c%c%c ", dev->name, dev->flags, (dev->flags & DEV_FLAGS_SYSTEM) ? 'S' : '.', (dev->flags & DEV_FLAGS_INPUT) ? 'I' : '.', (dev->flags & DEV_FLAGS_OUTPUT) ? 'O' : '.'); for (l = 0; l < MAX_FILES; l++) { if (stdio_devices[l] == dev) { printf ("%s ", stdio_names[l]); } } putc ('\n'); } return 0; }
int SendDataPacket (SourceVChan_type* srcVChan, DataPacket_type** dataPacketPtr, BOOL srcVChanNeedsPacket, char** errorMsg) { INIT_ERR size_t nSinks = ListNumItems(srcVChan->sinkVChans); SinkVChan_type* sinkVChan = NULL; size_t nPacketsSent = 0; // counts to how many Sink VChans the packet has been sent successfuly size_t nPacketRecipients = 0; // counts the number of packet recipients // set packet counter // Note: Since the Source VChan is open, an active Sink VChan is also an open Sink VChan if (srcVChanNeedsPacket) { nPacketRecipients = GetNumOpenSinkVChans(srcVChan)+1; nPacketsSent++; } else nPacketRecipients = GetNumOpenSinkVChans(srcVChan); if (*dataPacketPtr) SetDataPacketCounter(*dataPacketPtr, nPacketRecipients); // if there are no recipients then dispose of the data packet if (!nPacketRecipients) { ReleaseDataPacket(dataPacketPtr); return 0; } // send data packet for (size_t i = 1; i <= nSinks; i++) { sinkVChan = *(SinkVChan_type**)ListGetPtrToItem(srcVChan->sinkVChans,i); if (!sinkVChan->baseClass.isOpen) continue; // forward packet only to open Sink VChans connected to this Source VChan // put data packet into Sink VChan TSQ CmtErrChk( CmtWriteTSQData(sinkVChan->tsqHndl, dataPacketPtr, 1, (int)sinkVChan->writeTimeout, NULL) ); nPacketsSent++; } *dataPacketPtr = NULL; // Data packet is considered to be consumed even if sending to some Sink VChans did not succeed // Sink VChans that did receive the data packet, can further process it and release it. return 0; CmtError: Cmt_ERR Error: // cleanup for (size_t i = 0; i < nPacketRecipients - nPacketsSent; i++) ReleaseDataPacket(dataPacketPtr); RETURN_ERR }
int device_deregister(char *devname) { int i,l,dev_index; device_t *dev = NULL; char temp_names[3][8]; dev_index=-1; for (i=1; i<=ListNumItems(devlist); i++) { dev = ListGetPtrToItem (devlist, i); if(strcmp(dev->name,devname)==0) { dev_index=i; break; } } if(dev_index<0) /* device not found */ return 0; /* get stdio devices (ListRemoveItem changes the dev list) */ for (l=0 ; l< MAX_FILES; l++) { if (stdio_devices[l] == dev) { /* Device is assigned -> report error */ return -1; } memcpy (&temp_names[l][0], stdio_devices[l]->name, sizeof(stdio_devices[l]->name)); } ListRemoveItem(devlist,NULL,dev_index); /* reassign Device list */ for (i=1; i<=ListNumItems(devlist); i++) { dev = ListGetPtrToItem (devlist, i); for (l=0 ; l< MAX_FILES; l++) { if(strcmp(dev->name,temp_names[l])==0) { stdio_devices[l] = dev; } } } return 0; }
void ListDisposePtrList (list_t list) { int index; int numItems; if (list) { numItems = ListNumItems (list); for (index = 1; index <= numItems; index++) free (*(void **) ListGetPtrToItem (list, index)); ListDispose (list); } }
/// HIFN Checks if a VChan object exists among a list of VChans of VChan_type*. /// OUT idx 1-based index of the found VChan object within the VChan list.Pass 0 if this is not needed. If item is not found, *idx is 0. /// HIRET TRUE if VChan exists, FALSE otherwise. BOOL VChanExists (ListType VChanList, VChan_type* VChan, size_t* idx) { VChan_type* VChanItem = NULL; size_t nVChans = ListNumItems(VChanList); for (size_t i = 1; i <= nVChans; i++) { VChanItem = *(VChan_type**)ListGetPtrToItem(VChanList, i); if (VChanItem == VChan) { if (idx) *idx = i; return TRUE; } } if (idx) *idx = 0; return FALSE; }
static size_t GetNumOpenSinkVChans (SourceVChan_type* srcVChan) { SinkVChan_type* sinkVChan = NULL; size_t nSinkVChans = ListNumItems(srcVChan->sinkVChans); size_t nOpenSinkVChans = 0; for (size_t i = 1; i <= nSinkVChans; i++) { sinkVChan = *(SinkVChan_type**)ListGetPtrToItem(srcVChan->sinkVChans, i); if (sinkVChan->baseClass.isOpen) nOpenSinkVChans++; } return nOpenSinkVChans; }
/// HIFN Searches for a given VChan name from a VChan list of VChan_type* and if found, returns a pointer to the VChan object. /// OUT idx 1-based index of VChan object in the list of VChans. Pass 0 if this is not needed. If item is not found, *idx is 0. /// HIRET Pointer to the found VChan_type* if VChan exists, NULL otherwise. VChan_type* VChanNameExists (ListType VChanList, char VChanName[], size_t* idx) { VChan_type* VChan = NULL; size_t nVChans = ListNumItems(VChanList); for (size_t i = 1; i <= nVChans; i++) { VChan = *(VChan_type**)ListGetPtrToItem(VChanList, i); if (!strcmp(VChan->name, VChanName)) { if (idx) *idx = i; return VChan; } } if (idx) *idx = 0; return NULL; }
/* search a device */ device_t *search_device (int flags, char *name) { int i, items; device_t *dev = NULL; items = ListNumItems (devlist); if (name == NULL) return dev; for (i = 1; i <= items; i++) { dev = ListGetPtrToItem (devlist, i); if ((dev->flags & flags) && (strcmp (name, dev->name) == 0)) { break; } } return dev; }
void DAQLabModule_empty (ListType* modules) { DAQLabModule_type** modPtrPtr; size_t nummodules = ListNumItems(*modules); if (!(*modules)) return; for (size_t i = 1; i <= nummodules; i++) { modPtrPtr = ListGetPtrToItem(*modules, i); // call discard method specific to each module (*(*modPtrPtr)->Discard)(modPtrPtr); } ListDispose(*modules); *modules = 0; }
stPosicion PAT_Informacion(char *c) { char cVelocidad[10]={0}; static int iElementos=0; stPosicion p = MistPosicion; //obtiene el indice de la velocidad iElementos = ListNumItems(miLista); for (int i=0;i<iElementos;i++) { ListGetItem(miLista, &p, i+1); if (CompareStrings(p.cDescripcion, 0, c, 0, 0)==0) { i=iElementos; } } return p; }
/// HIFN Connects a Source VChan and Sink VChan. If the provided Sink VChan is connected to another Source VChan, it is first disconnected from that Source VChan. /// HIFN If both Source and Sink VChans are active then they will be opened if they are closed. /// HIRET True if successful, False otherwise. BOOL VChan_Connect (SourceVChan_type* srcVChan, SinkVChan_type* sinkVChan) { if (!srcVChan || !sinkVChan) return FALSE; SinkVChan_type* connectedSinkVChan = NULL; size_t nSinks = ListNumItems(srcVChan->sinkVChans); // check if the provided Sink VChan is already connected to this Source VChan for (size_t i = 1; i <= nSinks; i++) { connectedSinkVChan = *(SinkVChan_type**)ListGetPtrToItem(srcVChan->sinkVChans, i); if (connectedSinkVChan == sinkVChan) return FALSE; } // if Sink VChan is already connected to another Source VChan, disconnect it from that Source VChan if (sinkVChan->sourceVChan) if(!VChan_Disconnect((VChan_type*)sinkVChan) ) return FALSE; // error // add sink to source's list of sinks if (!ListInsertItem(srcVChan->sinkVChans, &sinkVChan, END_OF_LIST)) return FALSE; // error // add Source VChan to Sink VChan sinkVChan->sourceVChan = srcVChan; // if both Sink and Source VChans are active, then open Sink VChan and also Source VChan if it is not open already if (srcVChan->baseClass.isActive && sinkVChan->baseClass.isActive) { // open Sink VChan sinkVChan->baseClass.isOpen = VChan_Open; if (sinkVChan->baseClass.VChanStateChangeCBFptr) (*sinkVChan->baseClass.VChanStateChangeCBFptr) ((VChan_type*)sinkVChan, sinkVChan->baseClass.VChanOwner, sinkVChan->baseClass.isOpen); // open Source VChan if not open already if (!srcVChan->baseClass.isOpen) { srcVChan->baseClass.isOpen = VChan_Open; if (srcVChan->baseClass.VChanStateChangeCBFptr) (*srcVChan->baseClass.VChanStateChangeCBFptr) ((VChan_type*)srcVChan, srcVChan->baseClass.VChanOwner, srcVChan->baseClass.isOpen); } } return TRUE; }
void SetSourceVChanDataType (SourceVChan_type* srcVChan, DLDataTypes dataType) { // disconnect Sink VChans if they are incompatible size_t nSinks = ListNumItems(srcVChan->sinkVChans); SinkVChan_type* sinkVChan; BOOL compatibleVChans; for (size_t i = 1; i <= nSinks; i++) { sinkVChan = *(SinkVChan_type**) ListGetPtrToItem(srcVChan->sinkVChans, i); compatibleVChans = FALSE; for (size_t j = 0; j < sinkVChan->nDataTypes; j++) if (srcVChan->dataType == sinkVChan->dataTypes[j]) { compatibleVChans = TRUE; break; } if (!compatibleVChans) VChan_Disconnect((VChan_type*)sinkVChan); } // change Source VChan data type srcVChan->dataType = dataType; }
static BOOL disconnectSinkVChan (SinkVChan_type* sinkVChan) { if (!sinkVChan) return FALSE; SinkVChan_type* connectedSinkVChan = NULL; SourceVChan_type* srcVChan = sinkVChan->sourceVChan; if (!srcVChan) return TRUE; // do nothing if there is no source to disconnect // remove Source VChan from Sink VChan sinkVChan->sourceVChan = NULL; // if Sink VChan is open, close it if (sinkVChan->baseClass.isOpen) { sinkVChan->baseClass.isOpen = VChan_Closed; if (sinkVChan->baseClass.VChanStateChangeCBFptr) (*sinkVChan->baseClass.VChanStateChangeCBFptr) ((VChan_type*)sinkVChan, sinkVChan->baseClass.VChanOwner, sinkVChan->baseClass.isOpen); } // remove Sink VChan from Source VChan for (size_t i = 1; i <= ListNumItems(srcVChan->sinkVChans); i++) { connectedSinkVChan = *(SinkVChan_type**)ListGetPtrToItem(srcVChan->sinkVChans, i); if (connectedSinkVChan == sinkVChan) { ListRemoveItem(srcVChan->sinkVChans, 0, i); // if Source VChan is open and there are no more active Sinks, then close Source VChan if (srcVChan->baseClass.isOpen && !GetNumActiveSinkVChans(srcVChan)) { srcVChan->baseClass.isOpen = VChan_Closed; if (srcVChan->baseClass.VChanStateChangeCBFptr) (*srcVChan->baseClass.VChanStateChangeCBFptr) ((VChan_type*)srcVChan, srcVChan->baseClass.VChanOwner, srcVChan->baseClass.isOpen); } return TRUE; } } return FALSE; }
void ListRemoveDuplicates (list_t list, CompareFunction compareFunction) { int numItems, index, startIndexForFind, duplicatesIndex; numItems = ListNumItems (list); for (index = 1; index < numItems; index++) { startIndexForFind = index + 1; while (startIndexForFind <= numItems) { duplicatesIndex = ListFindItem (list, ListGetPtrToItem (list, index), startIndexForFind, compareFunction); if (duplicatesIndex > 0) { ListRemoveItem (list, NULL, duplicatesIndex); numItems--; startIndexForFind = duplicatesIndex; } else { break; } } } }
int ENT_CalculaDesplazamientoPrueba() { //debe realizar un recorrido por los diferentes planos en busca de las velocidades y su neutral int iElementos=0; stPosicion Analisis[TOTAL_ANALISIS]={0}; int iPlanos[TOTAL_PLANOS]={0}; int iTotalPlanos=0; int iIndiceAnalisis=0; char cAnalisis[500]={0}; char c[30][30]={0}; char cPrimerNeutral[20]={0}; int iTotal=0; iElementos = ListNumItems(miLista); //el primer ciclo es para identificar el total de planos configurados for (int i=0;i<iElementos;i++) { stPosicion p; ListGetItem(miLista, &p, i+1); int iPosicionLibre=-1; int iExiste=0; //primero verifica que no se haya registrado el plano ya for (int j=0;j<TOTAL_PLANOS;j++) { if ((iPlanos[j] == 0) && (iPosicionLibre == -1)) iPosicionLibre=j; if (iPlanos[j] == p.iPlano) { iExiste = 1; break; } } //si el plano no ha sido registrado if (iExiste == 0) { iPlanos[iPosicionLibre] = p.iPlano; iTotalPlanos++; } } //ahora recorre cada uno de los planos localizando sus velocidades disponibles int iIndice=0; for (int j=0;j<iTotalPlanos;j++) { iIndiceAnalisis=0; //inicializa el arreglo de Analisis for (int i=0;i<TOTAL_ANALISIS;i++) Analisis[i].iTipo = -999; for (int i=0;i<iElementos;i++) { stPosicion p; ListGetItem(miLista, &p, i+1); if (iIndiceAnalisis!=3) { if (iPlanos[j] == p.iPlano) { Analisis[iIndiceAnalisis++] = p; } } else break; } //ahora ordena la informacion de Analisis como Velocidad - Neutral - Velocidad //Revisa si el elemento de la posicion 1 es diferente de Neutral if (Analisis[1].iTipo != NEUTRAL) { stPosicion p; //revisa si la primer posicion es neutral if (Analisis[0].iTipo == NEUTRAL) { p=Analisis[0]; Analisis[0] = Analisis[1]; Analisis[1] = p; } else { p=Analisis[2]; Analisis[2] = Analisis[1]; Analisis[1] = p; } } //Aqui tengo en Analisis los elementos del plano j //inicia con la neutral strcat(cAnalisis,Analisis[1].cDescripcion); strcat(cAnalisis,"->"); if (strlen(cPrimerNeutral)==0) { Fmt(cPrimerNeutral,"%s<%s",Analisis[1].cDescripcion); Fmt(cNeutralActual,"%s<%s",Analisis[1].cDescripcion); } for (int i=0;i<iIndiceAnalisis;i++) { strcat(cAnalisis,Analisis[i].cDescripcion); strcat(cAnalisis,"->"); } if (iIndiceAnalisis > 2) { //termina con la neutral strcat(cAnalisis,Analisis[1].cDescripcion); strcat(cAnalisis,"->"); } } strcat(cAnalisis,cPrimerNeutral); Fmt(cDesplazamientoPrueba,"%s<%s",cAnalisis); return 0; }
/* Called after the relocation - use desired console functions */ int console_init_r (void) { device_t *inputdev = NULL, *outputdev = NULL; int i, items = ListNumItems (devlist); #ifdef CONFIG_SPLASH_SCREEN /* suppress all output if splash screen is enabled and we have a bmp to display */ if (getenv("splashimage") != NULL) gd->flags |= GD_FLG_SILENT; #endif /* Scan devices looking for input and output devices */ for (i = 1; (i <= items) && ((inputdev == NULL) || (outputdev == NULL)); i++ ) { device_t *dev = ListGetPtrToItem (devlist, i); if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) { inputdev = dev; } if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) { outputdev = dev; } } /* Initializes output console first */ if (outputdev != NULL) { console_setfile (stdout, outputdev); console_setfile (stderr, outputdev); } /* Initializes input console */ if (inputdev != NULL) { console_setfile (stdin, inputdev); } gd->flags |= GD_FLG_DEVINIT; /* device initialization completed */ #ifndef CFG_CONSOLE_INFO_QUIET /* Print information */ puts ("In: "); if (stdio_devices[stdin] == NULL) { puts ("No input devices available!\n"); } else { printf ("%s\n", stdio_devices[stdin]->name); } puts ("Out: "); if (stdio_devices[stdout] == NULL) { puts ("No output devices available!\n"); } else { printf ("%s\n", stdio_devices[stdout]->name); } puts ("Err: "); if (stdio_devices[stderr] == NULL) { puts ("No error devices available!\n"); } else { printf ("%s\n", stdio_devices[stderr]->name); } #endif /* CFG_CONSOLE_INFO_QUIET */ /* Setting environment variables */ for (i = 0; i < 3; i++) { setenv (stdio_names[i], stdio_devices[i]->name); } #if 0 /* If nothing usable installed, use only the initial console */ if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) return (0); #endif return (0); }
int console_init_r (void) { device_t *inputdev = NULL, *outputdev = NULL; int i, items = ListNumItems (devlist); #ifdef CONFIG_SPLASH_SCREEN if (getenv("splashimage") != NULL) outputdev = search_device (DEV_FLAGS_OUTPUT, "nulldev"); #endif #ifdef CONFIG_SILENT_CONSOLE if (gd->flags & GD_FLG_SILENT) outputdev = search_device (DEV_FLAGS_OUTPUT, "nulldev"); #endif for (i = 1; (i <= items) && ((inputdev == NULL) || (outputdev == NULL)); i++ ) { device_t *dev = ListGetPtrToItem (devlist, i); if ((dev->flags & DEV_FLAGS_INPUT) && (inputdev == NULL)) { inputdev = dev; } if ((dev->flags & DEV_FLAGS_OUTPUT) && (outputdev == NULL)) { outputdev = dev; } } if (outputdev != NULL) { console_setfile (stdout, outputdev); console_setfile (stderr, outputdev); } if (inputdev != NULL) { console_setfile (stdin, inputdev); } gd->flags |= GD_FLG_DEVINIT; #ifndef CFG_CONSOLE_INFO_QUIET puts ("In: "); if (stdio_devices[stdin] == NULL) { puts ("No input devices available!\n"); } else { printf ("%s\n", stdio_devices[stdin]->name); } puts ("Out: "); if (stdio_devices[stdout] == NULL) { puts ("No output devices available!\n"); } else { printf ("%s\n", stdio_devices[stdout]->name); } puts ("Err: "); if (stdio_devices[stderr] == NULL) { puts ("No error devices available!\n"); } else { printf ("%s\n", stdio_devices[stderr]->name); } #endif for (i = 0; i < 3; i++) { setenv (stdio_names[i], stdio_devices[i]->name); } #if 0 if ((stdio_devices[stdin] == NULL) && (stdio_devices[stdout] == NULL)) return (0); #endif return (0); }
void SetVChanActive (VChan_type* VChan, BOOL isActive) { // if it has the same active/inactive status, do nothing if (VChan->isActive == isActive) return; // update active/inactive VChan->isActive = isActive; // open/close VChans if neccessary switch (VChan->dataFlow) { case VChan_Source: if (VChan->isActive) { // Inactive -> Active // Source VChan is closed. Open Source VChan if it has at least an active Sink VChan if (GetNumActiveSinkVChans((SourceVChan_type*)VChan)) { VChan->isOpen = VChan_Open; if (VChan->VChanStateChangeCBFptr) (*VChan->VChanStateChangeCBFptr) (VChan, VChan->VChanOwner, VChan->isOpen); } // Sink VChans are closed. Open active Sink VChans. SinkVChan_type* sinkVChan = NULL; size_t nSinks = ListNumItems(((SourceVChan_type*)VChan)->sinkVChans); for (size_t i = 1; i <= nSinks; i++) { sinkVChan = *(SinkVChan_type**)ListGetPtrToItem(((SourceVChan_type*)VChan)->sinkVChans, i); if (!sinkVChan->baseClass.isActive) continue; // skip inactive Sink VChans sinkVChan->baseClass.isOpen = VChan_Open; if (sinkVChan->baseClass.VChanStateChangeCBFptr) (*sinkVChan->baseClass.VChanStateChangeCBFptr) ((VChan_type*)sinkVChan, sinkVChan->baseClass.VChanOwner, sinkVChan->baseClass.isOpen); } } else { // Active -> Inactive // If Source VChan is open, then close it if (VChan->isOpen) { VChan->isOpen = VChan_Closed; if (VChan->VChanStateChangeCBFptr) (*VChan->VChanStateChangeCBFptr) (VChan, VChan->VChanOwner, VChan->isOpen); } // Close all open Sink VChans SinkVChan_type* sinkVChan = NULL; size_t nSinks = ListNumItems(((SourceVChan_type*)VChan)->sinkVChans); for (size_t i = 1; i <= nSinks; i++) { sinkVChan = *(SinkVChan_type**)ListGetPtrToItem(((SourceVChan_type*)VChan)->sinkVChans, i); if (!sinkVChan->baseClass.isOpen) continue; // skip closed Sink VChans sinkVChan->baseClass.isOpen = VChan_Closed; if (sinkVChan->baseClass.VChanStateChangeCBFptr) (*sinkVChan->baseClass.VChanStateChangeCBFptr) ((VChan_type*)sinkVChan, sinkVChan->baseClass.VChanOwner, sinkVChan->baseClass.isOpen); } } break; case VChan_Sink: if (VChan->isActive) { // Inactive -> Active // Sink VChan is closed, open Sink VChan if a Source VChan is attached to it and is active SourceVChan_type* srcVChan = ((SinkVChan_type*)VChan)->sourceVChan; if (srcVChan && srcVChan->baseClass.isActive) { VChan->isOpen = VChan_Open; if (VChan->VChanStateChangeCBFptr) (*VChan->VChanStateChangeCBFptr) (VChan, VChan->VChanOwner, VChan->isOpen); } // If Sink VChan has a closed active Source VChan, then open the Source VChan if (srcVChan && srcVChan->baseClass.isActive && !srcVChan->baseClass.isOpen) { srcVChan->baseClass.isOpen = VChan_Open; if (srcVChan->baseClass.VChanStateChangeCBFptr) (*srcVChan->baseClass.VChanStateChangeCBFptr) ((VChan_type*)srcVChan, srcVChan->baseClass.VChanOwner, srcVChan->baseClass.isOpen); } } else { // Active -> Inactive // Close Sink VChan if open if (VChan->isOpen) { VChan->isOpen = VChan_Closed; if (VChan->VChanStateChangeCBFptr) (*VChan->VChanStateChangeCBFptr) (VChan, VChan->VChanOwner, VChan->isOpen); } // If Sink has an open Source VChan and there are no more active Sinks, then close Source VChan SourceVChan_type* srcVChan = ((SinkVChan_type*)VChan)->sourceVChan; if (srcVChan && srcVChan->baseClass.isOpen && !GetNumActiveSinkVChans(srcVChan)) { srcVChan->baseClass.isOpen = VChan_Closed; if (srcVChan->baseClass.VChanStateChangeCBFptr) (*srcVChan->baseClass.VChanStateChangeCBFptr) ((VChan_type*)srcVChan, srcVChan->baseClass.VChanOwner, srcVChan->baseClass.isOpen); } } break; } }
size_t GetNSinkVChans (SourceVChan_type* srcVChan) { return ListNumItems(srcVChan->sinkVChans); }