add image_reader abstraction layer to hanfle multiple image formats
(work-in-progress)
This commit is contained in:
50
include/mbgl/util/factory.hpp
Normal file
50
include/mbgl/util/factory.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef MBGL_UTIL_FACTORY_HPP
|
||||
#define MBGL_UTIL_FACTORY_HPP
|
||||
|
||||
#include "singleton.hpp"
|
||||
|
||||
// stl
|
||||
#include <stdexcept>
|
||||
#include <map>
|
||||
|
||||
namespace mbgl { namespace util {
|
||||
|
||||
template
|
||||
<
|
||||
typename product_type,
|
||||
typename key_type,
|
||||
typename ...Args >
|
||||
class factory : public singleton<factory <product_type,
|
||||
key_type,
|
||||
Args...> >
|
||||
{
|
||||
private:
|
||||
using product_creator = product_type* (*) (Args...);
|
||||
using product_map = std::map<key_type,product_creator>;
|
||||
product_map map_;
|
||||
public:
|
||||
|
||||
bool register_product(key_type const& key, product_creator creator)
|
||||
{
|
||||
return map_.insert(typename product_map::value_type(key,creator)).second;
|
||||
}
|
||||
|
||||
bool unregister_product(const key_type& key)
|
||||
{
|
||||
return map_.erase(key)==1;
|
||||
}
|
||||
|
||||
product_type* create_object(key_type const& key, Args...args)
|
||||
{
|
||||
typename product_map::const_iterator pos=map_.find(key);
|
||||
if (pos!=map_.end())
|
||||
{
|
||||
return (pos->second)(args...);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
50
include/mbgl/util/image_reader.hpp
Normal file
50
include/mbgl/util/image_reader.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef MBGL_UTIL_IMAGE_READER_HPP
|
||||
#define MBGL_UTIL_IMAGE_READER_HPP
|
||||
|
||||
#include "factory.hpp"
|
||||
#include "noncopyable.hpp"
|
||||
// stl
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl { namespace util {
|
||||
|
||||
class image_reader_exception : public std::exception
|
||||
{
|
||||
private:
|
||||
std::string message_;
|
||||
public:
|
||||
image_reader_exception(std::string const& message)
|
||||
: message_(message) {}
|
||||
|
||||
~image_reader_exception() throw() {}
|
||||
|
||||
virtual const char* what() const throw()
|
||||
{
|
||||
return message_.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
struct image_reader : private noncopyable
|
||||
{
|
||||
virtual unsigned width() const=0;
|
||||
virtual unsigned height() const=0;
|
||||
virtual bool has_alpha() const=0;
|
||||
virtual bool premultiplied_alpha() const=0;
|
||||
virtual void read(unsigned x,unsigned y, unsigned width, unsigned height, char* image)=0;
|
||||
virtual ~image_reader() {}
|
||||
};
|
||||
|
||||
template <typename...Args>
|
||||
bool register_image_reader(std::string const& type, image_reader* (* fun)(Args...))
|
||||
{
|
||||
return factory<image_reader,std::string, Args...>::instance().register_product(type, fun);
|
||||
}
|
||||
|
||||
//image_reader* get_image_reader(std::string const& file,std::string const& type);
|
||||
//image_reader* get_image_reader(std::string const& file);
|
||||
image_reader* get_image_reader(char const* data, size_t size);
|
||||
|
||||
}}
|
||||
|
||||
#endif
|
||||
126
include/mbgl/util/singleton.hpp
Normal file
126
include/mbgl/util/singleton.hpp
Normal file
@@ -0,0 +1,126 @@
|
||||
#ifndef MBGL_UTIL_SINGLETON_HPP
|
||||
#define MBGL_UTIL_SINGLETON_HPP
|
||||
|
||||
// stl
|
||||
#include <stdexcept> // std::runtime_error
|
||||
#include <cstdlib> // std::atexit
|
||||
#include <new> // operator new
|
||||
#define SINGLETON_THREADSAFE
|
||||
#ifdef SINGLETON_THREADSAFE
|
||||
#include <mutex>
|
||||
#endif
|
||||
|
||||
namespace mbgl { namespace util {
|
||||
|
||||
template <typename T>
|
||||
class CreateUsingNew
|
||||
{
|
||||
public:
|
||||
static T* create()
|
||||
{
|
||||
return new T;
|
||||
}
|
||||
static void destroy(T* obj)
|
||||
{
|
||||
delete obj;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class CreateStatic
|
||||
{
|
||||
private:
|
||||
union MaxAlign
|
||||
{
|
||||
char t_[sizeof(T)];
|
||||
short int shortInt_;
|
||||
int int_;
|
||||
long int longInt_;
|
||||
float float_;
|
||||
double double_;
|
||||
long double longDouble_;
|
||||
struct Test;
|
||||
int Test::* pMember_;
|
||||
int (Test::*pMemberFn_)(int);
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
static T* create()
|
||||
{
|
||||
static MaxAlign staticMemory;
|
||||
return new(&staticMemory) T;
|
||||
}
|
||||
static void destroy(volatile T* obj)
|
||||
{
|
||||
obj->~T();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T,
|
||||
template <typename U> class CreatePolicy=CreateStatic> class singleton
|
||||
{
|
||||
friend class CreatePolicy<T>;
|
||||
static T* pInstance_;
|
||||
static bool destroyed_;
|
||||
singleton(const singleton &rhs);
|
||||
singleton& operator=(const singleton&);
|
||||
|
||||
static void onDeadReference()
|
||||
{
|
||||
throw std::runtime_error("dead reference!");
|
||||
}
|
||||
|
||||
static void DestroySingleton()
|
||||
{
|
||||
CreatePolicy<T>::destroy(pInstance_);
|
||||
pInstance_ = 0;
|
||||
destroyed_ = true;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
#ifdef SINGLETON_THREADSAFE
|
||||
static std::mutex mutex_;
|
||||
#endif
|
||||
singleton() {}
|
||||
public:
|
||||
static T& instance()
|
||||
{
|
||||
if (! pInstance_)
|
||||
{
|
||||
#ifdef SINGLETON_THREADSAFE
|
||||
std::unique_lock<std::mutex> lock(mutex_);
|
||||
#endif
|
||||
if (! pInstance_)
|
||||
{
|
||||
if (destroyed_)
|
||||
{
|
||||
destroyed_ = false;
|
||||
onDeadReference();
|
||||
}
|
||||
else
|
||||
{
|
||||
pInstance_ = CreatePolicy<T>::create();
|
||||
// register destruction
|
||||
std::atexit(&DestroySingleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
return *pInstance_;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef SINGLETON_THREADSAFE
|
||||
template <typename T,
|
||||
template <typename U> class CreatePolicy> std::mutex singleton<T,CreatePolicy>::mutex_;
|
||||
#endif
|
||||
|
||||
template <typename T,
|
||||
template <typename U> class CreatePolicy> T* singleton<T,CreatePolicy>::pInstance_=0;
|
||||
template <typename T,
|
||||
template <typename U> class CreatePolicy> bool singleton<T,CreatePolicy>::destroyed_=false;
|
||||
|
||||
}}
|
||||
|
||||
#endif //
|
||||
Reference in New Issue
Block a user