Haven't been active much, programming wise lately, so I decided I'd start at another engine-writing attempt.

After spending most of the last two days pulling my hair out, I think I finally came up with a usable resource manager.

The concept I was going for, was to have only one resource manager (as a singleton) to track Resource objects, which would be the base class for resources. For memory management, I decided to store the resources as reference counting pointers. The resource manager wraps std::map<std::string, CountedPtr<Resource> > for storage and tracking.

I dunno if anything I came up with was necessarily the best way of going about things. I haven't really bothered to write "full" resource manager before. Which is why I'm posting it for you all to comment on . (I won't bother posting headers). The code is also probably full of bugs and other issues - I haven't gotten around to testing yet. Not enough of the other parts of the engine are completed yet.

Resource.cpp:
Code:
#include "pch.h"
#include "Resource.h"

namespace Sakti{
    
    Resource::Resource(string name, string type){
        _name = name;
        _type = type;
        _id = rand(); //TODO: fix
        
        load();
    }
    Resource::~Resource(){
        unload();
    }
    
    string Resource::getName(){
        return _name;
    }
    
    string Resource::getType(){
        return _type;
    }
    
    void Resource::load(){
        loadImp();
    }
    
    void Resource::unload(){
        unloadImp();
    }
    
}
ResourceManager.cpp:
Code:
#include "pch.h"
#include "ResourceManager.h"

namespace Sakti{
    
    ResourceManager::ResourceManager(){
        _initialised = false;
    }
    ResourceManager::~ResourceManager(){
        for(_resMapItr = _resMap.begin(); _resMapItr != _resMap.end(); _resMapItr++){
            removeResource(((*_resMapItr).second)->getName());
        }
    }
    
    ResourceManager& ResourceManager::get(){
        return *singleton;
    }
    ResourceManager* ResourceManager::getPtr(){
        return singleton;
    }
    
    void ResourceManager::addResource(CountedPtr<Resource> res){
        if(_initialised){
            if(getResource(res->getName()).get() == NULL){
                _resMap.insert(std::pair<string, CountedPtr<Resource> >(res->getName(), res));
            }
            else{
                Utility::logMessage("Error adding resource: resource already exists.");
            }
        }
        else{
            MessageManager::get().sendMessage("RECOVERABLE_ERROR");
            Utility::logMessage("Error adding resource: resource manager not initialised.");
        }
    }
    
    void ResourceManager::removeResource(string name){
        if(_initialised){
            _resMapItr = _resMap.find(name);
            if(_resMapItr != _resMap.end()){
                _resMap.erase(_resMapItr);
            }
            else{
                Utility::logMessage("Error removing resource: resource not found.");
            }
        }
        else{
            MessageManager::get().sendMessage("RECOVERABLE_ERROR");
            Utility::logMessage("Error adding resource: not initialised.");
        }
            
    }
    
    CountedPtr<Resource> ResourceManager::getResource(string name){
        _resMapItr = _resMap.find(name);
        if(_resMapItr != _resMap.end()){
            return (*_resMapItr).second;
        }
        else{    
            return CountedPtr<Resource>();
        }
    }
    
    void ResourceManager::init(){
        if(!_initialised){
            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(Platform::getApplicationPath()+"Media/", "FileSystem", "Default", true);
            Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("Default");
        }
        
        _initialised = true;
    }
    
}
CountedPtr.h:
Code:
#ifndef _COUNTED_PTR_H
#define _COUNTED_PTR_H

#include "Sakti.h"

namespace Sakti{
    
    class RefCounter{
    public:
        RefCounter(){
            _count = 0;
        }
        
        size_t add(){
            _count++;
            return _count;
        }
        
        size_t remove(){
            _count--;
            return _count;
        }
        
    protected:
        size_t _count;
    };

    template<class T>
    class SAPI CountedPtr{
    public:
        explicit CountedPtr(T* ptr){
            _ptr = ptr;
            _counter = new RefCounter();
            _counter->add();
        }
        CountedPtr(const CountedPtr& ctdPtr){
            _ptr = ctdPtr._ptr;
            _counter = ctdPtr._counter;
            _counter->add();
        }
        CountedPtr(){
            _ptr = NULL;
        }
        ~CountedPtr(){
            if(_counter->remove() == 0){
                delete _ptr;
                delete _counter;
            }
        }
        
        size_t getCount(){
            return _counter->_count;
        }
        
        T* get(){
            return _ptr;
        }
        
        CountedPtr& operator=(const CountedPtr& ctdPtr){
            return *this;
        }
        
        bool operator==(const CountedPtr& ctdPtr){
            return _ptr == ctdPtr._ptr;
        }
        
        
        bool operator !=(const CountedPtr& ctdPtr){
            return _ptr != ctdPtr._ptr;
        }
        
        T& operator*(){
            return *_ptr;
        }
        
        T* operator->(){
            return _ptr;
        }
        
    protected:
        T* _ptr;
        RefCounter* _counter;
    };
    
}

#endif