void StandardListCtrl::deleteEntry(int id) { for (int i = 0; i < entryPtrs.size(); i++) { if (entries[i].consoleIndex == id) { entries.erase(i); break; } } //resort entryPtrs.clear(); for (int j = 0; j < entries.size(); j++) { entryPtrs.push_back(&entries[j]); } m_qsort((void *)&entryPtrs[0], entryPtrs.size(), sizeof(StandardListCtrl::EntryRep *), standardNameAscend); //set the size and selected cell setSize(Point2I(1, entryPtrs.size())); selectedCell.set(-1, -1); }
void PlayerListCtrl::deleteEntry(int id) { for (int i = 0; i < playerPtrs.size(); i++) { if (players[i].consoleIndex == id) { players.erase(i); break; } } //resort playerPtrs.clear(); for (int j = 0; j < players.size(); j++) { playerPtrs.push_back(&players[j]); } m_qsort((void *)&playerPtrs[0], playerPtrs.size(), sizeof(PlayerListCtrl::ClientRep *), playerNameAscend); //set the size and selected cell setSize(Point2I(1, playerPtrs.size())); selectedCell.set(-1, -1); }
//console function members void StandardListCtrl::addEntry(const char *buf, int id) { EntryRep newEntry; newEntry.consoleIndex = id; strncpy(newEntry.name, buf, MaxEntryNameLength); newEntry.name[MaxEntryNameLength] = '\0'; entries.push_back(newEntry); //resort entryPtrs.clear(); for (int j = 0; j < entries.size(); j++) { entryPtrs.push_back(&entries[j]); } if (mbSortEntries) { m_qsort((void *)&entryPtrs[0], entryPtrs.size(), sizeof(StandardListCtrl::EntryRep *), standardNameAscend); } //set the size and selected cell setSize(Point2I(1, entryPtrs.size())); setSelected(id); }
/* qsort: sort v[left]...v[right] into increasing order */ void m_qsort(void *v[], int left, int right, int (*comp)(void *, void *)) { int i, last; if (left >= right) /* do nothing if array contains */ return; /* fewer than two elements */ swap(v, left, (left + right)/2); last = left; for (i = left+1; i <= right; i++) if ((*comp)(v[i], v[left]) < 0) swap(v, ++last, i); swap(v, left, last); m_qsort(v, left, last-1, comp); m_qsort(v, last+1, right, comp); }
/* sort input lines */ main(int argc, char *argv[]) { int nlines; /* number of input lines read */ int numeric = 0; /* 1 if numeric sort */ if (argc > 1 && strcmp(argv[1], "-n") == 0) numeric = 1; if ((nlines = readlines(lineptr, MAXLINES)) >= 0) { m_qsort((void**) lineptr, 0, nlines-1, (int (*)(void*,void*))(numeric ? numcmp : strcmp)); writelines(lineptr, nlines); return 0; } else { printf("input too big to sort\n"); return 1; } }
//console function members void PlayerListCtrl::addEntry(const char *buf, int id) { ClientRep newPlayer; newPlayer.consoleIndex = id; strncpy(newPlayer.name, buf, MaxClientNameLength); newPlayer.name[MaxClientNameLength] = '\0'; players.push_back(newPlayer); //resort playerPtrs.clear(); for (int j = 0; j < players.size(); j++) { playerPtrs.push_back(&players[j]); } m_qsort((void *)&playerPtrs[0], playerPtrs.size(), sizeof(PlayerListCtrl::ClientRep *), playerNameAscend); //set the size and selected cell setSize(Point2I(1, playerPtrs.size())); setSelected(id); }
bool GhostManager::writePacket(BitStream *bstream, DWORD &key) { if(curMode != GhostScopeAlwaysMode && curMode != GhostNormalMode && !(curMode == InactiveMode && ghostList) ) return false; // fill a packet (or two) with ghosting data // first step is to check all our polled ghosts: // 1. Scope query - find if any new objects have come into // scope and if any have gone out. // While the client rep is sending out the ghost always packets // the scope query is not called... just ghost always objects are in the list // 2. call scoped objects' priority functions if the flag set is nonzero // A removed ghost is assumed to have a high priority // If the client rep is sending out ghost always objects // then instead of the priority function, the instantiation // time is used for priority. No objects are updated until // all are ghosted during this phase. // 3. call updates based on sorted priority until the packet is // full. set flags to zero for all updated objects camInfo.camera = NULL; camInfo.pos.set(0,0,0); camInfo.orientation.set(0,1,0); camInfo.visibleDistance = 1; camInfo.fov = (float)(M_PI / 4.0f); camInfo.sinFov = 0.5; camInfo.cosFov = 0.5; GhostInfo *walk = ghostList; bstream->writeFlag(curMode == GhostScopeAlwaysMode); if(curMode == GhostNormalMode || curMode == InactiveMode) { if(curMode == GhostNormalMode) { while(walk) { if(!(walk->flags & GhostInfo::ScopeAlways)) walk->flags &= ~GhostInfo::InScope; walk = walk->nextRef; } if(scopeObject) scopeObject->buildScopeAndCameraInfo(this, &camInfo); } walk = ghostList; while(walk) { if(!(walk->flags & GhostInfo::InScope)) { walk->flags |= GhostInfo::KillGhost; // remove this ghostManager from the object's ghostRefs if(walk->obj) { Vector<GhostRef>::iterator i; for(i = walk->obj->ghosts.begin(); i != walk->obj->ghosts.end(); i++) { if(i->ghostManager == this) { walk->obj->ghosts.erase(i); break; } } walk->obj = NULL; } } walk = walk->nextRef; } } static Vector<UpdateQueueEntry> qPriority; static Vector<UpdateQueueEntry> qDelete; qPriority.clear(); qDelete.clear(); walk = ghostList; while(walk) { // clear out any kill objects that haven't been ghosted yet if((walk->flags & GhostInfo::KillGhost) && (walk->flags & GhostInfo::NotYetGhosted)) { GhostInfo *temp = walk->nextRef; freeGhostInfo(walk); walk = temp; continue; } // don't do any ghost processing on objects that are being killed // or in the process of ghosting else if(!(walk->flags & (GhostInfo::KillingGhost | GhostInfo::Ghosting))) { if(walk->flags & GhostInfo::KillGhost) qDelete.push_back(UpdateQueueEntry(0, walk)); else if((walk->flags & GhostInfo::NotYetGhosted) && (curMode == GhostScopeAlwaysMode)) qPriority.push_back(UpdateQueueEntry(-walk->obj->getNumber(), walk)); else if(walk->updateMask && (curMode == GhostNormalMode)) { float priority; if(scopeObject) priority = walk->obj->getUpdatePriority(&camInfo, walk->updateMask, walk->updateSkipCount); else priority = 1; qPriority.push_back(UpdateQueueEntry(priority, walk)); } } walk = walk->nextRef; } PacketObjectRef *updateList = NULL; m_qsort((void *) &qPriority[0], qPriority.size(), sizeof(UpdateQueueEntry), UQECompare); Vector<UpdateQueueEntry>::iterator i = qDelete.begin(); int packedIdSize = sendIdSize - 3; // 0-7 3 bit number bstream->writeInt(packedIdSize, 3); for(;;i++) { if(i == qDelete.end()) i = qPriority.begin(); if(i == qPriority.end()) break; if(bstream->isFull()) { (*i).obj->updateSkipCount++; } else { walk = (*i).obj; if(walk->flags & (GhostInfo::KillGhost | GhostInfo::Ghosting) == (GhostInfo::KillGhost | GhostInfo::Ghosting)) continue; int startPos = bstream->getCurPos(); bstream->writeFlag(true); bstream->writeInt(walk->ghostIndex, sendIdSize); DWORD updateMask = walk->updateMask; PacketObjectRef *upd = freePackRefList; if(upd) freePackRefList = freePackRefList->nextRef; else upd = new PacketObjectRef; upd->nextRef = updateList; updateList = upd; upd->nextUpdateChain = walk->updateChain; walk->updateChain = upd; upd->ghost = walk; upd->ghostInfoFlags = 0; if(walk->flags & GhostInfo::KillGhost) { walk->flags &= ~GhostInfo::KillGhost; walk->flags |= GhostInfo::KillingGhost; upd->ghostInfoFlags = GhostInfo::KillingGhost; bstream->writeFlag(true); // killing ghost } else { bstream->writeFlag(false); if(walk->flags & GhostInfo::NotYetGhosted) { if(curMode == GhostScopeAlwaysMode) bstream->writeInt(walk->obj->getNumber(), 32); #ifdef DEBUG_NET if(!walk->obj->getClass()) { AssertFatal(0, avar("%s is not a persist declared class.", walk->obj->getClassName())); } #endif DWORD tag = walk->obj->getGhostTag(); AssertFatal(tag > 0 && tag < 1024, "Bad ghost tag."); walk->flags &= ~GhostInfo::NotYetGhosted; walk->flags |= GhostInfo::Ghosting; upd->ghostInfoFlags = GhostInfo::Ghosting; bstream->writeInt(tag, 10); } // update the object DWORD retMask = walk->obj->packUpdate(this, updateMask, bstream); AssertFatal((retMask & (~updateMask)) == 0, "Cannot set new bits in packUpdate return"); walk->updateMask = retMask; upd->mask = updateMask & ~retMask; PacketStream::getStats()->addBits(PacketStats::Send, bstream->getCurPos() - startPos, walk->obj->getPersistTag()); #ifdef DEBUG_NET // write out a checksum... // we'll check this on the other side for validation // later we can put in stuff to check sizes and such bstream->writeInt(walk->ghostIndex ^ DebugChecksum, 32); #endif } walk->updateSkipCount = 0; } } // no more objects... bstream->writeFlag(false); key = (DWORD) updateList; if(curMode == GhostScopeAlwaysMode) { // if this is our mode, // loop through all the objects // if they all have been ghosted, (ie, flags NotYetGhosted and // Ghosting are NOT set), then tag this packet as the ghost always // done packet // just a bit of advanced warning to the other side to add all its // objects. (if this packet is dropped - no big deal, read will // figure it out when it gets a normal ghost packet) walk = ghostList; bool allGhosted = true; while(walk) { if(walk->flags & (GhostInfo::NotYetGhosted | GhostInfo::Ghosting)) { allGhosted = false; break; } walk = walk->nextRef; } bstream->writeFlag(allGhosted); if(allGhosted) { curMode = GhostNormalMode; CSDelegate *delegate = (CSDelegate *) manager->findObject(SimCSDelegateId); if(delegate) delegate->onGhostAlwaysDone(getOwner()); } } return true; }