186 lines
4.6 KiB
C++
186 lines
4.6 KiB
C++
/*
|
|
DB.hpp - registry holding known Asset instances.
|
|
|
|
Copyright (C) Lumiera.org
|
|
2008, Hermann Vosseler <Ichthyostega@web.de>
|
|
|
|
This program is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License as
|
|
published by the Free Software Foundation; either version 2 of
|
|
the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
|
|
#ifndef ASSET_DB_H
|
|
#define ASSET_DB_H
|
|
|
|
|
|
#include "lib/sync.hpp"
|
|
#include "lib/error.hpp"
|
|
#include "proc/asset.hpp"
|
|
|
|
#include <memory>
|
|
#include <unordered_map>
|
|
// #include <boost/functional/hash.hpp> /////////TODO which boost include to use here??
|
|
#include <boost/utility.hpp>
|
|
|
|
|
|
namespace proc {
|
|
namespace asset {
|
|
|
|
using std::static_pointer_cast;
|
|
using std::dynamic_pointer_cast;
|
|
|
|
using lib::Sync;
|
|
using lib::RecursiveLock_NoWait;
|
|
|
|
|
|
/* ===== hash implementations ===== */
|
|
|
|
size_t
|
|
hash_value (Asset::Ident const& idi)
|
|
{
|
|
size_t hash = 0;
|
|
boost::hash_combine(hash, idi.org);
|
|
boost::hash_combine(hash, idi.name);
|
|
boost::hash_combine(hash, idi.category);
|
|
return hash;
|
|
}
|
|
|
|
size_t
|
|
hash_value (Asset const& asset)
|
|
{
|
|
return asset.getID();
|
|
}
|
|
|
|
|
|
/**
|
|
* trivial hash functor
|
|
* returns any hash value unmodified.
|
|
* For building a hashtable with keys
|
|
* already containing valid hash values.
|
|
*/
|
|
struct IdentityHash
|
|
: public std::unary_function<size_t, size_t>
|
|
{
|
|
size_t
|
|
operator() (size_t val) const { return val; }
|
|
};
|
|
|
|
typedef std::unordered_map<size_t, PAsset, IdentityHash> IdHashtable;
|
|
|
|
|
|
|
|
|
|
/**
|
|
* Implementation of the registry holding all Asset
|
|
* instances known to the Asset Manager subsystem.
|
|
* As of 8/2007 implemented by a hashtable.
|
|
*/
|
|
class DB
|
|
: private boost::noncopyable,
|
|
public Sync<RecursiveLock_NoWait>
|
|
{
|
|
IdHashtable table;
|
|
|
|
DB()
|
|
: table()
|
|
{ }
|
|
|
|
~DB()
|
|
{
|
|
clear();
|
|
}
|
|
|
|
friend class lib::DependencyFactory;
|
|
|
|
|
|
public:
|
|
template<class KIND>
|
|
P<KIND>
|
|
get (ID<KIND> hash) const
|
|
{
|
|
return dynamic_pointer_cast<KIND,Asset> (find (hash));
|
|
}
|
|
|
|
template<class KIND>
|
|
void
|
|
put (ID<KIND> hash, P<KIND>& ptr)
|
|
{
|
|
table[hash] = static_pointer_cast (ptr);
|
|
}
|
|
|
|
void
|
|
put (ID<Asset> hash, PAsset& ptr)
|
|
{
|
|
table[hash] = ptr;
|
|
}
|
|
|
|
bool
|
|
del (ID<Asset> hash)
|
|
{
|
|
return table.erase (hash);
|
|
}
|
|
|
|
/** removes all registered assets and does something similar
|
|
* to Asset::unlink() on each to break cyclic dependencies
|
|
* (we can't use the real unlink()-function, because this
|
|
* will propagate, including calls to the AssetManager.
|
|
* As the destructor of DB needs to call clear(), this
|
|
* could result in segfaults. This doesn't seem to be
|
|
* a problem, though, because we register and process
|
|
* \e all assets and the net effect is just breaking
|
|
* any cyclic dependencies)
|
|
* @note EX_FREE
|
|
*/
|
|
void
|
|
clear ()
|
|
try
|
|
{
|
|
IdHashtable::iterator i = table.begin();
|
|
IdHashtable::iterator e = table.end();
|
|
for ( ; i!=e ; ++i )
|
|
i->second->dependants.clear();
|
|
|
|
table.clear();
|
|
}
|
|
ERROR_LOG_AND_IGNORE (progress, "cleaning the Asset registry")
|
|
|
|
|
|
/** intended for diagnostics */
|
|
void
|
|
asList (list<PcAsset>& output) const
|
|
{
|
|
IdHashtable::const_iterator i = table.begin();
|
|
IdHashtable::const_iterator e = table.end();
|
|
for ( ; i!=e ; ++i )
|
|
output.push_back (i->second);
|
|
}
|
|
|
|
|
|
private:
|
|
const PAsset &
|
|
find (size_t hash) const
|
|
{
|
|
static const PAsset NULLP;
|
|
IdHashtable::const_iterator i = table.find (hash);
|
|
if (i == table.end())
|
|
return NULLP; // empty ptr signalling "not found"
|
|
else
|
|
return i->second;
|
|
}
|
|
};
|
|
|
|
|
|
}} // namespace proc::asset
|
|
#endif
|