/*----------------------------------------------------------------------- | l1 := l1||l2; l2 := empty | The elements themselves are not moved, so pointers to them remain valid. | | l1 gets all the elements of l1 in their original order followed by | all the elements of l2 in the order they were in in l2. | l2 becomes empty. ------------------------------------------------------------------------*/ void APIENTRY List_Join( LIST l1, LIST l2 ) { if ((l1==NULL)||(l2==NULL)) { TRACE_ERROR("Bug: List_Join of bogus list. Continuing...", FALSE); return; } l1->bOK = l1->bOK &&l2->bOK; /* result OK if both inputs OK */ l2->bOK = TRUE; /* as l2 always becomes empty */ if (l2->pitNext==l2) { /* no elements need moving */ } else if (l2->pitNext==l2) { SwitchLists(l1,l2); return; } else { l2->pitNext->pitPrev = l1->pitPrev; l1->pitPrev->pitNext = l2->pitNext; l1->pitPrev = l2->pitPrev; l1->pitPrev->pitNext = l1; l2->pitNext = l2; l2->pitPrev = l2; } }
/*----------------------------------------------------------------------- | Let L1 be *pl1 and L2 be *pl2 | L1 := L1[...Curs] || L2 || L1[Curs+1...]; L2 := empty | Curs=NULL means insert L2 at the start of L1 | The elements themselves are not moved, so pointers to them remain valid. | | L1 gets the elements of L1 from the start up to and including the element | that Curs points at, in their original order, | followed by all the elements that were in L2, in their original order, | followed by the rest of L1 ------------------------------------------------------------------------*/ void APIENTRY List_InsertListAfter( LIST l1, LIST l2, LPVOID Curs ) { LIST pitA; /* The element after Curs, could be anchor */ LIST pit; /* The start of the element that Curs points at | or the anchor block if Curs==NULL */ if ( (l1==NULL) || (l2==NULL)) { TRACE_ERROR("Bug: List_InsertListAfter with bogus list. Continuing...", FALSE); return; } l1->bOK = l1->bOK && l2->bOK; l2->bOK = TRUE; if (l2->pitNext==l2) { /* no elements need moving */ } else if ( l1->pitNext==l1) { /* the easy way to code this would be simply to switch the two | pointers l1 and l2, but they are value parameters and we don't | want to change that. */ SwitchLists(l1,l2); return; } else { if (Curs==NULL) { pit = l1; } else { MOVEBACK(Curs) pit = (LIST)Curs; } /* pit points to a block to insert after, could be anchor */ pitA = pit->pitNext; /* Cannot be same as P, already checked */ l2->pitNext->pitPrev = pit; /* P<-- elems-of-l2 A */ l2->pitPrev->pitNext = pitA; /* P<-- elems-of-l2 -->A */ pit->pitNext = l2->pitNext; /* P<-->elems-of-l2 -->A */ pitA->pitPrev = l2->pitPrev; /* P<-->elems-of-l2<-->A */ l2->pitNext = l2; l2->pitPrev = l2; } }
void MASTER::Proceed(ELEMENT* starting_element) { // listy u¿ywane podczas obliczeñ OUTPUT_LIST list1; OUTPUT_LIST list2; OUTPUT_LIST* current_list = &list1; OUTPUT_LIST* next_list = &list2; // utworzenie listy startowej InitProcessing(starting_element, elements_set, current_list); // g³ówna pêtla unsigned i; for (i = 0; i < elements_set.RetAmount() * 2; i++) { bool state_changed = false; // właściwe działanie elementów // (dla NANDÓW jest to albo odczytanie stanów wejściowych i propagacja // albo ustalenie stanu i wysłanie sygnału do nowych elementów (czyli dodanie ich do next_list) // dla pozostałych elementów jest to po prostu ustalenie stanu for (unsigned j = 0; j < current_list->retAmount(); j++) { state_changed |= (*current_list)[j]->element->Proceed(next_list); char u = (*current_list)[j]->element->RetId()+'0'; //MessageBox(hwnd, &u, "debug", MB_OK); } // zamiana wskaźników SwitchLists(current_list, next_list); if (starting_element && !state_changed) break; } //if (i && i == elements_set.RetAmount() * 2 && !unstable_system_notification) //{ // MessageBox(hwnd, "Podany układ jest niestabilny.", "NAND2", MB_OK); // unstable_system_notification = true; //} Paint(); return; }
/*----------------------------------------------------------------------- | Let l1 be l1 and l2 be l2 | Split l2 off from the front of l1: final l2,l1 = original l1 | | Split l1 into l2: objects of l1 up to and including Curs object | l1: objects of l1 after Curs | Any original contents of l2 are freed. | List_Spilt(l1, l2, NULL) splits l1 before the first object so l1 gets all. | The elements themselves are not moved. ------------------------------------------------------------------------*/ void APIENTRY List_SplitAfter( LIST l1, LIST l2, LPVOID Curs ) { LIST pit; if ((l1==NULL) || (l2==NULL)) { TRACE_ERROR("Bug: List_SplitAfter bogus list. Continuing...", FALSE); return; } if (l2->pitNext!=l2) { List_Clear(l2); }; if (Curs!=NULL) { MOVEBACK(Curs) pit = (LIST)Curs; /* Curs had better be an item in l1! l2 had better be created! */ if (pit==l1) { l1->bOK = FALSE; l2->bOK = FALSE; return; } if (pit->pitNext==l1) { /* transfer whole of l2 to l1 */ SwitchLists(l2,l1); return; } l2->pitPrev = pit; l2->pitNext = l1->pitNext; l1->pitNext = pit->pitNext; pit->pitNext = l2; l2->pitNext->pitPrev = l2; l1->pitNext->pitPrev = l1; } }
/*---------------------------------------------------------------------- | Split l2 off from the back of l1: final l1,l2 = original l1 | | Split l1 into l1: objects of l1 up to but not including Curs object | l2: objects of l1 from Curs onwards | Any original contants of l2 are freed. | List_Spilt(l1, l2, NULL) splits l1 after the last object so l1 gets all. | The elements themselves are not moved. -----------------------------------------------------------------------*/ void APIENTRY List_SplitBefore( LIST l1, LIST l2, LPVOID Curs ) { LIST pit; if ((l1==NULL) || (l2==NULL)) { TRACE_ERROR("Bug: List_SplitBefore bogus list. Continuing...", FALSE); return; } if (l2->pitNext!=l2) { List_Clear(l2); } if (Curs!=NULL) { MOVEBACK(Curs) pit = (LIST)Curs; /* Curs had better be an item in L1! L2 had better be created! */ if (pit==l1) { l1->bOK = FALSE; l2->bOK = FALSE; return; } if (pit->pitPrev==l1) { SwitchLists(l2,l1); return; } l2->pitNext = pit; l2->pitPrev = l1->pitPrev; l1->pitPrev = pit->pitPrev; pit->pitPrev = l2; l2->pitPrev->pitNext = l2; l1->pitPrev->pitNext = l1; } }