Example #1
0
    void recycle(GarbageDestructor condition = 0)
    {
        DENG2_GUARD(this);

        if (allocs.empty()) return;

#ifdef DENG2_DEBUG
        //qDebug() << "[Garbage] Recycling" << allocs.size() << "allocs/objects";
#endif

        for (Allocs::iterator i = allocs.begin(); i != allocs.end(); )
        {
            Allocs::iterator next = i;
            ++next;

            DENG2_ASSERT(i->second);
            if (!condition || i->second == condition)
            {
                i->second(i->first);

                // Erase one by one if a condition has been given.
                if (condition) allocs.erase(i);
            }

            i = next;
        }

        if (!condition)
        {
            // All can be erased as we have no condition.
            allocs.clear();
        }
    }
Example #2
0
    bool contains(void const *ptr) const
    {
        DENG2_GUARD(this);

        Allocs::const_iterator i = allocs.find(const_cast<void *>(ptr));
        return i != allocs.end();
    }
Example #3
0
bool PathTree::has(Path const &path, ComparisonFlags flags) const
{
    DENG2_GUARD(this);

    flags &= ~RelinquishMatching; // never relinquish
    return d->find(path, flags) != 0;
}
void MemoryLogSink::clear()
{
    DENG2_GUARD(this);

    qDeleteAll(_entries);
    _entries.clear();
}
Example #5
0
void NativeFile::flush()
{
    DENG2_GUARD(this);

    d->closeOutput();
    DENG2_ASSERT(!d->out);
}
Example #6
0
void NativeFile::set(Offset at, Byte const *values, Size count)
{
    DENG2_GUARD(this);

    QFile &out = output();
    if (at > size())
    {
        /// @throw IByteArray::OffsetError  @a at specified a position beyond the
        /// end of the file.
        throw OffsetError("NativeFile::set", "Cannot write past end of file");
    }
    out.seek(at);
    out.write(reinterpret_cast<char const *>(values), count);
    if (out.error() != QFile::NoError)
    {
        /// @throw OutputError  Failure to write to the native file.
        throw OutputError("NativeFile::set", "Error writing to file:" +
                          out.errorString());
    }
    // Update status.
    Status st = status();
    st.size = max(st.size, at + count);
    st.modifiedAt = Time();
    setStatus(st);
}
Example #7
0
 void recycleWithDestructor(GarbageDestructor func)
 {
     DENG2_GUARD(this);
     for (iterator i = begin(); i != end(); ++i)
     {
         i->second->recycle(func);
     }
 }
Example #8
0
void LoopCallback::enqueue(Callback func)
{
    DENG2_GUARD(this);

    _funcs << func;

    Loop::get().audienceForIteration() += this;
}
Example #9
0
    BusyRunner::DeferredResult performDeferredGLTask() override
    {
        initPendingModels(1);

        DENG2_GUARD(pendingModels);
        return pendingModels.value.isEmpty()? BusyRunner::AllTasksCompleted
                                            : BusyRunner::TasksPending;
    }
ArchiveEntryFile::~ArchiveEntryFile()
{
    DENG2_GUARD(this);

    DENG2_FOR_AUDIENCE2(Deletion, i) i->fileBeingDeleted(*this);
    audienceForDeletion().clear();
    
    deindex();
}
Example #11
0
void MemoryLogSink::remove(int pos, int n)
{
    DENG2_GUARD(this);

    while(n-- > 0)
    {
        delete _entries.takeAt(pos);
    }
}
Example #12
0
 void clearAll()
 {
     DENG2_GUARD(this);
     for (iterator i = begin(); i != end(); ++i)
     {
         delete i->second;
     }
     clear();
 }
Example #13
0
LogSink &MemoryLogSink::operator << (LogEntry const &entry)
{
    if(entry.level() >= _minLevel)
    {
        DENG2_GUARD(this);
        _entries.append(new LogEntry(entry));
        addedNewEntry(*_entries.back());
    }
    return *this;
}
Example #14
0
File &LinkFile::target()
{
    DENG2_GUARD(this);

    if (d->target)
    {
        return *const_cast<File *>(d->target.get());
    }
    return File::target();
}
Example #15
0
File const &LinkFile::target() const
{
    DENG2_GUARD(this);

    if (d->target)
    {
        return *d->target;
    }
    return File::target();
}
Example #16
0
String LinkFile::describe() const
{
    DENG2_GUARD(this);

    if (!isBroken())
    {
        DENG2_GUARD_FOR(target(), G);
        return "link to " + target().description();
    }
    return "broken link";
}
Example #17
0
void NativeFile::clear()
{
    DENG2_GUARD(this);

    File::clear();

    Flags oldMode = mode();
    setMode(Write | Truncate);
    d->getOutput();
    File::setMode(oldMode);
}
Example #18
0
void NativeFile::setMode(Flags const &newMode)
{
    DENG2_GUARD(this);

    close();
    File::setMode(newMode);

    if (newMode.testFlag(Truncate))
    {
        d->needTruncation = true;
    }
}
Example #19
0
PathTree::Node const &PathTree::find(Path const &searchPath, ComparisonFlags flags) const
{
    DENG2_GUARD(this);

    Node const *found = d->find(searchPath, flags);
    if(!found)
    {
        /// @throw NotFoundError  The referenced node could not be found.
        throw NotFoundError("PathTree::find", "No paths found matching \"" + searchPath + "\"");
    }
    return *found;
}
Example #20
0
PathTree::Node &PathTree::insert(Path const &path)
{
    DENG2_GUARD(this);

    PathTree::Node *node = d->buildNodesForPath(path);
    DENG2_ASSERT(node != 0);

    // There is now one more unique path in the tree.
    d->size++;

    return *node;
}
void ArchiveEntryFile::clear()
{
    DENG2_GUARD(this);

    File::clear();
    
    archive().entryBlock(_entryPath).clear();
    
    // Update status.
    Status st = status();
    st.size = 0;
    st.modifiedAt = Time();
    setStatus(st);
}
String ArchiveFolder::describe() const
{
    DENG2_GUARD(this);

    String desc = String("archive \"%1\"").arg(name());

    String const feedDesc = describeFeeds();
    if(!feedDesc.isEmpty())
    {
        desc += String(" (%1)").arg(feedDesc);
    }

    return desc;
}
Example #23
0
void NativeFile::get(Offset at, Byte *values, Size count) const
{
    DENG2_GUARD(this);

    QFile &in = input();
    if(at + count > size())
    {
        /// @throw IByteArray::OffsetError  The region specified for reading extends
        /// beyond the bounds of the file.
        throw OffsetError("NativeFile::get", description() + ": cannot read past end of file " +
                          String("(%1[+%2] > %3)").arg(at).arg(count).arg(size()));
    }
    in.seek(at);
    in.read(reinterpret_cast<char *>(values), count);
}
Example #24
0
bool PathTree::remove(Path const &path, ComparisonFlags flags)
{
    DENG2_GUARD(this);

    PathTree::Node *node = d->find(path, flags | RelinquishMatching);
    if(node)
    {
        delete node;

        // One less unique path in the tree.
        d->size--;
        return true;
    }
    return false;
}
void ArchiveEntryFile::set(Offset at, Byte const *values, Size count)
{
    DENG2_GUARD(this);

    verifyWriteAccess();
    
    // The entry will be marked for recompression (due to non-const access).
    Block &entryBlock = archive().entryBlock(_entryPath);
    entryBlock.set(at, values, count);
    
    // Update status.
    Status st = status();
    st.size = entryBlock.size();
    st.modifiedAt = Time();
    setStatus(st);
}
void ArchiveEntryFile::set(Offset at, Byte const *values, Size count)
{
    DENG2_GUARD(this);

    verifyWriteAccess();
    
    // The entry will be marked for recompression (due to non-const access).
    Block &entryBlock = archive().entryBlock(_entryPath);
    entryBlock.set(at, values, count);
    
    // Update status.
    Status st = status();
    st.size = entryBlock.size();
    // Timestamps must match, otherwise would be pruned needlessly.
    st.modifiedAt = archive().entryStatus(_entryPath).modifiedAt;
    setStatus(st);
}
Example #27
0
    void assetAvailabilityChanged(String const &identifier, filesys::AssetObserver::Event event) override
    {
        LOG_RES_MSG("Model asset \"%s\" is now %s")
                << identifier
                << (event == filesys::AssetObserver::Added? "available" :
                                                            "unavailable");

        if (event == filesys::AssetObserver::Added)
        {
            bank.add(identifier, App::asset(identifier).absolutePath("path"));

            // Begin loading the model right away.
            bank.load(identifier);
        }
        else
        {
            auto const &model = bank.model<render::Model const>(identifier);

            // Unload programs used by the various rendering passes.
            for (auto const &pass : model.passes)
            {
                DENG2_ASSERT(pass.program);
                unloadProgram(*static_cast<Program *>(pass.program));
            }

            // Alternatively, the entire model may be using a single program.
            if (model.passes.isEmpty())
            {
                if (model.program())
                {
                    unloadProgram(*static_cast<Program *>(model.program()));
                }
            }
            else
            {
                DENG2_ASSERT(!model.program());
            }

            bank.remove(identifier);
            {
                DENG2_GUARD(pendingModels);
                pendingModels.value.remove(identifier);
            }
        }
    }
Example #28
0
void LoopCallback::loopIteration()
{
    QList<Callback> funcs;

    // Lock while modifying but not during the callbacks themselves.
    {
        DENG2_GUARD(this);
        Loop::get().audienceForIteration() -= this;

        // Make a copy of the list if new callbacks get enqueued in the callback.
        funcs = _funcs;
        _funcs.clear();
    }

    for (Callback const &cb : funcs)
    {
        cb();
    }
}
Example #29
0
void NativeFile::get(Offset at, Byte *values, Size count) const
{
    DENG2_GUARD(this);

    if (at + count > size())
    {
        d->closeInput();
        /// @throw IByteArray::OffsetError  The region specified for reading extends
        /// beyond the bounds of the file.
        throw OffsetError("NativeFile::get", description() + ": cannot read past end of file " +
                          String("(%1[+%2] > %3)").arg(at).arg(count).arg(size()));
    }
    QFile &in = input();
    if (in.pos() != qint64(at)) in.seek(qint64(at));
    in.read(reinterpret_cast<char *>(values), count);

    // Close the native input file after reaching the end of the file.
    if (in.atEnd())
    {
        d->closeInput();
    }
}
Example #30
0
    /**
     * Initializes one or more uninitialized models for rendering.
     * Must be called from the main thread.
     *
     * @param maxCount  Maximum number of models to initialize.
     */
    void initPendingModels(int maxCount)
    {
        DENG2_GUARD(pendingModels);

        while (!pendingModels.value.isEmpty() && maxCount > 0)
        {
            String const identifier = *pendingModels.value.begin();
            pendingModels.value.remove(identifier);

            if (!bank.has(identifier))
            {
                continue;
            }

            LOG_GL_MSG("Initializing \"%s\"") << identifier;

            auto &model = bank.model<render::Model>(identifier);
            model.glInit();

            --maxCount;
        }
    }