home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / NeoIntroPP3.0 folder / PowerPlant / NeoBench / Source / CNeoWindow.cp < prev    next >
Encoding:
Text File  |  1994-09-29  |  20.5 KB  |  782 lines  |  [TEXT/MMCC]

  1. /**********************************************************************
  2.   CNeoWindow.cp
  3.  
  4.   This window behaves differently than CWindow when it is Zoomed.
  5.   It is supposed to move to the center of the screen when the Zoom
  6.   button is pressed. So no matter where it is,  it will always
  7.   center when Zoom is pressed.
  8.  
  9.   The "Direction" argument to Zoom is meaningless and is ignored.
  10. **********************************************************************/
  11.  
  12. #include "NeoTypes.h"
  13. #include "CNeoWindow.h"
  14. #include CNeoDocNativeH
  15. #include CNeoDatabaseNativeH
  16. #include CNeoMetaClassH
  17. #include CNeoIndexIteratorH
  18. #include CNeoPersistNativeH
  19. #include "CRawText.h"
  20. #include <stdlib.h>
  21. #include <Timer.h>
  22. #include <Fonts.h>
  23. #include <UDrawingState.h>
  24. #include "LEditField.h"
  25. #include "LButton.h"
  26. #include "CFiller.h"
  27.  
  28. #include "CIDIndex.h"
  29.  
  30. #ifdef qNeoThreads
  31. static short default_threads[kMaxPhase + 1] = { 1, 2, 2, 2, 2 };
  32. #endif
  33.  
  34. long gLoopOverhead;    // Timer Manager Overhead
  35.  
  36. CNeoWindow::CNeoWindow(const ResIDT aResID, CNeoDocPP *aDocument)
  37.     : LWindow(aResID, windAttr_Regular + windAttr_Enabled + windAttr_Targetable, aDocument)
  38. {
  39.     short    height;
  40.     short    index, j;
  41.     short   hpos;
  42.     short    vpos;
  43.     long    value;
  44.     Point    pt;
  45.     Rect    bounds;
  46.     Rect    rect;
  47.  
  48. #ifdef qNeoThreads
  49.     fThreadCount = 0;
  50.     for (index = 0; index < kMaxThreads; index++)
  51.         fThreadInfo[index].thread = nil;
  52. #endif
  53.  
  54.     fRefresh = TRUE;
  55.     fIterator = nil;
  56.  
  57.     /**
  58.      ** Set the Min and Max value the window can be resized.
  59.      **  Note that we really don't want the user to resize it
  60.      **  so we make the min and max numbers the same.
  61.      **/
  62.     SetRect(&bounds, 0, 0, 390, 200);
  63.     pt.h = (qd.screenBits.bounds.right - (bounds.right - bounds.left)) / 2;
  64.     pt.v = (qd.screenBits.bounds.bottom - (bounds.bottom - bounds.top)) / 3;
  65.     height = GetMBarHeight() + 1;
  66.     pt.v = (pt.v > height ? pt.v : height);
  67.     rect.top = pt.v;
  68.     rect.bottom = bounds.bottom + (pt.v - bounds.top);
  69.     rect.left = pt.h;
  70.     rect.right = bounds.right + (pt.h - bounds.left);
  71.     DoSetBounds(rect);
  72.  
  73.     // -----------------------------------------------------------
  74.     // Set the thread counts for each phase
  75.     // -----------------------------------------------------------
  76.  
  77.     for (index = kMinPhase; index <= kMaxPhase; index++) {
  78.         fPhaseInfo[index].dirty = FALSE;
  79. #ifdef qNeoThreads
  80.         NeoAssert(default_threads[index] <= kMaxThreads);
  81.         fPhaseInfo[index].threadCount = default_threads[index];
  82. #endif
  83.     }
  84.  
  85.     // -----------------------------------------------------------
  86.     // Make the Stat Text Phase names going down
  87.     // -----------------------------------------------------------
  88.     vpos = V_TOTAL;
  89.  
  90.     for (index = kMinPhase; index <= kMaxPhase; index++) {
  91.         NeoPhaseNames[index] = new CRawText(this, PhaseNames[index], LEFT_STAT, vpos, PHASE_NAME_WID, STAT_HGT);
  92.         NeoPhaseNames[index]->SetTextTraitsID(NeoLeftStyleID);
  93.         vpos += V_DIST;
  94.     }
  95.  
  96.     // -----------------------------------------------------------
  97.     // Make the object size static text item.
  98.     // -----------------------------------------------------------
  99.  
  100.     vpos += 14;
  101.     fSizeStatic = new CRawText(this, "\pObject Size:", LEFT_STAT +75, vpos, PHASE_NAME_WID, STAT_HGT);
  102.     fSizeStatic->SetTextTraitsID(NeoLeftStyleID);
  103.  
  104.     // -----------------------------------------------------------
  105.     // Make the Editable Text boxes going down
  106.     // -----------------------------------------------------------
  107.     vpos = V_TOTAL;
  108.  
  109.     for (index = kMinPhase; index <= kMaxPhase; index++) {
  110.         NeoEditTexts[index] = new LEditField();
  111.         NeoEditTexts[index]->SetTextTraitsID(NeoTextStyleID);
  112.         NeoEditTexts[index]->SetKeyFilter((KeyFilterFunc)UKeyFilters::IntegerField);
  113.         NeoEditTexts[index]->Enable();
  114.         NeoEditTexts[index]->SelectAll();
  115.         NeoEditTexts[index]->PutInside(this);
  116.         NeoEditTexts[index]->SetDescriptor(Txts);
  117.         NeoEditTexts[index]->ResizeFrameTo(TOT_WID, TOT_HGT, FALSE);
  118.         NeoEditTexts[index]->PlaceInSuperImageAt(H_TOTAL, vpos, FALSE);
  119.         NeoEditTexts[index]->SetSuperCommander(this);
  120.         value = default_vals[index];
  121.         NeoEditTexts[index]->SetValue(value);
  122.         vpos += V_DIST;
  123.     }
  124.     NeoEditTexts[kMinPhase]->Activate();
  125.  
  126.     // -----------------------------------------------------------
  127.     // Make the object size static text items.
  128.     // -----------------------------------------------------------
  129.  
  130.     vpos += 14;
  131.     fSizeText = new LEditField();
  132.     fSizeText->SetTextTraitsID(NeoTextStyleID);
  133.     fSizeText->SetKeyFilter((KeyFilterFunc)UKeyFilters::IntegerField);
  134.     fSizeText->Enable();
  135.     fSizeText->SelectAll();
  136.     fSizeText->PutInside(this);
  137.     fSizeText->SetDescriptor(Txts);
  138.     fSizeText->ResizeFrameTo(SIZE_WID, TOT_HGT, FALSE);
  139.     fSizeText->PlaceInSuperImageAt(H_TOTAL +75, vpos, FALSE);
  140.     fSizeText->SetSuperCommander(this);
  141.     value = CFiller::GetLength();
  142.     fSizeText->SetValue(value);
  143.  
  144.     // -----------------------------------------------------------
  145.     // Make the Stat Text boxes going down and across
  146.     // -----------------------------------------------------------
  147.     vpos = V_STAT_START;
  148.  
  149.     for (index = kMinPhase; index <= kMaxPhase; index++) {
  150.         hpos = H_STAT_START;
  151.         for (j = kSoFar; j <= kMaxCol; j++) {
  152.             switch (j) {
  153.             case kSoFar:
  154.             case kPerObject:
  155.                 NeoRawTexts[index][j] = new CRawText(this, Txts, hpos, vpos, STAT_WID, STAT_HGT);
  156.                 break;
  157.  
  158.             case kTotal:
  159.                 NeoRawTexts[index][j] = new CTimeText(this, Txts, hpos, vpos, STAT_WID, STAT_HGT);
  160.                 break;
  161.             }
  162.             NeoRawTexts[index][j]->SetTextTraitsID(NeoRightStyleID);
  163.             hpos += H_DIST;
  164.         }
  165.         vpos += V_DIST;
  166.     }
  167.  
  168.     // -----------------------------------------------------------
  169.     // Create the Go button and disable it.
  170.     // -----------------------------------------------------------
  171.     NeoGoButton = new LButton();
  172.     NeoGoButton->PutInside(this);
  173.     NeoGoButton->SetGraphics(GO_RES_ID, GO_RES_ID +1);
  174.     NeoGoButton->PlaceInSuperImageAt(GO_LFT, GO_TOP, FALSE);
  175.     NeoGoButton->ResizeFrameTo(GO_WID, GO_HGT, FALSE);
  176.     NeoGoButton->SetValueMessage(cmdGO);
  177.     NeoGoButton->Show();
  178.     NeoGoButton->Activate();
  179.     NeoGoButton->Enable();
  180.     NeoGoButton->AddListener(this);
  181.  
  182.     // -----------------------------------------------------------
  183.     // Create the Stop button,  and disable it.
  184.     // -----------------------------------------------------------
  185.     NeoStopButton = new LButton();
  186.     NeoStopButton->PutInside(this);
  187.     NeoStopButton->SetGraphics(STOP_RES_ID, STOP_RES_ID +1);
  188.     NeoStopButton->PlaceInSuperImageAt(STOP_LFT, STOP_TOP, FALSE);
  189.     NeoStopButton->ResizeFrameTo(STOP_WID, STOP_HGT, FALSE);
  190.     NeoStopButton->SetValueMessage(cmdSTOP);
  191.     NeoStopButton->Show();
  192.     NeoStopButton->Activate();
  193.     NeoStopButton->Disable();
  194.     NeoStopButton->AddListener(this);
  195.  
  196.     //------------------------------------------------------------
  197.     // Now put in the default max value
  198.     //------------------------------------------------------------
  199.     for (index = kMinPhase; index <= kMaxPhase; index++) {
  200.         maxValue[index] = default_maxs[index];
  201.         minValue[index] = 0;
  202.     }
  203.  
  204.     ClearStatPanes();
  205.  
  206.     /**
  207.      ** Set the button state flag
  208.      **/
  209.     fState = kStop;
  210.  
  211.     fPhase = kNoPhase;            /* No phase yet    */
  212.  
  213.     // These three values are the running values that change
  214.     col_index = kMinCol;
  215.     for (index = kMinCol; index <= kMinCol; index++)
  216.         col_value[index] = 0;
  217.  
  218.     //
  219.     // Init the fields in the array.  The default values
  220.     // will be coming from the text in the TextEdit boxes.
  221.     //
  222.     for (index = kMinPhase; index <= kMaxPhase; index++) {
  223.         fPhaseInfo[index].target = 0;
  224.         fPhaseInfo[index].done = 0;
  225.         fPhaseInfo[index].committed = 0;
  226.         fPhaseInfo[index].soFar = 0;
  227.     }
  228.  
  229.     srand((unsigned int)clock());
  230.  
  231.     Enable();
  232.     Select();
  233.     Show();
  234.  
  235.     NeoStopButton->Disable();
  236.     NeoGoButton->Disable();
  237.     NeoGoButton->Enable();
  238. }
  239.  
  240. CNeoWindow::~CNeoWindow(void)
  241. {
  242. #ifdef qNeoThreads
  243.     killThreads();
  244. #endif
  245. }
  246.  
  247. /***
  248.  * DrawSelf
  249.  *
  250.  *    In this method, you draw whatever you need to display in
  251.  *    your pane. The area parameter gives the portion of the
  252.  *    pane that needs to be redrawn. Area is in frame coordinates.
  253.  *
  254.  ***/
  255.  
  256. void CNeoWindow::DrawSelf(void)
  257. {
  258.     Rect        rect;
  259.     Rect        frame;
  260.     PicHandle    pict;
  261.  
  262.     CalcLocalFrameRect(frame);
  263.     StColorPenState::Normalize();
  264.  
  265.     pict = ::GetPicture(kTitlePICTID);
  266.     NeoFailNil(pict);
  267.     rect = (*pict)->picFrame;
  268.     ::OffsetRect(&rect, -rect.left, -rect.top);
  269.     ::OffsetRect(&rect, H_TOTAL, 15);
  270.     ::DrawPicture(pict, &rect);
  271. }
  272.  
  273. /********************************************************************
  274.   For a particular index,   get the total number converted from the
  275.   TextBox string,  and compare it with the limits,  and if out of
  276.   limits,  adjust them to be back within the given limits.
  277. ********************************************************************/
  278. long    CNeoWindow::GetTotalNum(short index)
  279. {
  280.     long    value;
  281.  
  282.     if (index < kMinPhase || index > kMaxPhase)
  283.         return 0;
  284.  
  285.     value = NeoEditTexts[index]->GetValue();
  286.     if (value > maxValue[index]) {
  287.         NeoEditTexts[index]->SetValue(maxValue[index]);
  288.         value = maxValue[index];
  289.     }
  290.     if (value < minValue[index]) {
  291.         NeoEditTexts[index]->SetValue(minValue[index]);
  292.         value = minValue[index];
  293.  
  294.     }
  295.     return(value);
  296. }
  297.  
  298. /*******************************************************************
  299.   ClearStatPanes - Clears out the Stat text panes containing the
  300.   numbers calculated from the run.   Sets the numbers to Zero
  301.   in preparation for the run.
  302. *******************************************************************/
  303. void    CNeoWindow::ClearStatPanes(void)
  304. {
  305.     short    row;
  306.     short    column;
  307.  
  308.     for (row = kMinPhase; row <= kMaxPhase; row++)
  309.         for (column = kSoFar; column <= kMaxCol; column++) {
  310.             NeoRawTexts[row][column]->SetValue(0);
  311.             NeoRawTexts[row][column]->Refresh();
  312.         }
  313. }
  314.  
  315. /*******************************************************************
  316.   UpdateCol - Given an index into the phase array ( 0 - 4),  and
  317.   an index into the row (0 - 2),  we put the value into the
  318.   static text area of the dialog box.
  319. *******************************************************************/
  320. void CNeoWindow::UpdateCol(short aPhase, short aRow, long aValue)
  321. {
  322.     // Do error bounds checking,  because it spits and sparksten
  323.     // if these arrays are out of bounds.
  324.  
  325.     if (aPhase > kMaxPhase || aPhase < kMinPhase || aRow > kMaxCol || aRow < kMinCol)
  326.         return;
  327.  
  328.     NeoRawTexts[aPhase][aRow]->SetValue(aValue);
  329.     NeoRawTexts[aPhase][aRow]->Refresh();
  330. }
  331.  
  332.  
  333. short CNeoWindow::getPhase(void) const
  334. {
  335.     return fPhase;
  336. }
  337.  
  338. long CNeoWindow::getPhaseTarget(const short aPhase) const
  339. {
  340.     return fPhaseInfo[aPhase].target;
  341. }
  342.  
  343. Boolean CNeoWindow::getState(void) const
  344. {
  345.     return fState;
  346. }
  347.  
  348. #define CR 0x24
  349. /*******************************************************************
  350.  
  351. *******************************************************************/
  352. Boolean CNeoWindow::HandleKeyPress(const EventRecord &aEvent)
  353. {
  354.     Boolean        handled;
  355.  
  356.     if ((aEvent.message&charCodeMask) == CR) {
  357.         if (fState == kStop)
  358.             ListenToMessage(cmdGO, nil);
  359.         else
  360.             ListenToMessage(cmdSTOP, nil);
  361.         handled = TRUE;
  362.     }
  363.     else
  364.         handled = LCommander::HandleKeyPress(aEvent);
  365.  
  366.     return handled;
  367. }
  368.  
  369. #ifdef qNeoThreads
  370. void CNeoWindow::killThreads(void)
  371. {
  372.     short    index;
  373.  
  374.     for (index = 0; index < kMaxThreads; index++) {
  375.         if (fThreadInfo[index].state == kAlive) {
  376.             NeoAssert(fThreadInfo[index].thread);
  377.             fThreadInfo[index].state = kDie;
  378.             CNeoThreadNative::Yield(fThreadInfo[index].thread);
  379.             fThreadInfo[index].thread = nil;
  380.         }
  381.     }
  382. }
  383. #endif
  384.  
  385. void CNeoWindow::ListenToMessage(MessageT aMessage, void *aParam)
  386. {
  387.     switch (aMessage) {
  388.     case cmdGO:
  389.         setState(kStart);
  390.         break;
  391.  
  392.     case cmdSTOP:
  393.         setState(kStop);
  394.         break;
  395.     }
  396. }
  397.  
  398. void CNeoWindow::setDocument(CNeoDocPP *aDocument)
  399. {
  400.     CNeoDatabasePP *    database;
  401.  
  402.     database = aDocument->getDatabase();
  403.  
  404.     if (database)
  405.         checkDatabaseState();
  406. }
  407.  
  408. void CNeoWindow::checkDatabaseState(void)
  409. {
  410.     long            tryFor;
  411.     long            actual;
  412.     CNeoDocPP *        document    = (CNeoDocPP *)GetSuperCommander();
  413.     CNeoDatabase *    database    = document->getDatabase();
  414.  
  415.     fPhaseInfo[kInsert].delta = database->getObjectCount(kFillerID, FALSE);
  416.     if (fPhaseInfo[kInsert].delta) {
  417.         UpdateCol(kInsert, kSoFar, fPhaseInfo[kInsert].delta);
  418.         tryFor = database->getVersion();
  419.         actual = CFiller::SetLength(tryFor);
  420.         NeoAssert(actual <= tryFor);
  421.         fSizeText->SetValue(actual);
  422.     }
  423.     else {
  424.         tryFor = fSizeText->GetValue();
  425.         actual = CFiller::SetLength(tryFor);
  426.         database->setVersion(actual);
  427.         if (actual != tryFor)
  428.             fSizeText->SetValue(actual);
  429.     }
  430. }
  431.  
  432. void CNeoWindow::setPhase(const short aPhase)
  433. {
  434. #ifdef qNeoThreads
  435.     short    index;
  436.     short    count;
  437.  
  438.     if (aPhase >= kMinPhase &&
  439.         aPhase <= kMaxPhase)
  440.         count = fPhaseInfo[aPhase].threadCount;
  441.     else {
  442.         if (fIterator) {
  443.             delete fIterator;
  444.             fIterator = nil;
  445.         }
  446.         count = 0;
  447.     }
  448.  
  449.     for (index = 0; index < count; index++) {
  450.         fThreadInfo[index].window = this;
  451.         fThreadInfo[index].phase = aPhase;
  452.         fThreadInfo[index].state = kAlive;
  453.         if (index >= fThreadCount) {
  454.             fThreadInfo[index].thread = new CBenchThread(&fThreadInfo[index]);
  455.             fThreadCount++;
  456.             fThreadInfo[index].thread->Resume();
  457.         }
  458.     }
  459.  
  460.     for (index = fThreadCount; index > count; index--)
  461.         fThreadInfo[index].state = kDie;
  462. #endif
  463.  
  464.     fPhase = aPhase;
  465. }
  466.  
  467. void CNeoWindow::setState(const Boolean aState)
  468. {
  469.     short    index;
  470.     short    phase;
  471.  
  472.     if (aState == kStop) {
  473. #ifdef qNeoThreads
  474.         killThreads();
  475. #endif
  476.         StopIdling();
  477.         phase = kNoPhase;
  478.         NeoStopButton->Disable();
  479.         NeoGoButton->Enable();
  480.     }
  481.     else {
  482.         for (index = kMinPhase;  index <= kMaxPhase; index++) {
  483.             fPhaseInfo[index].target = GetTotalNum(index);
  484.             fPhaseInfo[index].done = 0;
  485.             fPhaseInfo[index].delta = 0;
  486.             fPhaseInfo[index].committed = 0;
  487.             fPhaseInfo[index].soFar = 0;
  488.         }
  489.  
  490.         checkDatabaseState();
  491.  
  492.         if (fPhaseInfo[kInsert].delta < fPhaseInfo[kInsert].target)
  493.             phase = kMinPhase;
  494.         else
  495.             phase = kRandomly;
  496.  
  497.         StartIdling();
  498.         NeoGoButton->Disable();
  499.         NeoStopButton->Enable();
  500.     }
  501.     NeoGoButton->Refresh();
  502.     NeoStopButton->Refresh();
  503.  
  504.     fState = aState;
  505.  
  506.     setPhase(phase);
  507. }
  508.  
  509. /******************************************************************************
  510.  SpendTime
  511.  ******************************************************************************/
  512. void CNeoWindow::SpendTime(const EventRecord &aEvent)
  513. {
  514.     short            index;
  515.     long            loops        = 0;
  516.     CNeoDocPP *        document    = (CNeoDocPP *)GetSuperCommander();
  517.     CNeoDatabase *    database    = document->getDatabase();
  518.  
  519.     NeoUsed(aEvent);
  520.     NeoUsed(loops);
  521.  
  522. #ifndef qNeoThreads
  523.     TMTask            timer;
  524.  
  525.     doSomeWork(fPhase, &timer);
  526. #endif
  527.  
  528.     for (index = kMinPhase; index <= kMaxPhase; index++) {
  529.         if (fPhaseInfo[index].dirty) {
  530.             UpdateCol(index, kSoFar, fPhaseInfo[index].delta + fPhaseInfo[index].committed);
  531.             UpdateCol(index, kPerObject, ((double)fPhaseInfo[index].committed / (double)(fPhaseInfo[index].soFar ? fPhaseInfo[index].soFar : 1)) * 1000000);
  532.             UpdateCol(index, kTotal, fPhaseInfo[index].soFar);
  533.             fPhaseInfo[index].dirty = FALSE;
  534.         }
  535.         fRefresh = FALSE;
  536.     }
  537.  
  538.     if (fPhase > kMaxPhase)
  539.         setState(kStop);
  540.  
  541. #ifdef qNeoThreads
  542.     loops = 0;
  543.     while (!fRefresh) {
  544.         LThread::Yield();
  545. #ifdef qNeoDebug
  546.         loops++;
  547.         if (loops > 1000) {
  548.             loops = 0;
  549.             break;
  550.         }
  551. #endif
  552.     }
  553. #endif
  554. }
  555.  
  556. /******************************************************************************
  557.  doSomeWork
  558.  ******************************************************************************/
  559. void CNeoWindow::doSomeWork(const short aPhase, TMTask *aTimer)
  560. {
  561.     long            done;
  562.     long            IveDone        = 0;
  563.     long            delta;
  564.     long            quantum;
  565.     NeoID            id;
  566.     CNeoPersist *    object;
  567.     CNeoDocPP *        document    = (CNeoDocPP *)GetSuperCommander();
  568.     CNeoDatabase *    oldDatabase    = gNeoDatabase;
  569.     CNeoDatabase *    database    = document->getDatabase();
  570.     TMTask            updateTask;
  571.  
  572. #ifdef qNeoThreads
  573.     quantum = 500 * fPhaseInfo[aPhase].threadCount;
  574. #else
  575.     quantum = 500;
  576. #endif
  577.     if (fPhaseInfo[aPhase].delta + fPhaseInfo[aPhase].done < fPhaseInfo[aPhase].target) {
  578.         gNeoDatabase = database;
  579.  
  580.         updateTask.tmAddr = nil;
  581.         updateTask.qType = 0;
  582.         updateTask.tmCount = 0;
  583.         updateTask.tmWakeUp = 0;
  584.         updateTask.tmReserved = 0;
  585.         InsXTime((QElem *)&updateTask);
  586.         PrimeTime((QElem *)&updateTask, quantum);
  587.  
  588.         aTimer->tmAddr = nil;
  589.         aTimer->qType = 0;
  590.         aTimer->tmCount = 0;
  591.         aTimer->tmWakeUp = 0;
  592.         aTimer->tmReserved = 0;
  593.         InsXTime((QElem *)aTimer);
  594.         PrimeTime((QElem *)aTimer, k30MicroMinutes);
  595.     
  596.         while ((updateTask.qType&0x8000) &&
  597.                (fPhaseInfo[aPhase].delta + fPhaseInfo[aPhase].done < fPhaseInfo[aPhase].target)) {
  598.     
  599.             fPhaseInfo[aPhase].done++;
  600.             IveDone++;
  601.  
  602.             switch (aPhase) {
  603.             case    kInsert:
  604.                 /*------------------------------------------------------*/
  605.                 /* Perform the code for record insertion sequence         */
  606.                 /*------------------------------------------------------*/
  607.                 object = new CFiller;
  608.                 FailNIL(object);
  609.                 delta = fPhaseInfo[kInsert].delta;
  610.                 done = fPhaseInfo[kInsert].done;
  611.                 object->fID = delta + done;
  612.                 database->addObject(object);
  613.                 document->setDirty();
  614.                 object->unrefer();
  615.                 break;
  616.  
  617.             case    kRandomly:
  618.                 /*------------------------------------------------------*/
  619.                 /* Perform the code for randomly searching sequence     */
  620.                 /*------------------------------------------------------*/
  621.                 id = (rand()&0x7FFFFFFF) % fPhaseInfo[kInsert].target;
  622.                 if (!id)
  623.                     id = fPhaseInfo[kInsert].target / 2;
  624.                 object = (CFiller *)CFiller::FindByID(database, kFillerID, id, FALSE, nil, nil);
  625.                 NeoAssert(object);
  626.                 object->unrefer();
  627.                 break;
  628.  
  629.             case    kSerially:
  630.                 /*------------------------------------------------------*/
  631.                 /* Serially iterate over a class of objects                */
  632.                 /*------------------------------------------------------*/
  633.                 if (fIterator) {
  634.                     object = fIterator->nextObject();
  635.                     if (!object) {
  636.                         fIterator->reset();
  637.                         object = fIterator->currentObject();
  638.                     }
  639.                 }
  640.                 else {
  641.                     fIterator = new CNeoIndexIterator(database, kFillerID, nil, FALSE, FALSE);
  642.                     object = fIterator->currentObject();
  643.                 }
  644.                 NeoAssert(object);
  645.                 break;
  646.  
  647.             case    kChange:
  648.                 /*------------------------------------------------------*/
  649.                 /* Perform the code for Change sequence here            */
  650.                 /*------------------------------------------------------*/
  651.                 if (fIterator) {
  652.                     object = fIterator->nextObject();
  653.                     if (!object) {
  654.                         fIterator->reset();
  655.                         object = fIterator->currentObject();
  656.                     }
  657.                 }
  658.                 else {
  659.                     fIterator = new CNeoIndexIterator(database, kFillerID);
  660.                     object = fIterator->currentObject();
  661.                 }
  662.                 NeoAssert(object);
  663.                 object->autoReferTo();
  664.                 object->setDirty();
  665.                 object->autoUnrefer();
  666.                 document->setDirty();
  667.                 break;
  668.  
  669.             case    kDelete:
  670.                 /*------------------------------------------------------*/
  671.                 /* Perform the code for Delete sequencing here            */
  672.                 /*------------------------------------------------------*/
  673.                 if (!fIterator)
  674.                     fIterator = new CNeoIndexIterator(database, kFillerID);
  675.                 object = fIterator->currentObject();
  676.                 NeoAssert(object);
  677.                 object->autoReferTo();
  678.                 fIterator->removeCurrent();
  679.                 object->autoUnrefer();
  680.                 break;
  681.             }
  682.         }
  683.  
  684.         if (database->isOpen() &&
  685.             document->isDirty() &&
  686.             CNeoPersist::FCacheUsed > (CNeoPersist::FCacheSize>>1)) {
  687.             if (aPhase == kDelete &&
  688.                 fPhaseInfo[aPhase].delta + fPhaseInfo[aPhase].done >= fPhaseInfo[aPhase].target)
  689.                 database->commit(TRUE);
  690.             else
  691.                 database->commit(FALSE);
  692.             document->setDirty(FALSE);
  693.         }
  694.  
  695.         RmvTime((QElem *)aTimer);
  696.         RmvTime((QElem *)&updateTask);
  697.  
  698.         if (aTimer->tmCount > 0)
  699.             fPhaseInfo[aPhase].soFar += -(k30MicroMinutes + aTimer->tmCount * 1000) - gLoopOverhead;
  700.         else
  701.             fPhaseInfo[aPhase].soFar += -(k30MicroMinutes - aTimer->tmCount) - gLoopOverhead;
  702.         fPhaseInfo[aPhase].committed += IveDone;
  703.         fPhaseInfo[aPhase].dirty = TRUE;
  704.         fRefresh = TRUE;
  705.  
  706.         gNeoDatabase = oldDatabase;
  707.     }
  708.     else {
  709.         setPhase(aPhase +1);
  710.         if (fIterator) {
  711.             fIterator->setForward(!fIterator->isForward());
  712.             fIterator->reset();
  713.         }
  714.     }
  715. }
  716.  
  717. void CNeoWindow::ClickInZoom(const EventRecord& inMacEvent, short inZoomDirection)    // Zoom can be in or out
  718. {
  719.     // Don't allow zooming
  720. }
  721.  
  722. #ifdef qNeoThreads
  723. CBenchThread::CBenchThread(ThreadInfo *aInfo, const NeoThreadType aType, void **aArg, const Size aStackSize, const NeoThreadOptions aOptions)
  724.     : CNeoThreadNative(aType, aArg, aStackSize, aOptions)
  725. {
  726.     fSetTimer = FALSE;
  727.     fTimer.qType = 0;
  728.     fInfo = aInfo;
  729. }
  730.  
  731. long CBenchThread::run(void)
  732. {
  733.     while (fInfo->state == kAlive) {
  734.         fInfo->window->doSomeWork(fInfo->phase, &fTimer);
  735.     
  736.         LThread::Yield();
  737.     }
  738.  
  739.     fInfo->thread = nil;
  740.  
  741.     return fResult;
  742. }
  743.  
  744. // ---------------------------------------------------------------------------
  745. //        • handleSwapIn
  746. // ---------------------------------------------------------------------------
  747. //    Callback to the Thread Manager.
  748. //    
  749. void CBenchThread::handleSwapIn(void)
  750. {
  751.     inherited::handleSwapIn();
  752.  
  753.     // turn timers back on
  754.     if (fSetTimer) {
  755.         InsXTime((QElem *)&fTimer);
  756.         PrimeTime((QElem *)&fTimer, 0);
  757.     }
  758. }
  759.  
  760. // ---------------------------------------------------------------------------
  761. //        • handleSwapOut
  762. // ---------------------------------------------------------------------------
  763. //    Callback to the Thread Manager.
  764. //    
  765. void CBenchThread::handleSwapOut(void)
  766. {
  767.     // turn timers off
  768.     fSetTimer = (((fTimer.qType)&0x8000) != 0);
  769.     RmvTime((QElem *)&fTimer);
  770.     if (fSetTimer) {
  771. //        if (fTimer.tmCount > 0)
  772. //            fTimer.tmCount += gLoopOverhead ;
  773. //        else
  774. //            fTimer.tmCount -= gLoopOverhead * 1000;
  775.     }
  776.  
  777.     inherited::handleSwapOut();
  778. }
  779.  
  780. #endif
  781.  
  782.