Exemplo n.º 1
0
FixCallCost::FixCallCost(TracePart* part, FixPool* pool,
			 TraceFunctionSource* functionSource,
                         unsigned int line, Addr addr,
                         TracePartCall* partCall,
                         SubCost callCount, FixString& s)
{
  if (0) qDebug("Got FixCallCost (addr 0x%s, line %d): calls %s",
                qPrintable(addr.toString()), line,
                qPrintable(callCount.pretty()));

  int maxCount = part->eventTypeMapping()->count();

    _part = part;
    _functionSource = functionSource;
    _line = line;
    _addr = addr;

    _cost = (SubCost*) pool->reserve(sizeof(SubCost) * (maxCount+1));
    s.stripSpaces();
    int i = 0;
    while(i<maxCount) {
	if (!s.stripUInt64(_cost[i])) break;
	i++;
    }
    _count = i;

    if (!pool->allocateReserved(sizeof(SubCost) * (_count+1) ))
      _count = 0;
    else
      _cost[_count] = callCount;

    _nextCostOfPartCall = partCall ? partCall->setFirstFixCallCost(this) : 0;
}
Exemplo n.º 2
0
FixCost::FixCost(TracePart* part, FixPool* pool,
		 TraceFunctionSource* functionSource,
		 PositionSpec& pos,
                 TracePartFunction* partFunction,
		 FixString& s)
{
    int maxCount = part->eventTypeMapping()->count();

    _part = part;
    _functionSource = functionSource;
    _pos = pos;

    _cost = (SubCost*) pool->reserve(sizeof(SubCost) * maxCount);
    s.stripSpaces();
    int i = 0;
    while(i<maxCount) {
	if (!s.stripUInt64(_cost[i])) break;
	i++;
    }
    _count = i;

    if (!pool->allocateReserved(sizeof(SubCost) * _count))
	_count = 0;

    _nextCostOfPartFunction = partFunction ?
	partFunction->setFirstFixCost(this) : 0;
}
Exemplo n.º 3
0
// update each subcost to be maximum of old and given costs
void ProfileCostArray::maxCost(EventTypeMapping* mapping, FixString & s)
{
    if (!mapping) return;
    s.stripSpaces();
    if (s.isEmpty()) return;
    reserve(mapping->set()->realCount());

    SubCost v;
    if (mapping->isIdentity()) {
        int i = 0;
        while(i<mapping->count()) {
            if (!s.stripUInt64(v)) break;
            if (i<_count) {
                if (v>_cost[i]) _cost[i] = v;
            }
            else
                _cost[i] = v;
            i++;
        }
        if (i > _count) _count = i;
    }
    else {
        int i = 0, maxIndex = 0, index;
        while(1) {
            if (!s.stripUInt64(v)) break;
            index = mapping->realIndex(i);
            if (maxIndex<index) maxIndex=index;
            if (index == ProfileCostArray::InvalidIndex) break;
            if (index<_count) {
                if (v>_cost[index]) _cost[index] = v;
            }
            else
                _cost[index] = v;
            i++;
        }
        if (maxIndex >= _count) {
            /* we have to set all costs of unused indexes in the interval
             *  [_count;maxIndex] to zero */
            for(i=mapping->nextUnused(_count-1); i<=maxIndex; i=mapping->nextUnused(i))
                _cost[i] = 0;
            _count = maxIndex+1;
        }
    }

    Q_ASSERT(_count <= _allocCount);
    invalidate();

#if TRACE_DEBUG
    _dirty = false; // do not recurse !
    qDebug("%s\n now %s", qPrintable( fullName() ),
           qPrintable(ProfileCostArray::costString(0)));
    _dirty = true; // because of invalidate()
#endif
}
Exemplo n.º 4
0
bool FixString::stripName(FixString& s)
{
    if (_len==0) return false;

    // first char has to be a letter or "_"
    if (!QChar(*_str).isLetter() && (*_str != '_')) return false;

    int newLen = 1;
    const char* newStr = _str;

    _str++;
    _len--;

    while(_len>0) {
        if (!QChar(*_str).isLetterOrNumber()
            && (*_str != '_')) break;

        newLen++;
        _str++;
        _len--;
    }

    s.set(newStr, newLen);
    return true;
}
Exemplo n.º 5
0
void ProfileCostArray::set(EventTypeMapping* mapping, FixString & s)
{
    if (!mapping) return;
    s.stripSpaces();
    if (s.isEmpty()) {
        clear();
        return;
    }

    reserve(mapping->set()->realCount());

    if (mapping->isIdentity()) {
        int i = 0;
        while(i<mapping->count()) {
            if (!s.stripUInt64(_cost[i])) break;
            i++;
        }
        _count = i;
    }
    else {
        int i = 0, maxIndex = 0, index;
        while(1) {
            index = mapping->realIndex(i);
            if (maxIndex<index) maxIndex=index;
            if (index == ProfileCostArray::InvalidIndex) break;
            if (!s.stripUInt64(_cost[index])) break;
            i++;
        }
        // we have to set all costs of unused indexes till maxIndex to zero
        for(i=mapping->firstUnused(); i<=maxIndex; i=mapping->nextUnused(i))
            _cost[i] = 0;
        _count = maxIndex+1;
    }
    Q_ASSERT(_count <= _allocCount);
    invalidate();
}
Exemplo n.º 6
0
bool FixFile::nextLine(FixString& str)
{
    if (_currentLeft == 0) return false;

    unsigned left = _currentLeft;
    char* current = _current;

    while(left>0) {
        if (*current == 0 || *current == '\n') break;
        current++;
        left--;
    }

    if (0) {
        char tmp[200];
        int l = _currentLeft-left;
        if (l>199) l = 199;
        strncpy(tmp, _current, l);
        tmp[l] = 0;
        qDebug("[FixFile::nextLine] At %lu, len %u: '%s'",
               (unsigned long) (_current - _base), _currentLeft-left, tmp);
    }

    int len =  _currentLeft-left;
    // get rid of any carriage return at end
    if ((len>0) && (*(current-1) == '\r')) len--;
    str.set(_current, len);

    if ((left > 0) && (*current == '\n')) {
        current++;
        left--;
    }
    _current = current;
    _currentLeft = left;

    return true;
}
Exemplo n.º 7
0
/**
 * The main import function...
 */
int CachegrindLoader::loadInternal(TraceData* data,
                                   QIODevice* device, const QString& filename)
{
    if (!data || !device) return 0;

    _data = data;
    _filename = filename;
    _lineNo = 0;

    loadStart(_filename);

    FixFile file(device, _filename);
    if (!file.exists()) {
        loadFinished(QStringLiteral("File does not exist"));
        return 0;
    }

    int statusProgress = 0;

#if USE_FIXCOST
    // FixCost Memory Pool
    FixPool* pool = _data->fixPool();
#endif

    _part = 0;
    partsAdded = 0;
    prepareNewPart();

    FixString line;
    char c;

    // current position
    nextLineType  = SelfCost;
    // default if there is no "positions:" line
    hasLineInfo = true;
    hasAddrInfo = false;

    while (file.nextLine(line)) {

        _lineNo++;

#if TRACE_LOADER
        qDebug() << "[CachegrindLoader] " << _filename << ":" << _lineNo
                 << " - '" << QString(line) << "'";
#endif

        // if we cannot strip a character, this was an empty line
        if (!line.first(c)) continue;

        if (c <= '9') {

            if (c == '#') continue;

            // parse position(s)
            if (!parsePosition(line, currentPos)) {
                error(QStringLiteral("Invalid position specification '%1'").arg(line));
                continue;
            }

            // go through after big switch
        }
        else { // if (c > '9')

            line.stripFirst(c);

            /* in order of probability */
            switch(c) {

            case 'f':

                // fl=
                if (line.stripPrefix("l=")) {

                    setFile(line);
                    // this is the default for new functions
                    currentFunctionFile = currentFile;
                    continue;
                }

                // fi=, fe=
                if (line.stripPrefix("i=") ||
                    line.stripPrefix("e=")) {

                    setFile(line);
                    continue;
                }

                // fn=
                if (line.stripPrefix("n=")) {

                    if (currentFile != currentFunctionFile)
                        currentFile = currentFunctionFile;
                    setFunction(line);

                    // on a new function, update status
                    int progress = (int)(100.0 * file.current() / file.len() +.5);
                    if (progress != statusProgress) {
                        statusProgress = progress;

                        /* When this signal is connected, it most probably
         * should lead to GUI update. Thus, when multiple
         * "long operations" (like file loading) are in progress,
         * this can temporarly switch to another operation.
         */
                        loadProgress(statusProgress);
                    }

                    continue;
                }

                break;

            case 'c':
                // cob=
                if (line.stripPrefix("ob=")) {
                    setCalledObject(line);
                    continue;
                }

                // cfi= / cfl=
                if (line.stripPrefix("fl=") ||
                    line.stripPrefix("fi=")) {
                    setCalledFile(line);
                    continue;
                }

                // cfn=
                if (line.stripPrefix("fn=")) {

                    setCalledFunction(line);
                    continue;
                }

                // calls=
                if (line.stripPrefix("alls=")) {
                    // ignore long lines...
                    line.stripUInt64(currentCallCount);
                    nextLineType = CallCost;
                    continue;
                }

                // cmd:
                if (line.stripPrefix("md:")) {
                    QString command = QString(line).trimmed();
                    if (!_data->command().isEmpty() &&
                        _data->command() != command) {

                        error(QStringLiteral("Redefined command, was '%1'").arg(_data->command()));
                    }
                    _data->setCommand(command);
                    continue;
                }

                // creator:
                if (line.stripPrefix("reator:")) {
                    // ignore ...
                    continue;
                }

                break;

            case 'j':

                // jcnd=
                if (line.stripPrefix("cnd=")) {
                    bool valid;

                    valid = line.stripUInt64(jumpsFollowed) &&
                            line.stripPrefix("/") &&
                            line.stripUInt64(jumpsExecuted) &&
                            parsePosition(line, targetPos);

                    if (!valid) {
                        error(QStringLiteral("Invalid line after 'jcnd'"));
                    }
                    else
                        nextLineType = CondJump;
                    continue;
                }

                if (line.stripPrefix("ump=")) {
                    bool valid;

                    valid = line.stripUInt64(jumpsExecuted) &&
                            parsePosition(line, targetPos);

                    if (!valid) {
                        error(QStringLiteral("Invalid line after 'jump'"));
                    }
                    else
                        nextLineType = BoringJump;
                    continue;
                }

                // jfi=
                if (line.stripPrefix("fi=")) {
                    currentJumpToFile = compressedFile(line);
                    continue;
                }

                // jfn=
                if (line.stripPrefix("fn=")) {

                    if (!currentJumpToFile) {
                        // !=0 as functions needs file
                        currentJumpToFile = currentFile;
                    }

                    currentJumpToFunction =
                            compressedFunction(line,
                                               currentJumpToFile,
                                               currentObject);
                    continue;
                }

                break;

            case 'o':

                // ob=
                if (line.stripPrefix("b=")) {
                    setObject(line);
                    continue;
                }

                break;

            case '#':
                continue;

            case 'a':
                // "arch: arm"
                if (line.stripPrefix("rch: arm")) {
                    TraceData::Arch a = _data->architecture();
                    if ((a != TraceData::ArchUnknown) &&
                        (a != TraceData::ArchARM)) {
                        error(QStringLiteral("Redefined architecture!"));
                    }
                    _data->setArchitecture(TraceData::ArchARM);
                    continue;
                }
                break;

            case 't':

                // totals:
                if (line.stripPrefix("otals:")) continue;

                // thread:
                if (line.stripPrefix("hread:")) {
                    prepareNewPart();
                    _part->setThreadID(QString(line).toInt());
                    continue;
                }

                // timeframe (BB):
                if (line.stripPrefix("imeframe (BB):")) {
                    _part->setTimeframe(line);
                    continue;
                }

                break;

            case 'd':

                // desc:
                if (line.stripPrefix("esc:")) {

                    line.stripSurroundingSpaces();

                    // desc: Trigger:
                    if (line.stripPrefix("Trigger:")) {
                        _part->setTrigger(line);
                    }

                    continue;
                }
                break;

            case 'e':

                // events:
                if (line.stripPrefix("vents:")) {
                    prepareNewPart();
                    mapping = _data->eventTypes()->createMapping(line);
                    _part->setEventMapping(mapping);
                    continue;
                }

                // event:<name>[=<formula>][:<long name>]
                if (line.stripPrefix("vent:")) {
                    line.stripSurroundingSpaces();

                    FixString e, f, l;
                    if (!line.stripName(e)) {
                        error(QStringLiteral("Invalid event"));
                        continue;
                    }
                    line.stripSpaces();
                    if (!line.stripFirst(c)) continue;

                    if (c=='=') f = line.stripUntil(':');
                    line.stripSpaces();

                    // add to known cost types
                    if (line.isEmpty()) line = e;
                    EventType::add(new EventType(e,line,f));
                    continue;
                }
                break;

            case 'p':

                // part:
                if (line.stripPrefix("art:")) {
                    prepareNewPart();
                    _part->setPartNumber(QString(line).toInt());
                    continue;
                }

                // pid:
                if (line.stripPrefix("id:")) {
                    prepareNewPart();
                    _part->setProcessID(QString(line).toInt());
                    continue;
                }

                // positions:
                if (line.stripPrefix("ositions:")) {
                    prepareNewPart();
                    QString positions(line);
                    hasLineInfo = positions.contains(QStringLiteral("line"));
                    hasAddrInfo = positions.contains(QStringLiteral("instr"));
                    continue;
                }
                break;

            case 'v':

                // version:
                if (line.stripPrefix("ersion:")) {
                    // ignore for now
                    continue;
                }
                break;

            case 's':

                // summary:
                if (line.stripPrefix("ummary:")) {
                    if (!mapping) {
                        error(QStringLiteral("No event line found. Skipping file"));
                        delete _part;
                        return false;
                    }

                    _part->totals()->set(mapping, line);
                    continue;
                }

            case 'r':

                // rcalls= (deprecated)
                if (line.stripPrefix("calls=")) {
                    // handle like normal calls: we need the sum of call count
                    // recursive cost is discarded in cycle detection
                    line.stripUInt64(currentCallCount);
                    nextLineType = CallCost;

                    warning(QStringLiteral("Old file format using deprecated 'rcalls'"));
                    continue;
                }
                break;

            default:
                break;
            }

            error(QStringLiteral("Invalid line '%1%2'").arg(c).arg(line));
            continue;
        }

        if (!mapping) {
            error(QStringLiteral("No event line found. Skipping file"));
            delete _part;
            return false;
        }

        // for a cost line, we always need a current function
        ensureFunction();



        if (!currentFunctionSource ||
            (currentFunctionSource->file() != currentFile)) {
            currentFunctionSource = currentFunction->sourceFile(currentFile,
                                                                true);
        }

#if !USE_FIXCOST
        if (hasAddrInfo) {
            if (!currentInstr ||
                (currentInstr->addr() != currentPos.fromAddr)) {
                currentInstr = currentFunction->instr(currentPos.fromAddr,
                                                      true);

                if (!currentInstr) {
                    error(QString("Invalid address '%1'").arg(currentPos.fromAddr.toString()));

                    continue;
                }

                currentPartInstr = currentInstr->partInstr(_part,
                                                           currentPartFunction);
            }
        }

        if (hasLineInfo) {
            if (!currentLine ||
                (currentLine->lineno() != currentPos.fromLine)) {

                currentLine = currentFunctionSource->line(currentPos.fromLine,
                                                          true);
                currentPartLine = currentLine->partLine(_part,
                                                        currentPartFunction);
            }
            if (hasAddrInfo && currentInstr)
                currentInstr->setLine(currentLine);
        }
#endif

#if TRACE_LOADER
        qDebug() << _filename << ":" << _lineNo;
        qDebug() << "  currentInstr "
                 << (currentInstr ? qPrintable(currentInstr->toString()) : ".");
        qDebug() << "  currentLine "
                 << (currentLine ? qPrintable(currentLine->toString()) : ".")
                 << "( file " << currentFile->name() << ")";
        qDebug() << "  currentFunction "
                 << qPrintable(currentFunction->prettyName());
        qDebug() << "  currentCalled "
                 << (currentCalledFunction ? qPrintable(currentCalledFunction->prettyName()) : ".");
#endif

        // create cost item

        if (nextLineType == SelfCost) {

#if USE_FIXCOST
            new (pool) FixCost(_part, pool,
                               currentFunctionSource,
                               currentPos,
                               currentPartFunction,
                               line);
#else
            if (hasAddrInfo) {
                TracePartInstr* partInstr;
                partInstr = currentInstr->partInstr(_part, currentPartFunction);

                if (hasLineInfo) {
                    // we need to set <line> back after reading for the line
                    int l = line.len();
                    const char* s = line.ascii();

                    partInstr->addCost(mapping, line);
                    line.set(s,l);
                }
                else
                    partInstr->addCost(mapping, line);
            }

            if (hasLineInfo) {
                TracePartLine* partLine;
                partLine = currentLine->partLine(_part, currentPartFunction);
                partLine->addCost(mapping, line);
            }
#endif

            if (!line.isEmpty()) {
                error(QStringLiteral("Garbage at end of cost line ('%1')").arg(line));
            }
        }
        else if (nextLineType == CallCost) {
            nextLineType = SelfCost;

            TraceCall* calling = currentFunction->calling(currentCalledFunction);
            TracePartCall* partCalling =
                    calling->partCall(_part, currentPartFunction,
                                      currentCalledPartFunction);

#if USE_FIXCOST
            FixCallCost* fcc;
            fcc = new (pool) FixCallCost(_part, pool,
                                         currentFunctionSource,
                                         hasLineInfo ? currentPos.fromLine : 0,
                                         hasAddrInfo ? currentPos.fromAddr : Addr(0),
                                         partCalling,
                                         currentCallCount, line);
            fcc->setMax(_data->callMax());
            _data->updateMaxCallCount(fcc->callCount());
#else
            if (hasAddrInfo) {
                TraceInstrCall* instrCall;
                TracePartInstrCall* partInstrCall;

                instrCall = calling->instrCall(currentInstr);
                partInstrCall = instrCall->partInstrCall(_part, partCalling);
                partInstrCall->addCallCount(currentCallCount);

                if (hasLineInfo) {
                    // we need to set <line> back after reading for the line
                    int l = line.len();
                    const char* s = line.ascii();

                    partInstrCall->addCost(mapping, line);
                    line.set(s,l);
                }
                else
                    partInstrCall->addCost(mapping, line);

                // update maximum of call cost
                _data->callMax()->maxCost(partInstrCall);
                _data->updateMaxCallCount(partInstrCall->callCount());
            }

            if (hasLineInfo) {
                TraceLineCall* lineCall;
                TracePartLineCall* partLineCall;

                lineCall = calling->lineCall(currentLine);
                partLineCall = lineCall->partLineCall(_part, partCalling);

                partLineCall->addCallCount(currentCallCount);
                partLineCall->addCost(mapping, line);

                // update maximum of call cost
                _data->callMax()->maxCost(partLineCall);
                _data->updateMaxCallCount(partLineCall->callCount());
            }
#endif
            currentCalledFile = 0;
            currentCalledPartFile = 0;
            currentCalledObject = 0;
            currentCalledPartObject = 0;
            currentCallCount = 0;

            if (!line.isEmpty()) {
                error(QStringLiteral("Garbage at end of call cost line ('%1')").arg(line));
            }
        }
        else { // (nextLineType == BoringJump || nextLineType == CondJump)

            TraceFunctionSource* targetSource;

            if (!currentJumpToFunction)
                currentJumpToFunction = currentFunction;

            targetSource = (currentJumpToFile) ?
                               currentJumpToFunction->sourceFile(currentJumpToFile, true) :
                               currentFunctionSource;

#if USE_FIXCOST
            new (pool) FixJump(_part, pool,
                               /* source */
                               hasLineInfo ? currentPos.fromLine : 0,
                               hasAddrInfo ? currentPos.fromAddr : 0,
                               currentPartFunction,
                               currentFunctionSource,
                               /* target */
                               hasLineInfo ? targetPos.fromLine : 0,
                               hasAddrInfo ? targetPos.fromAddr : Addr(0),
                               currentJumpToFunction,
                               targetSource,
                               (nextLineType == CondJump),
                               jumpsExecuted, jumpsFollowed);
#else
            if (hasAddrInfo) {
                TraceInstr* jumpToInstr;
                TraceInstrJump* instrJump;
                TracePartInstrJump* partInstrJump;

                jumpToInstr = currentJumpToFunction->instr(targetPos.fromAddr,
                                                           true);
                instrJump = currentInstr->instrJump(jumpToInstr,
                                                    (nextLineType == CondJump));
                partInstrJump = instrJump->partInstrJump(_part);
                partInstrJump->addExecutedCount(jumpsExecuted);
                if (nextLineType == CondJump)
                    partInstrJump->addFollowedCount(jumpsFollowed);
            }

            if (hasLineInfo) {
                TraceLine* jumpToLine;
                TraceLineJump* lineJump;
                TracePartLineJump* partLineJump;

                jumpToLine = targetSource->line(targetPos.fromLine, true);
                lineJump = currentLine->lineJump(jumpToLine,
                                                 (nextLineType == CondJump));
                partLineJump = lineJump->partLineJump(_part);

                partLineJump->addExecutedCount(jumpsExecuted);
                if (nextLineType == CondJump)
                    partLineJump->addFollowedCount(jumpsFollowed);
            }
#endif

            if (0) {
                qDebug() << _filename << ":" << _lineNo
                         << " - jump from 0x" << currentPos.fromAddr.toString()
                         << " (line " << currentPos.fromLine
                         << ") to 0x" << targetPos.fromAddr.toString()
                         << " (line " << targetPos.fromLine << ")";

                if (nextLineType == BoringJump)
                    qDebug() << " Boring Jump, count " << jumpsExecuted.pretty();
                else
                    qDebug() << " Cond. Jump, followed " << jumpsFollowed.pretty()
                             << ", executed " << jumpsExecuted.pretty();
            }

            nextLineType = SelfCost;
            currentJumpToFunction = 0;
            currentJumpToFile = 0;

            if (!line.isEmpty()) {
                error(QStringLiteral("Garbage at end of jump cost line ('%1')").arg(line));
            }

        }
    }

    loadFinished();

    if (mapping) {
        _part->invalidate();
        _part->totals()->clear();
        _part->totals()->addCost(_part);
        data->addPart(_part);
        partsAdded++;
    }
    else {
        delete _part;
    }

    device->close();

    return partsAdded;
}
Exemplo n.º 8
0
/**
 * Return false if this is no position specification
 */
bool CachegrindLoader::parsePosition(FixString& line,
                                     PositionSpec& newPos)
{
    char c;
    uint diff;

    if (hasAddrInfo) {

        if (!line.first(c)) return false;

        if (c == '*') {
            // nothing changed
            line.stripFirst(c);
            newPos.fromAddr = currentPos.fromAddr;
            newPos.toAddr = currentPos.toAddr;
        }
        else if (c == '+') {
            line.stripFirst(c);
            line.stripUInt(diff, false);
            newPos.fromAddr = currentPos.fromAddr + diff;
            newPos.toAddr = newPos.fromAddr;
        }
        else if (c == '-') {
            line.stripFirst(c);
            line.stripUInt(diff, false);
            newPos.fromAddr = currentPos.fromAddr - diff;
            newPos.toAddr = newPos.fromAddr;
        }
        else if (c >= '0') {
            uint64 v;
            line.stripUInt64(v, false);
            newPos.fromAddr = Addr(v);
            newPos.toAddr = newPos.fromAddr;
        }
        else return false;

        // Range specification
        if (line.first(c)) {
            if (c == '+') {
                line.stripFirst(c);
                line.stripUInt(diff);
                newPos.toAddr = newPos.fromAddr + diff;
            }
            else if ((c == '-') || (c == ':')) {
                line.stripFirst(c);
                uint64 v;
                line.stripUInt64(v);
                newPos.toAddr = Addr(v);
            }
        }
        line.stripSpaces();

#if TRACE_LOADER
        if (newPos.fromAddr == newPos.toAddr)
            qDebug() << " Got Addr " << newPos.fromAddr.toString();
        else
            qDebug() << " Got AddrRange " << newPos.fromAddr.toString()
                     << ":" << newPos.toAddr.toString();
#endif

    }

    if (hasLineInfo) {

        if (!line.first(c)) return false;

        if (c > '9') return false;
        else if (c == '*') {
            // nothing changed
            line.stripFirst(c);
            newPos.fromLine = currentPos.fromLine;
            newPos.toLine   = currentPos.toLine;
        }
        else if (c == '+') {
            line.stripFirst(c);
            line.stripUInt(diff, false);
            newPos.fromLine = currentPos.fromLine + diff;
            newPos.toLine = newPos.fromLine;
        }
        else if (c == '-') {
            line.stripFirst(c);
            line.stripUInt(diff, false);
            if (currentPos.fromLine < diff) {
                error(QStringLiteral("Negative line number %1")
                      .arg((int)currentPos.fromLine - (int)diff));
                diff = currentPos.fromLine;
            }
            newPos.fromLine = currentPos.fromLine - diff;
            newPos.toLine = newPos.fromLine;
        }
        else if (c >= '0') {
            line.stripUInt(newPos.fromLine, false);
            newPos.toLine = newPos.fromLine;
        }
        else return false;

        // Range specification
        if (line.first(c)) {
            if (c == '+') {
                line.stripFirst(c);
                line.stripUInt(diff);
                newPos.toLine = newPos.fromLine + diff;
            }
            else if ((c == '-') || (c == ':')) {
                line.stripFirst(c);
                line.stripUInt(newPos.toLine);
            }
        }
        line.stripSpaces();

#if TRACE_LOADER
        if (newPos.fromLine == newPos.toLine)
            qDebug() << " Got Line " << newPos.fromLine;
        else
            qDebug() << " Got LineRange " << newPos.fromLine
                     << ":" << newPos.toLine;
#endif

    }

    return true;
}
Exemplo n.º 9
0
	void TestStage::onRender( float dFrame )
	{
		glDisable( GL_DEPTH_TEST );
		glDisable( GL_CULL_FACE );
		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
		glEnable( GL_STENCIL_TEST );

		GameWindow& window = Global::getDrawEngine()->getWindow();
		int w = window.getWidth();
		int h = window.getHeight();

	
		for ( LightList::iterator iter = lights.begin(), itEnd = lights.end();
			  iter != itEnd ; ++iter )
		{
			Light& light = *iter;

#if 1
			glColorMask(false, false, false, false);
			glStencilFunc(GL_ALWAYS, 1, 1);
			glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);

			for( BlockList::iterator iter = blocks.begin(), itEnd = blocks.end();
				 iter != itEnd ; ++iter )
			{
				Block& block = *iter;
				renderPolyShadow( light , block.pos , block.getVertices() , block.getVertexNum() );
			}
			
			glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
			glStencilFunc(GL_EQUAL, 0, 1);
			glColorMask(true, true, true, true);
#endif

			glEnable(GL_BLEND);
			glBlendFunc(GL_ONE, GL_ONE);

			glUseProgram(program);

			glUniform2f( loc_lightLocation , light.pos.x , light.pos.y );
			glUniform3f( loc_lightColor , light.color.x , light.color.y , light.color.z );
			glUniform3f( loc_lightAttenuation , 0 , 1 / 5.0 , 0 );

			glBegin( GL_QUADS );
			glVertex2i( 0 , 0 );
			glVertex2i( w , 0 );
			glVertex2i( w , h );
			glVertex2i( 0 , h );
			glEnd();

			glUseProgram(0);
			glDisable(GL_BLEND);
			glClear(GL_STENCIL_BUFFER_BIT);
		}

		glDisable( GL_STENCIL_TEST );


		GLGraphics2D& g = ::Global::getDrawEngine()->getGLGraphics();

		g.beginRender();

		RenderUtility::setFont( g , FONT_S8 );
		FixString< 256 > str;
		Vec2i pos = Vec2i( 10 , 10 );
		g.drawText( pos , str.format( "Lights Num = %u" , lights.size() ) );

		g.endRender();
	}
Exemplo n.º 10
0
void Game::run()
{
	using std::cout;
	using std::endl;

	int prevTime = Platform::getTickCount();
	int64 timeFrame = Platform::getTickCount();
	int frameCount = 0;

	IText* text = IText::create( mFonts[0] , 18 , Color(255,255,25) );

	static int const NUM_FPS_SAMPLES = 12;
	float fpsSamples[NUM_FPS_SAMPLES];
	int   NumFramePerSample = 10;
	std::fill_n( fpsSamples , NUM_FPS_SAMPLES , 60.0f );
	int  idxSample = 0;

	while( !mNeedEnd )
	{
		int64 curTime = Platform::getTickCount();
		float deltaT = ( curTime - prevTime ) / 1000.0f;
		prevTime = curTime;

		while ( mStageAdd )
		{
			if( mbRemovePrevStage )
			{
				mStageStack.back()->onExit();
				delete mStageStack.back();
				mStageStack.pop_back();
				cout << "Old stage deleted." << endl;
			}

			GameStage* stage = mStageAdd;
			mStageAdd = NULL;
			mStageStack.push_back( stage );
			cout << "Setup new state..." << endl;
			if ( !stage->onInit() )
			{
				cout << "Stage Can't Init !" << endl;
			}
			cout << "Stage Init !" << endl;
		}

		GameStage* stage = mStageStack.back();

		mSoundMgr->update( deltaT );
		stage->onUpdate( deltaT );

		if ( mRenderSystem->prevRender() )
		{
			stage->onRender();

			++frameCount;
			if ( frameCount > NumFramePerSample )
			{
				int64 temp = Platform::getTickCount();
				fpsSamples[idxSample] = 1000.0f * ( frameCount ) / (  temp - timeFrame );
				timeFrame = temp;
				frameCount = 0;

				++idxSample;
				if ( idxSample == NUM_FPS_SAMPLES )
					idxSample = 0;

				mFPS = 0;
				for (int i = 0; i < NUM_FPS_SAMPLES; i++)
					mFPS += fpsSamples[i];

				mFPS /= NUM_FPS_SAMPLES;
#if 0
				std::cout << "FPS =" << mFPS << std::endl;
#endif
			}

			FixString< 256 > str;
			str.format( "FPS = %f" , mFPS );
			text->setString( str.c_str() );

			mRenderSystem->drawText( text , 
				Vec2i( getGame()->getScreenSize().x - 100 , 10 ) , 
				TEXT_SIDE_LEFT | TEXT_SIDE_TOP );

			mRenderSystem->postRender();
		}

		if( stage->needStop() )
		{
			mStageStack.pop_back();
			stage->onExit();
			delete stage;
			cout << "Stage Exit !" << endl;
		}
		if( mStageStack.empty() )		
			mNeedEnd=true;
	}

	text->release();
}