VirtualBox

Ignore:
Timestamp:
Sep 22, 2008 11:57:52 PM (16 years ago)
Author:
vboxsync
Message:

Debugger: coding.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Debugger/VBoxDbgStatsQt4.cpp

    r12521 r12660  
    140140    /** The name. */
    141141    char                   *pszName;
     142    /** The length of the name. */
     143    size_t                  cchName;
    142144    /** The description string. */
    143145    QString                *pDescStr;
     
    348350     *
    349351     * @param   a_pVM           The VM handle.
     352     * @param   a_rPatStr       The selection pattern.
    350353     * @param   a_pParent       The parent object. NULL is fine.
    351354     */
    352     VBoxDbgStatsModelVM(PVM a_pVM, QObject *a_pParent);
     355    VBoxDbgStatsModelVM(PVM a_pVM, QString &a_rPatStr, QObject *a_pParent);
    353356
    354357    /** Destructor */
     
    364367    virtual void update(const QString &a_rPatStr);
    365368
    366 private:
     369protected:
    367370    /**
    368371     * Enumeration callback used by update.
     
    387390     * @returns Pointer to the root of the tree we've constructed. This will be NULL
    388391     *          if the STAM API throws an error or we run out of memory.
    389      */
    390     PDBGGUISTATSNODE createNewTree(void);
     392     * @param   a_rPatStr       The selection pattern.
     393     */
     394    PDBGGUISTATSNODE createNewTree(QString &a_rPatStr);
     395
     396protected:
     397    /** Next update child. This is UINT32_MAX when invalid. */
     398    uint32_t m_iUpdateChild;
     399    /** Pointer to the node m_szUpdateParent represent and m_iUpdateChild refers to. */
     400    PDBGGUISTATSNODE m_pUpdateParent;
     401    /** The length of the path. */
     402    size_t m_cchUpdateParent;
     403    /** The path to the current update parent, including a trailing slash. */
     404    char m_szUpdateParent[1024];
     405    /** Inserted or/and removed nodes during the update. */
     406    bool m_fUpdateInsertRemove;
    391407};
    392408
     
    421437
    422438
     439#if 0
    423440/**
    424441 * Formats a number into a 64-byte buffer.
     
    448465    return psz;
    449466}
     467#endif
    450468
    451469
     
    625643    pRoot->enmUnit = STAMUNIT_INVALID;
    626644    pRoot->pszName = (char *)RTMemDup("/", sizeof("/"));
     645    pRoot->cchName = 1;
    627646    pRoot->enmState = kDbgGuiStatsNodeState_kRoot;
    628647
     
    644663    pNode->enmUnit = STAMUNIT_INVALID;
    645664    pNode->pszName = (char *)RTMemDupEx(pszName, cchName, 1);
     665    pNode->cchName = cchName;
    646666    pNode->enmState = kDbgGuiStatsNodeState_kVisible;
    647667
     
    10611081
    10621082
    1063 VBoxDbgStatsModelVM::VBoxDbgStatsModelVM(PVM a_pVM, QObject *a_pParent)
    1064     : VBoxDbgStatsModel(a_pParent), VBoxDbgBase(a_pVM)
    1065 {
    1066     /*
    1067      * Create a model containing *all* the STAM entries since this is is
    1068      * faster than adding stuff later. (And who cares about wasing a few MBs anyway...)
    1069      */
    1070     PDBGGUISTATSNODE pTree = createNewTree();
     1083VBoxDbgStatsModelVM::VBoxDbgStatsModelVM(PVM a_pVM, QString &a_rPatStr, QObject *a_pParent)
     1084    : VBoxDbgStatsModel(a_pParent), VBoxDbgBase(a_pVM),
     1085    m_iUpdateChild(UINT32_MAX), m_pUpdateParent(NULL), m_cchUpdateParent(0)
     1086{
     1087    /*
     1088     * Create a model containing the STAM entries matching the pattern.
     1089     * (The original idea was to get everything and rely on some hide/visible
     1090     * flag that it turned out didn't exist.)
     1091     */
     1092    PDBGGUISTATSNODE pTree = createNewTree(a_rPatStr);
    10711093    setRootNode(pTree);
    10721094}
     
    10761098{
    10771099    /* nothing to do here. */
     1100}
     1101
     1102
     1103static void resetNode(PDBGGUISTATSNODE pNode)
     1104{
     1105    /** @todo */
     1106}
     1107
     1108static void updateNode(PDBGGUISTATSNODE pNode, STAMTYPE enmType, void *pvSample, STAMUNIT enmUnit,
     1109                       STAMVISIBILITY enmVisibility, const char *pszDesc, void *pvUser)
     1110{
     1111    /** @todo */
     1112}
     1113
     1114static int32_t getNodePath(PCDBGGUISTATSNODE pNode, char *psz, ssize_t cch)
     1115{
     1116    int32_t off;
     1117    if (!pNode->pParent)
     1118    {
     1119        /* root - don't add it's slash! */
     1120        AssertReturn(cch >= 1, -1);
     1121        off = 0;
     1122        *psz = '\0';
     1123    }
     1124    else
     1125    {
     1126        cch -= pNode->cchName - 1;
     1127        AssertReturn(cch > 0, -1);
     1128        off = getNodePath(pNode->pParent, psz, cch);
     1129        if (off >= 0)
     1130        {
     1131            psz[off++] = '/';
     1132            memcpy(&psz[off], pNode->pszName, pNode->cchName + 1);
     1133            off += pNode->cchName;
     1134        }
     1135    }
     1136    return off;
     1137}
     1138
     1139static bool isNodeAncestorOf(PCDBGGUISTATSNODE pNode, PCDBGGUISTATSNODE pAncestor)
     1140{
     1141    while (pNode)
     1142    {
     1143        pNode = pNode->pParent;
     1144        if (pNode == pAncestor)
     1145            return true;
     1146    }
     1147    return false;
     1148}
     1149
     1150static PDBGGUISTATSNODE nextNode(PDBGGUISTATSNODE pNode)
     1151{
     1152    /** @todo */
     1153    return pNode;
     1154}
     1155
     1156static PDBGGUISTATSNODE prevNode(PDBGGUISTATSNODE pNode)
     1157{
     1158    /** @todo */
     1159    return pNode;
     1160}
     1161
     1162static void removeAndDeleteNode(PDBGGUISTATSNODE pNode)
     1163{
     1164    /** @todo */
     1165
    10781166}
    10791167
     
    10921180        return 0;
    10931181
    1094 /** @todo a much much faster approach would be to link all items into a doubly chained list. */
    1095 #if 0
    1096     /*
    1097      * Locate the node in the tree, creating whatever doesn't exist.
    1098      * Because of strict input ordering we can assume that any parent that is
    1099      * still in an undetermined state should be wing clipped and show no data.
    1100      */
    1101     AssertReturn(*pszName == '/' && pszName[1] != '/', VERR_INTERNAL_ERROR);
    1102     PDBGGUISTATSNODE pNode = pRoot;
    1103     const char *pszCur = pszName + 1;
    1104     while (*pszCur)
    1105     {
    1106         /* find the end of this component. */
    1107         const char *pszNext = strchr(pszCur, '/');
    1108         if (!pszNext)
    1109             pszNext = strchr(pszCur, '\0');
    1110         size_t cchCur = pszNext - pszCur;
    1111 
    1112         /* look it up, create it if it not found. */
    1113 
    1114 
    1115         /* Create it if it doesn't exist (it will be last if it exists). */
    1116         if (    !pNode->cChildren
    1117             ||  strncmp(pNode->papChildren[pNode->cChildren - 1]->pszName, pszCur, cchCur)
    1118             ||  pNode->papChildren[pNode->cChildren - 1]->pszName[cchCur])
    1119         {
    1120             pNode = createAndInsertNode(pNode, pszCur, pszNext - pszCur, UINT32_MAX);
    1121             if (!pNode)
    1122                 return VERR_NO_MEMORY;
    1123         }
     1182    /*
     1183     * The default assumption is that nothing has changed.
     1184     * For now we'll reset the model when ever something changes.
     1185     */
     1186    PDBGGUISTATSNODE pNode;
     1187    if (pThis->m_iUpdateChild != UINT32_MAX)
     1188    {
     1189        pNode = pThis->m_pUpdateParent->papChildren[pThis->m_iUpdateChild];
     1190        if (    !strncmp(pszName, pThis->m_szUpdateParent, pThis->m_cchUpdateParent)
     1191            &&  !strcmp(pszName + pThis->m_cchUpdateParent, pNode->pszName))
     1192            /* got it! */;
    11241193        else
    1125             pNode = pNode->papChildren[pNode->cChildren - 1];
    1126 
    1127         /* Advance */
    1128         pszCur = *pszNext ? pszNext + 1 : pszNext;
    1129     }
    1130 
    1131     /*
    1132      * Save the data.
    1133      */
    1134     return initNode(pNode, enmType, pvSample, enmUnit, enmVisibility, pszDesc);
    1135 #endif
    1136 #if 0
    1137     /*
    1138      * Advance to the matching item.
    1139      */
    1140     VBoxDbgStatsLeafItem *pCur = pThis->m_pCur;
    1141     while (pCur)
     1194        {
     1195            /*
     1196             * We might be inserting a new node between pPrev and pNode
     1197             * or we might be removing one or more nodes. Either case is
     1198             * handled in the same rough way.
     1199             */
     1200            pThis->m_fUpdateInsertRemove = true;
     1201
     1202            /* Start with the current parent node and look for a common ancestor
     1203               hoping that this is faster than going from the root. */
     1204            PDBGGUISTATSNODE const pPrev = prevNode(pNode);
     1205            while (pNode != pThis->m_pRoot)
     1206            {
     1207                if (!strncmp(pszName, pThis->m_szUpdateParent, pThis->m_cchUpdateParent))
     1208                    break;
     1209                Assert(pThis->m_cchUpdateParent > pNode->cchName);
     1210                pThis->m_cchUpdateParent -= pNode->cchName + 1;
     1211                pThis->m_szUpdateParent[pThis->m_cchUpdateParent] = '\0';
     1212                pNode = pNode->pParent;
     1213            }
     1214
     1215            /* Decent until we've found/created the node pszName indicates,
     1216               modifying m_szUpdateParent as we go along. */
     1217            while (pszName[pThis->m_cchUpdateParent - 1] == '/')
     1218            {
     1219                /* Find the end of this component. */
     1220                const char *pszStart = &pszName[pThis->m_cchUpdateParent];
     1221                const char *pszEnd = strchr(pszStart, '/');
     1222                if (!pszEnd)
     1223                    pszEnd = strchr(pszStart, '/');
     1224                char *pszSubName = &pThis->m_szUpdateParent[pThis->m_cchUpdateParent];
     1225                size_t cchSubName = pszEnd - pszStart;
     1226
     1227                /* Add the name to the path. */
     1228                memcpy(pszSubName, pszStart, cchSubName);
     1229                pThis->m_cchUpdateParent += cchSubName;
     1230                pThis->m_szUpdateParent[pThis->m_cchUpdateParent] = '\0';
     1231
     1232                if (pNode->cChildren)
     1233                {
     1234                    /* first child */
     1235                    pNode = createAndInsertNode(pNode, pszSubName, UINT32_MAX);
     1236                    AssertReturn(pNode, VERR_NO_MEMORY);
     1237                }
     1238                else
     1239                {
     1240                    /* binary search. */
     1241                    int32_t iStart = 0;
     1242                    int32_t iLast = pNode->cChildren - 1;
     1243                    for (;;)
     1244                    {
     1245                        int32_t i = iStart + (iLast + 1 - iStart) / 2;
     1246                        int iDiff = strcmp(pszSubName, pNode->papChildren[i]->pszName);
     1247                        if (iDiff > 0)
     1248                        {
     1249                            iStart = i + 1;
     1250                            if (iStart > iLast)
     1251                            {
     1252                                pNode = createAndInsertNode(pNode, pszSubName, iStart);
     1253                                AssertReturn(pNode, VERR_NO_MEMORY);
     1254                                break;
     1255                            }
     1256                        }
     1257                        else if (iDiff < 0)
     1258                        {
     1259                            iLast = i - 1;
     1260                            if (iLast < iStart)
     1261                            {
     1262                                pNode = createAndInsertNode(pNode, pszSubName, i);
     1263                                AssertReturn(pNode, VERR_NO_MEMORY);
     1264                                break;
     1265                            }
     1266                        }
     1267                        else
     1268                        {
     1269                            pNode = pNode->papChildren[i];
     1270                            break;
     1271                        }
     1272                    }
     1273                }
     1274
     1275                pThis->m_szUpdateParent[pThis->m_cchUpdateParent++] = '/';
     1276                pThis->m_szUpdateParent[pThis->m_cchUpdateParent] = '\0';
     1277                Assert(pThis->m_cchUpdateParent < sizeof(pThis->m_szUpdateParent));
     1278            }
     1279            Assert(pszName[pThis->m_cchUpdateParent - 1] == '\0');
     1280
     1281            /* Remove all the nodes between pNode and pPrev but keep all
     1282               of pNode's ancestors (or it'll get orphaned). */
     1283            PDBGGUISTATSNODE pCur = prevNode(pNode);
     1284            Assert(pCur != pPrev);
     1285            while (pCur != pPrev)
     1286            {
     1287                PDBGGUISTATSNODE pAdv = prevNode(pCur);
     1288                if (!isNodeAncestorOf(pCur, pNode))
     1289                    removeAndDeleteNode(pCur);
     1290                pCur = pAdv;
     1291            }
     1292
     1293            /* Removed the data from all ancestors of pNode that it doesn't share them pPrev. */
     1294            pCur = pNode->pParent;
     1295            while (!isNodeAncestorOf(pCur, pPrev))
     1296            {
     1297                resetNode(pNode);
     1298                pCur = pCur->pParent;
     1299            }
     1300
     1301            /* Finally, adjust the globals (szUpdateParent is one level too deep). */
     1302            Assert(pThis->m_cchUpdateParent > pNode->cchName - 1);
     1303            pThis->m_cchUpdateParent -= pNode->cchName - 1;
     1304            pThis->m_szUpdateParent[pThis->m_cchUpdateParent] = '\0';
     1305            pThis->m_pUpdateParent = pNode->pParent;
     1306            pThis->m_iUpdateChild = pNode->iSelf;
     1307        }
     1308    }
     1309    else
    11421310    {
    11431311        /*
    1144          * ASSUMES ascending order of STAM items.
     1312         * Insert it at the end of the tree                                                                        .
     1313         *                                                                                                        .
     1314         * Do the same as we're doing down in createNewTreeCallback, walk from the                                 .
     1315         * root and create whatever we need.
    11451316         */
    1146         int iDiff = strcmp(pszName, pCur->getName());
    1147         if (!iDiff)
    1148             break;
    1149         if (iDiff > 0)
    1150         {
    1151             /*
    1152              * Removed / filtered out.
    1153              */
    1154             Log2(("updateCallback: %s - filtered out\n", pCur->getName()));
    1155             if (pCur->isVisible())
     1317        pThis->m_fUpdateInsertRemove = true;
     1318
     1319        AssertReturn(*pszName == '/' && pszName[1] != '/', VERR_INTERNAL_ERROR);
     1320        pNode = pThis->m_pRoot;
     1321        const char *pszCur = pszName + 1;
     1322        while (*pszCur)
     1323        {
     1324            /* Find the end of this component. */
     1325            const char *pszNext = strchr(pszCur, '/');
     1326            if (!pszNext)
     1327                pszNext = strchr(pszCur, '\0');
     1328            size_t cchCur = pszNext - pszCur;
     1329
     1330            /* Create it if it doesn't exist (it will be last if it exists). */
     1331            if (    !pNode->cChildren
     1332                ||  strncmp(pNode->papChildren[pNode->cChildren - 1]->pszName, pszCur, cchCur)
     1333                ||  pNode->papChildren[pNode->cChildren - 1]->pszName[cchCur])
    11561334            {
    1157                 pCur->setVisible(false);
    1158                 hideParentBranches(pCur);
     1335                pNode = createAndInsertNode(pNode, pszCur, pszNext - pszCur, UINT32_MAX);
     1336                if (!pNode)
     1337                    return VERR_NO_MEMORY;
    11591338            }
    1160 
    1161             pCur = pCur->m_pNext;
    1162         }
    1163         else if (iDiff < 0)
    1164         {
    1165             /*
    1166              * New item, insert before pCur.
    1167              */
    1168             Log2(("updateCallback: %s - new\n", pszName));
    1169             VBoxDbgStatsLeafItem *pNew = new VBoxDbgStatsLeafItem(pszName, pThis->createPath(pszName));
    1170             pNew->m_pNext = pCur;
    1171             pNew->m_pPrev = pCur->m_pPrev;
    1172             if (pNew->m_pPrev)
    1173                 pNew->m_pPrev->m_pNext = pNew;
    11741339            else
    1175                 pThis->m_pHead = pNew;
    1176             pCur->m_pPrev = pNew;
    1177             pCur = pNew;
    1178             Assert(!strcmp(pszName, pCur->getName()));
    1179             break;
    1180         }
    1181     }
    1182 
    1183     /*
    1184      * End of items, insert it at the tail.
    1185      */
    1186     if (!pCur)
    1187     {
    1188         Log2(("updateCallback: %s - new end\n", pszName));
    1189         pCur = new VBoxDbgStatsLeafItem(pszName, pThis->createPath(pszName));
    1190         pCur->m_pNext = NULL;
    1191         pCur->m_pPrev = pThis->m_pTail;
    1192         if (pCur->m_pPrev)
    1193             pCur->m_pPrev->m_pNext = pCur;
    1194         else
    1195             pThis->m_pHead = pCur;
    1196         pThis->m_pTail = pCur;
    1197     }
    1198     Assert(pThis->m_pHead);
    1199     Assert(pThis->m_pTail);
    1200 
    1201     /*
    1202      * Update it and move on.
    1203      */
    1204     if (!pCur->isVisible())
    1205         showParentBranches(pCur);
    1206     pCur->update(enmType, pvSample, enmUnit, enmVisibility, pszDesc);
    1207     pThis->m_pCur = pCur->m_pNext;
    1208 
    1209 #endif
     1340                pNode = pNode->papChildren[pNode->cChildren - 1];
     1341
     1342            /* Advance */
     1343            pszCur = *pszNext ? pszNext + 1 : pszNext;
     1344        }
     1345
     1346    }
     1347
     1348    /*
     1349     * Perform the update.
     1350     */
     1351    updateNode(pNode, enmType, pvSample, enmUnit, enmVisibility, pszDesc, pvUser);
     1352
     1353    /*
     1354     * Advance to the next node.
     1355     * (Again, we're ASSUMING that the input is sorted on (full) path name.)
     1356     */
     1357    PDBGGUISTATSNODE pParent = pNode->pParent;
     1358    if (pNode->cChildren)
     1359    {
     1360        /* decend to the children. */
     1361        pThis->m_iUpdateChild = 0;
     1362        Assert(pThis->m_cchUpdateParent + pNode->cchName + 2 < sizeof(pThis->m_szUpdateParent));
     1363        memcpy(&pThis->m_szUpdateParent[pThis->m_cchUpdateParent], pNode->pszName, pNode->cchName);
     1364        pThis->m_cchUpdateParent += pNode->cchName;
     1365        pThis->m_szUpdateParent[pThis->m_cchUpdateParent++] = '/';
     1366        pThis->m_pUpdateParent = pNode;
     1367    }
     1368    else if (pNode->iSelf + 1 < pParent->cChildren)
     1369    {
     1370        /* next sibling  */
     1371        pThis->m_iUpdateChild = pNode->iSelf + 1;
     1372        Assert(pThis->m_pUpdateParent == pNode->pParent);
     1373    }
     1374    else
     1375    {
     1376        /* move up and down- / on-wards */
     1377        for (;;)
     1378        {
     1379            /* ascend */
     1380            pNode = pParent;
     1381            pParent = pParent->pParent;
     1382            if (!pParent)
     1383            {
     1384                Assert(pNode == pThis->m_pRoot);
     1385                pThis->m_iUpdateChild = UINT32_MAX;
     1386                pThis->m_szUpdateParent[0] = '\0';
     1387                pThis->m_cchUpdateParent = 0;
     1388                pThis->m_pUpdateParent = NULL;
     1389                break;
     1390            }
     1391            Assert(pThis->m_cchUpdateParent > pNode->cchName);
     1392            pThis->m_cchUpdateParent -= pNode->cchName - 1;
     1393            pThis->m_szUpdateParent[pThis->m_cchUpdateParent] = '\0';
     1394
     1395            /* try advance */
     1396            if (pNode->iSelf + 1 < pParent->cChildren)
     1397            {
     1398                pNode = pParent->papChildren[pNode->iSelf + 1];
     1399
     1400                /* decend to a node containing data. */
     1401                while (   pNode->enmType == STAMTYPE_INVALID
     1402                       && pNode->cChildren > 0)
     1403                {
     1404                    Assert(pNode->enmState == kDbgGuiStatsNodeState_kVisible);
     1405
     1406                    Assert(pThis->m_cchUpdateParent + pNode->cchName + 2 < sizeof(pThis->m_szUpdateParent));
     1407                    memcpy(&pThis->m_szUpdateParent[pThis->m_cchUpdateParent], pNode->pszName, pNode->cchName);
     1408                    pThis->m_cchUpdateParent += pNode->cchName;
     1409                    pThis->m_szUpdateParent[pThis->m_cchUpdateParent++] = '/';
     1410
     1411                    pNode = pNode->papChildren[0];
     1412                }
     1413                Assert(pNode->enmType != STAMTYPE_INVALID);
     1414                pThis->m_iUpdateChild = pNode->iSelf;
     1415                pThis->m_pUpdateParent = pNode->pParent;
     1416                break;
     1417            }
     1418        }
     1419
     1420    }
    12101421    return VINF_SUCCESS;
    12111422}
     
    12161427{
    12171428    /*
    1218      * Mark all nodes that aren't yet invisble as invisible.
    1219      * (Depth first)
    1220      */
    1221     DBGGUISTATSSTACK    Stack;
    1222     Stack.a[0].pNode = m_pRoot;
    1223     Stack.a[0].iChild = -1;
    1224     Stack.iTop = 0;
    1225 
    1226     while (Stack.iTop >= 0)
    1227     {
    1228         /* get top element */
    1229         PDBGGUISTATSNODE pNode  = Stack.a[Stack.iTop].pNode;
    1230         uint32_t         iChild = ++Stack.a[Stack.iTop].iChild;
    1231         if (iChild < pNode->cChildren)
    1232         {
    1233             /* push */
    1234             Stack.iTop++;
    1235             Assert(Stack.iTop < (int32_t)RT_ELEMENTS(Stack.a));
    1236             Stack.a[Stack.iTop].pNode = pNode->papChildren[iChild];
    1237             Stack.a[Stack.iTop].iChild = 0;
    1238         }
    1239         else
    1240         {
    1241             /* pop */
    1242             Stack.iTop--;
    1243 
    1244             /* do the actual work. */
    1245             switch (pNode->enmState)
     1429     * Find the first child with data and set it up as the 'next'
     1430     * node to be updated.
     1431     */
     1432    PDBGGUISTATSNODE pFirst = m_pRoot;
     1433    while (pFirst && pFirst->enmType == STAMTYPE_INVALID)
     1434        pFirst = nextNode(pFirst);
     1435    if (pFirst)
     1436    {
     1437        m_iUpdateChild = pFirst->iSelf;
     1438        m_pUpdateParent = pFirst;
     1439        m_cchUpdateParent = getNodePath(m_pUpdateParent, m_szUpdateParent, sizeof(m_szUpdateParent) - 1);
     1440        AssertReturnVoid(m_cchUpdateParent >= 1);
     1441        m_szUpdateParent[m_cchUpdateParent++] = '/';
     1442        m_szUpdateParent[m_cchUpdateParent] = '\0';
     1443    }
     1444    else
     1445    {
     1446        m_iUpdateChild = UINT32_MAX;
     1447        m_pUpdateParent = NULL;
     1448        m_szUpdateParent[0] = '\0';
     1449        m_cchUpdateParent = 0;
     1450    }
     1451
     1452    /*
     1453     * Perform the update.
     1454     *
     1455     * If we're inserting and/or removing anything we'll simply reset the model.
     1456     * This can be optimized later when the normal updating is working perfectly.
     1457     */
     1458    m_fUpdateInsertRemove = false;
     1459
     1460    /** @todo the way we update this stuff is independent of the source (XML, file, STAM), our only
     1461     * ASSUMPTION is that the input is strictly ordered by (full) name. So, all this stuff should
     1462     * really move up into the parent class. */
     1463    stamEnum(a_rPatStr, updateCallback, this);
     1464
     1465    if (m_fUpdateInsertRemove)
     1466        reset();
     1467    else
     1468    {
     1469        /*
     1470         * Send dataChanged events.
     1471         */
     1472        DBGGUISTATSSTACK    Stack;
     1473        Stack.a[0].pNode = m_pRoot;
     1474        Stack.a[0].iChild = -1;
     1475        Stack.iTop = 0;
     1476
     1477        while (Stack.iTop >= 0)
     1478        {
     1479            /* get top element */
     1480            PDBGGUISTATSNODE pNode  = Stack.a[Stack.iTop].pNode;
     1481            uint32_t         iChild = ++Stack.a[Stack.iTop].iChild;
     1482            if (iChild < pNode->cChildren)
    12461483            {
    1247                 case kDbgGuiStatsNodeState_kVisible:
    1248                     pNode->enmState = kDbgGuiStatsNodeState_kMakeInvisible;
    1249                     break;
    1250                 case kDbgGuiStatsNodeState_kInvisible:
    1251                 case kDbgGuiStatsNodeState_kRoot:
    1252                     break;
    1253                 default:
    1254                     AssertMsgFailedBreak(("%d\n", pNode->enmState));
     1484                /* push */
     1485                Stack.iTop++;
     1486                Assert(Stack.iTop < (int32_t)RT_ELEMENTS(Stack.a));
     1487                Stack.a[Stack.iTop].pNode = pNode->papChildren[iChild];
     1488                Stack.a[Stack.iTop].iChild = 0;
    12551489            }
    1256         }
    1257     }
    1258 
    1259 
    1260     /*
    1261      * Perform the update.
    1262      */
    1263     stamEnum(a_rPatStr, updateCallback, this);
    1264 
    1265 
    1266     /*
    1267      * Send dataChanged events.
    1268      */
    1269     Stack.a[0].pNode = m_pRoot;
    1270     Stack.a[0].iChild = -1;
    1271     Stack.iTop = 0;
    1272 
    1273     while (Stack.iTop >= 0)
    1274     {
    1275         /* get top element */
    1276         PDBGGUISTATSNODE pNode  = Stack.a[Stack.iTop].pNode;
    1277         uint32_t         iChild = ++Stack.a[Stack.iTop].iChild;
    1278         if (iChild < pNode->cChildren)
    1279         {
    1280             /* push */
    1281             Stack.iTop++;
    1282             Assert(Stack.iTop < (int32_t)RT_ELEMENTS(Stack.a));
    1283             Stack.a[Stack.iTop].pNode = pNode->papChildren[iChild];
    1284             Stack.a[Stack.iTop].iChild = 0;
    1285         }
    1286         else
    1287         {
    1288             /* pop */
    1289             Stack.iTop--;
    1290 
    1291             /* do the actual work. */
    1292             iChild = 0;
    1293             while (iChild < pNode->cChildren)
     1490            else
    12941491            {
    1295                 /* skip to the first needing updating. */
    1296                 while (     iChild < pNode->cChildren
    1297                        &&   (   pNode->papChildren[iChild]->enmState != kDbgGuiStatsNodeState_kMakeVisible
    1298                              && pNode->papChildren[iChild]->enmState != kDbgGuiStatsNodeState_kMakeInvisible
    1299                              && pNode->papChildren[iChild]->enmState != kDbgGuiStatsNodeState_kRefresh))
    1300                     iChild++;
    1301                 if (iChild >= pNode->cChildren)
    1302                     break;
    1303                 QModelIndex TopLeft = createIndex(iChild, 0, pNode->papChildren[iChild]);
    1304 
    1305                 /* collect any subsequent nodes that also needs refreshing. */
    1306                 while (++iChild < pNode->cChildren)
     1492                /* pop */
     1493                Stack.iTop--;
     1494
     1495                /* do the actual work. */
     1496                iChild = 0;
     1497                while (iChild < pNode->cChildren)
    13071498                {
    1308                     DBGGUISTATENODESTATE enmState = pNode->papChildren[iChild]->enmState;
    1309                     if (    enmState == kDbgGuiStatsNodeState_kRefresh
    1310                         ||  enmState == kDbgGuiStatsNodeState_kMakeVisible)
    1311                         enmState = kDbgGuiStatsNodeState_kVisible;
    1312                     else if (enmState == kDbgGuiStatsNodeState_kMakeInvisible)
    1313                         enmState = kDbgGuiStatsNodeState_kInvisible;
    1314                     else
     1499                    /* skip to the first needing updating. */
     1500                    while (     iChild < pNode->cChildren
     1501                           &&   (   pNode->papChildren[iChild]->enmState != kDbgGuiStatsNodeState_kMakeVisible
     1502                                 && pNode->papChildren[iChild]->enmState != kDbgGuiStatsNodeState_kMakeInvisible
     1503                                 && pNode->papChildren[iChild]->enmState != kDbgGuiStatsNodeState_kRefresh))
     1504                        iChild++;
     1505                    if (iChild >= pNode->cChildren)
    13151506                        break;
    1316                     pNode->papChildren[iChild]->enmState = enmState;
     1507                    QModelIndex TopLeft = createIndex(iChild, 0, pNode->papChildren[iChild]);
     1508
     1509                    /* collect any subsequent nodes that also needs refreshing. */
     1510                    while (++iChild < pNode->cChildren)
     1511                    {
     1512                        DBGGUISTATENODESTATE enmState = pNode->papChildren[iChild]->enmState;
     1513                        if (    enmState == kDbgGuiStatsNodeState_kRefresh
     1514                            ||  enmState == kDbgGuiStatsNodeState_kMakeVisible)
     1515                            enmState = kDbgGuiStatsNodeState_kVisible;
     1516                        else if (enmState == kDbgGuiStatsNodeState_kMakeInvisible)
     1517                            enmState = kDbgGuiStatsNodeState_kInvisible;
     1518                        else
     1519                            break;
     1520                        pNode->papChildren[iChild]->enmState = enmState;
     1521                    }
     1522                    QModelIndex BottomRight = createIndex(iChild - 1, DBGGUI_STATS_COLUMNS - 1, pNode->papChildren[iChild - 1]);
     1523
     1524                    /* emit the refresh signal */
     1525                    emit dataChanged(TopLeft, BottomRight);
    13171526                }
    1318                 QModelIndex BottomRight = createIndex(iChild - 1, DBGGUI_STATS_COLUMNS - 1, pNode->papChildren[iChild - 1]);
    1319 
    1320                 /* emit the refresh signal */
    1321                 emit dataChanged(TopLeft, BottomRight);
    13221527            }
    13231528        }
     
    14791684
    14801685PDBGGUISTATSNODE
    1481 VBoxDbgStatsModelVM::createNewTree(void)
     1686VBoxDbgStatsModelVM::createNewTree(QString &a_rPatStr)
    14821687{
    14831688    PDBGGUISTATSNODE pRoot = createRootNode();
    14841689    if (pRoot)
    14851690    {
    1486         int rc = stamEnum(QString(), createNewTreeCallback, pRoot);
     1691        int rc = stamEnum(a_rPatStr, createNewTreeCallback, pRoot);
    14871692        if (VBOX_SUCCESS(rc))
    14881693            return pRoot;
     
    23272532    m_pPatCB = new QComboBox();
    23282533    pHLayout->addWidget(m_pPatCB);
    2329     if (pszPat && *pszPat)
    2330         m_pPatCB->addItem(pszPat);
     2534    if (!m_PatStr.isEmpty())
     2535        m_pPatCB->addItem(m_PatStr);
    23312536    m_pPatCB->setDuplicatesEnabled(false);
    23322537    m_pPatCB->setEditable(true);
     
    23592564     * Create the tree view and setup the layout.
    23602565     */
    2361     VBoxDbgStatsModelVM *pModel = new VBoxDbgStatsModelVM(pVM, NULL);
     2566    VBoxDbgStatsModelVM *pModel = new VBoxDbgStatsModelVM(pVM, m_PatStr, NULL);
    23622567    m_pView = new VBoxDbgStatsView(pVM, pModel, this);
    23632568
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette