ksacvet777.moy.su
Главная » Статьи » IT

Простое решение для менеджмента ресурсов создаваемых из файлов



Возможности:
  1. Простота использования. Достаточно первый раз обратиться методом ResourcesHolder::GetResource, чтобы создать объект и получить его.
  2. Автоматическое создание, автоматическое удаление ресурсов , создаваемых из файла. 
  3. Предотвращение дублирования ресурсов, с одинаковыми именами файлов. То есть  если происходит обращение по одному и тому же имени файла, что будет использован один и тот же ресурс.
  4. Возможность добавить в поиск произвольную директорию.



Недостатки:
  1. На каждый ресурс тип только одно расширение файла. Однако есть и исключения.
  2. Например файлы текстур DirectX имеют расширение dds для всех типов, но реализованы они от одного интерфейса. Функция создания текстур из файлов dds, которая распознаёт тип и создаёт соответствующий тип текстуры прилагается.
  3. Необходимость наследовать свои типы ресурсов от класса ResourceFromFile.
  4. Необходимость декларировать статический метод  создания из файла.

Как видно недостатки незначительны :).



Основной принцип:

   Класс имени файла (ResourceFileName )  Когда происходит обращение к ресурсу ( метод ResourcesHolder::GetResource  ) с случае если индекс равен 0-1, то есть не валиден, производится поиск полного пути ресурса, далее поиск не создан ли уже ресурс. Если создан, то индекс присваивается найденному и возвращается результат. Если же файл не найден в списке созданных ресурсов, то он создаётся. Второй параметр функции GetResource  - это возможный "хозяин" запрашиваемого ресурса, пот есть имя файла имеет короткий путь (например myfile.dat) и расположен в той же директории, где и "хозяин".



Пояснять лучше по ходу дела:

В этом решении три класса: 

ResourceFileName - Класс обёртка над именем файла ресурса. Помимо имени файла и пути хранит и индекс ресурса.

ResourceFromFile - Базовый класс для наследования всех ресурсов, создаваемых из файлов.

ResourcesHolder - Собственно сам менеджер ресурсов.



Загрузка:

 Если ресурсов много, то загрузку лучше выполнять отдельной операцией. 
 Чтобы произвести загрузку всех ресурсов, достаточно вызвать  ResourcesHolder::GetResource для всех объектов ResourceFromFile. 




Исходник с декларацией
#pragma once

#include <stdexcept>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

#include <boost/shared_ptr.hpp>


class ResourceFileName;
class ResourceFromFile;
class ResourcesHolder;

class ResourceFileName
{
 friend ResourcesHolder;
 ResourcesHolder* m_ResourcesHolder;
 size_t m_index;
 std::string m_filename;
 
public:

 ResourceFileName();
 ResourceFileName(const std::string& filename);
 ~ResourceFileName();

 void Reset(const std::string& filename)
 {
 m_index = 0-1;
 m_filename = filename;
 }

 size_t index() const { return m_index; }

 std::string GetFilename() const { return m_filename; }
 std::wstring GetFullpath() const;

};



class ResourceFromFile
{
public:

 virtual ~ResourceFromFile() {}

};


typedef ResourceFromFile* (*ResourceCreateCallback)(const std::wstring& path, void* userdata);


typedef std::wstring (*Convertion)( const std::string& a );

class ResourcesHolder
{
 friend ResourceFileName;

 struct resource_type_item 
 {
 ResourceCreateCallback createCallback;
 void* userdata;
 std::wstring extention;
 
 resource_type_item() : createCallback(NULL), userdata(NULL) {}
 resource_type_item(std::wstring _extention, ResourceCreateCallback _createCallback, void* _userdata) 
 : extention(_extention), createCallback(_createCallback), userdata(_userdata) {}
 };

 std::vector<resource_type_item> m_types;

 struct resource_item 
 {
 boost::shared_ptr<ResourceFromFile> resource;
 std::wstring fullpath;

 resource_item() {}
 resource_item(ResourceFromFile* r, std::wstring _fullpath) 
 : resource(r), fullpath(_fullpath) {}
 };

 std::vector<resource_item> m_resources;
 std::vector<std::wstring> m_search_dirs;

 const std::wstring& m_appl_path;
 Convertion m_conversion;

 std::vector<ResourceFileName*> m_all_filenames;

public:

 ResourcesHolder(const std::wstring& application_fullpath , Convertion _conversionFunction);
 virtual ~ResourcesHolder();

 static bool IsFileExists(const std::wstring& path);
 static bool IsFolderExists(const std::wstring& folder);
 static std::wstring GetExtention(const std::wstring& path);
 static std::wstring GetDirectory(const std::wstring& path);

 //! add additional search directory
 void AddSearchDirectory(std::wstring& dir);
 
 void AddResourceType(const std::wstring& extention, ResourceCreateCallback createCallback, void* userdata);
 bool SearchResourceFile( std::wstring& dest , std::string& filename );
 ResourceFromFile* GetResource(ResourceFileName& filename, ResourceFromFile* parent);
 
 //! remove all resources
 void DeleteResources() 
 {
 m_resources.clear();
 }


 #ifdef _DEBUG 
 void DebugHandleError(const std::string& err);
 #endif 


};





Категория: IT | Добавил: ksacvet777 (30.01.2014)
Просмотров: 262 | Теги: resource, из файлов, Ресурс, Class, Manager, C++ | Рейтинг: 0.0/0
Всего комментариев: 0
Имя *:
Email *:
Код *: