Revert "Refactoring and code style fixes in preparation of adding mesh typed items"

This reverts commit f14e7bac54.

Reverted due to missinterpretation of agreement, obvious dislike and me not interested in doing fights for feature I don't actually need
This commit is contained in:
Sapier 2015-12-29 19:55:50 +01:00
parent 25d128da36
commit 1735c20549
2 changed files with 402 additions and 485 deletions

View File

@ -28,10 +28,15 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "mapblock_mesh.h" #include "mapblock_mesh.h"
#include "mesh.h" #include "mesh.h"
#include "wieldmesh.h" #include "wieldmesh.h"
#include "client/tile.h"
#endif #endif
#include "log.h" #include "log.h"
#include "settings.h" #include "settings.h"
#include "util/serialize.h" #include "util/serialize.h"
#include "util/container.h"
#include "util/thread.h"
#include <map>
#include <set>
#ifdef __ANDROID__ #ifdef __ANDROID__
#include <GLES/gl.h> #include <GLES/gl.h>
@ -222,437 +227,429 @@ void ItemDefinition::deSerialize(std::istream &is)
// SUGG: Support chains of aliases? // SUGG: Support chains of aliases?
#ifndef SERVER class CItemDefManager: public IWritableItemDefManager
CItemDefManager::ClientCached::ClientCached() :
inventory_texture(NULL),
wield_mesh(NULL)
{}
#endif
CItemDefManager::CItemDefManager()
{ {
#ifndef SERVER #ifndef SERVER
m_main_thread = thr_get_current_thread_id(); struct ClientCached
#endif
clear();
}
/******************************************************************************/
CItemDefManager::~CItemDefManager()
{
#ifndef SERVER
const std::vector<ClientCached*> &values = m_clientcached.getValues();
for(std::vector<ClientCached*>::const_iterator
i = values.begin(); i != values.end(); ++i) {
ClientCached *cc = *i;
if (cc->wield_mesh)
cc->wield_mesh->drop();
delete cc;
}
#endif
for (std::map<std::string, ItemDefinition*>::iterator iter =
m_item_definitions.begin(); iter != m_item_definitions.end();
++iter) {
delete iter->second;
}
m_item_definitions.clear();
}
/******************************************************************************/
const ItemDefinition& CItemDefManager::get(const std::string &name_) const
{
// Convert name according to possible alias
std::string name = getAlias(name_);
// Get the definition
std::map<std::string, ItemDefinition*>::const_iterator i;
i = m_item_definitions.find(name);
if(i == m_item_definitions.end())
i = m_item_definitions.find("unknown");
assert(i != m_item_definitions.end());
return *(i->second);
}
/******************************************************************************/
std::string CItemDefManager::getAlias(const std::string &name) const
{
StringMap::const_iterator it = m_aliases.find(name);
if (it != m_aliases.end())
return it->second;
return name;
}
/******************************************************************************/
std::set<std::string> CItemDefManager::getAll() const
{
std::set<std::string> result;
for(std::map<std::string, ItemDefinition *>::const_iterator
it = m_item_definitions.begin();
it != m_item_definitions.end(); ++it) {
result.insert(it->first);
}
for (StringMap::const_iterator
it = m_aliases.begin();
it != m_aliases.end(); ++it) {
result.insert(it->first);
}
return result;
}
/******************************************************************************/
bool CItemDefManager::isKnown(const std::string &name_) const
{
// Convert name according to possible alias
std::string name = getAlias(name_);
// Get the definition
std::map<std::string, ItemDefinition*>::const_iterator i;
return m_item_definitions.find(name) != m_item_definitions.end();
}
#ifndef SERVER
/******************************************************************************/
CItemDefManager::ClientCached* CItemDefManager::createClientCachedDirect(const std::string &name,
IGameDef *gamedef) const
{
infostream<<"Lazily creating item texture and mesh for \""
<<name<<"\""<<std::endl;
// This is not thread-safe
sanity_check(thr_is_current_thread(m_main_thread));
// Skip if already in cache
ClientCached *cc = NULL;
m_clientcached.get(name, &cc);
if (cc)
return cc;
ITextureSource *tsrc = gamedef->getTextureSource();
INodeDefManager *nodedef = gamedef->getNodeDefManager();
const ItemDefinition &def = get(name);
// Create new ClientCached
cc = new ClientCached();
// Create an inventory texture
cc->inventory_texture = NULL;
if (def.inventory_image != "")
cc->inventory_texture = tsrc->getTexture(def.inventory_image);
// Additional processing for nodes:
// - Create a wield mesh if WieldMeshSceneNode can't render
// the node on its own.
// - If inventory_texture isn't set yet, create one using
// render-to-texture.
if (def.type == ITEM_NODE) {
createNodeItemTexture(name, def, nodedef, cc, gamedef, tsrc);
}
// Put in cache
m_clientcached.set(name, cc);
return cc;
}
/******************************************************************************/
CItemDefManager::ClientCached* CItemDefManager::getClientCached(const std::string &name,
IGameDef *gamedef) const
{
ClientCached *cc = NULL;
m_clientcached.get(name, &cc);
if (cc)
return cc;
if (thr_is_current_thread(m_main_thread)) {
return createClientCachedDirect(name, gamedef);
}
else
{ {
// We're gonna ask the result to be put into here video::ITexture *inventory_texture;
static ResultQueue<std::string, ClientCached*, u8, u8> result_queue; scene::IMesh *wield_mesh;
// Throw a request in ClientCached():
m_get_clientcached_queue.add(name, 0, 0, &result_queue); inventory_texture(NULL),
try{ wield_mesh(NULL)
while (true) { {}
// Wait result for a second };
GetResult<std::string, ClientCached*, u8, u8> #endif
result = result_queue.pop_front(1000);
if (result.key == name) { public:
return result.item; CItemDefManager()
{
#ifndef SERVER
m_main_thread = thr_get_current_thread_id();
#endif
clear();
}
virtual ~CItemDefManager()
{
#ifndef SERVER
const std::vector<ClientCached*> &values = m_clientcached.getValues();
for(std::vector<ClientCached*>::const_iterator
i = values.begin(); i != values.end(); ++i)
{
ClientCached *cc = *i;
if (cc->wield_mesh)
cc->wield_mesh->drop();
delete cc;
}
#endif
for (std::map<std::string, ItemDefinition*>::iterator iter =
m_item_definitions.begin(); iter != m_item_definitions.end();
++iter) {
delete iter->second;
}
m_item_definitions.clear();
}
virtual const ItemDefinition& get(const std::string &name_) const
{
// Convert name according to possible alias
std::string name = getAlias(name_);
// Get the definition
std::map<std::string, ItemDefinition*>::const_iterator i;
i = m_item_definitions.find(name);
if(i == m_item_definitions.end())
i = m_item_definitions.find("unknown");
assert(i != m_item_definitions.end());
return *(i->second);
}
virtual std::string getAlias(const std::string &name) const
{
StringMap::const_iterator it = m_aliases.find(name);
if (it != m_aliases.end())
return it->second;
return name;
}
virtual std::set<std::string> getAll() const
{
std::set<std::string> result;
for(std::map<std::string, ItemDefinition *>::const_iterator
it = m_item_definitions.begin();
it != m_item_definitions.end(); ++it) {
result.insert(it->first);
}
for (StringMap::const_iterator
it = m_aliases.begin();
it != m_aliases.end(); ++it) {
result.insert(it->first);
}
return result;
}
virtual bool isKnown(const std::string &name_) const
{
// Convert name according to possible alias
std::string name = getAlias(name_);
// Get the definition
std::map<std::string, ItemDefinition*>::const_iterator i;
return m_item_definitions.find(name) != m_item_definitions.end();
}
#ifndef SERVER
public:
ClientCached* createClientCachedDirect(const std::string &name,
IGameDef *gamedef) const
{
infostream<<"Lazily creating item texture and mesh for \""
<<name<<"\""<<std::endl;
// This is not thread-safe
sanity_check(thr_is_current_thread(m_main_thread));
// Skip if already in cache
ClientCached *cc = NULL;
m_clientcached.get(name, &cc);
if(cc)
return cc;
ITextureSource *tsrc = gamedef->getTextureSource();
INodeDefManager *nodedef = gamedef->getNodeDefManager();
const ItemDefinition &def = get(name);
// Create new ClientCached
cc = new ClientCached();
// Create an inventory texture
cc->inventory_texture = NULL;
if(def.inventory_image != "")
cc->inventory_texture = tsrc->getTexture(def.inventory_image);
// Additional processing for nodes:
// - Create a wield mesh if WieldMeshSceneNode can't render
// the node on its own.
// - If inventory_texture isn't set yet, create one using
// render-to-texture.
if (def.type == ITEM_NODE) {
// Get node properties
content_t id = nodedef->getId(name);
const ContentFeatures &f = nodedef->get(id);
bool need_rtt_mesh = cc->inventory_texture == NULL;
// Keep this in sync with WieldMeshSceneNode::setItem()
bool need_wield_mesh =
!(f.mesh_ptr[0] ||
f.drawtype == NDT_NORMAL ||
f.drawtype == NDT_ALLFACES ||
f.drawtype == NDT_AIRLIKE);
scene::IMesh *node_mesh = NULL;
if (need_rtt_mesh || need_wield_mesh) {
u8 param1 = 0;
if (f.param_type == CPT_LIGHT)
param1 = 0xee;
/*
Make a mesh from the node
*/
MeshMakeData mesh_make_data(gamedef, false);
u8 param2 = 0;
if (f.param_type_2 == CPT2_WALLMOUNTED)
param2 = 1;
MapNode mesh_make_node(id, param1, param2);
mesh_make_data.fillSingleNode(&mesh_make_node);
MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0));
node_mesh = mapblock_mesh.getMesh();
node_mesh->grab();
video::SColor c(255, 255, 255, 255);
setMeshColor(node_mesh, c);
// scale and translate the mesh so it's a
// unit cube centered on the origin
scaleMesh(node_mesh, v3f(1.0/BS, 1.0/BS, 1.0/BS));
translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0));
}
/*
Draw node mesh into a render target texture
*/
if (need_rtt_mesh) {
TextureFromMeshParams params;
params.mesh = node_mesh;
params.dim.set(64, 64);
params.rtt_texture_name = "INVENTORY_"
+ def.name + "_RTT";
params.delete_texture_on_shutdown = true;
params.camera_position.set(0, 1.0, -1.5);
params.camera_position.rotateXZBy(45);
params.camera_lookat.set(0, 0, 0);
// Set orthogonal projection
params.camera_projection_matrix.buildProjectionMatrixOrthoLH(
1.65, 1.65, 0, 100);
params.ambient_light.set(1.0, 0.2, 0.2, 0.2);
params.light_position.set(10, 100, -50);
params.light_color.set(1.0, 0.5, 0.5, 0.5);
params.light_radius = 1000;
#ifdef __ANDROID__
params.camera_position.set(0, -1.0, -1.5);
params.camera_position.rotateXZBy(45);
params.light_position.set(10, -100, -50);
#endif
cc->inventory_texture =
tsrc->generateTextureFromMesh(params);
// render-to-target didn't work
if (cc->inventory_texture == NULL) {
cc->inventory_texture =
tsrc->getTexture(f.tiledef[0].name);
} }
} }
/*
Use the node mesh as the wield mesh
*/
if (need_wield_mesh) {
cc->wield_mesh = node_mesh;
cc->wield_mesh->grab();
// no way reference count can be smaller than 2 in this place!
assert(cc->wield_mesh->getReferenceCount() >= 2);
}
if (node_mesh)
node_mesh->drop();
} }
catch(ItemNotFoundException &e)
// Put in cache
m_clientcached.set(name, cc);
return cc;
}
ClientCached* getClientCached(const std::string &name,
IGameDef *gamedef) const
{
ClientCached *cc = NULL;
m_clientcached.get(name, &cc);
if(cc)
return cc;
if(thr_is_current_thread(m_main_thread))
{ {
errorstream<<"Waiting for clientcached " << name << " timed out."<<std::endl; return createClientCachedDirect(name, gamedef);
return &m_dummy_clientcached; }
else
{
// We're gonna ask the result to be put into here
static ResultQueue<std::string, ClientCached*, u8, u8> result_queue;
// Throw a request in
m_get_clientcached_queue.add(name, 0, 0, &result_queue);
try{
while(true) {
// Wait result for a second
GetResult<std::string, ClientCached*, u8, u8>
result = result_queue.pop_front(1000);
if (result.key == name) {
return result.item;
}
}
}
catch(ItemNotFoundException &e)
{
errorstream<<"Waiting for clientcached " << name << " timed out."<<std::endl;
return &m_dummy_clientcached;
}
} }
} }
} // Get item inventory texture
virtual video::ITexture* getInventoryTexture(const std::string &name,
/******************************************************************************/ IGameDef *gamedef) const
// Get item inventory texture {
video::ITexture* CItemDefManager::getInventoryTexture(const std::string &name, ClientCached *cc = getClientCached(name, gamedef);
IGameDef *gamedef) const if(!cc)
{ return NULL;
ClientCached *cc = getClientCached(name, gamedef); return cc->inventory_texture;
if (!cc)
return NULL;
return cc->inventory_texture;
}
/******************************************************************************/
// Get item wield mesh
scene::IMesh* CItemDefManager::getWieldMesh(const std::string &name,
IGameDef *gamedef) const
{
ClientCached *cc = getClientCached(name, gamedef);
if (!cc)
return NULL;
return cc->wield_mesh;
}
#endif
/******************************************************************************/
void CItemDefManager::clear()
{
for (std::map<std::string, ItemDefinition*>::const_iterator
i = m_item_definitions.begin();
i != m_item_definitions.end(); ++i) {
delete i->second;
} }
m_item_definitions.clear(); // Get item wield mesh
m_aliases.clear(); virtual scene::IMesh* getWieldMesh(const std::string &name,
IGameDef *gamedef) const
// Add the four builtin items: {
// "" is the hand ClientCached *cc = getClientCached(name, gamedef);
// "unknown" is returned whenever an undefined item if(!cc)
// is accessed (is also the unknown node) return NULL;
// "air" is the air node return cc->wield_mesh;
// "ignore" is the ignore node
ItemDefinition* hand_def = new ItemDefinition;
hand_def->name = "";
hand_def->wield_image = "wieldhand.png";
hand_def->tool_capabilities = new ToolCapabilities;
m_item_definitions.insert(std::make_pair("", hand_def));
ItemDefinition* unknown_def = new ItemDefinition;
unknown_def->type = ITEM_NODE;
unknown_def->name = "unknown";
m_item_definitions.insert(std::make_pair("unknown", unknown_def));
ItemDefinition* air_def = new ItemDefinition;
air_def->type = ITEM_NODE;
air_def->name = "air";
m_item_definitions.insert(std::make_pair("air", air_def));
ItemDefinition* ignore_def = new ItemDefinition;
ignore_def->type = ITEM_NODE;
ignore_def->name = "ignore";
m_item_definitions.insert(std::make_pair("ignore", ignore_def));
}
/******************************************************************************/
void CItemDefManager::registerItem(const ItemDefinition &def)
{
verbosestream<<"ItemDefManager: registering \""<<def.name<<"\""<<std::endl;
// Ensure that the "" item (the hand) always has ToolCapabilities
if (def.name == "")
FATAL_ERROR_IF(!def.tool_capabilities, "Hand does not have ToolCapabilities");
if (m_item_definitions.count(def.name) == 0)
m_item_definitions[def.name] = new ItemDefinition(def);
else
*(m_item_definitions[def.name]) = def;
// Remove conflicting alias if it exists
bool alias_removed = (m_aliases.erase(def.name) != 0);
if (alias_removed)
infostream<<"ItemDefManager: erased alias "<<def.name
<<" because item was defined"<<std::endl;
}
/******************************************************************************/
void CItemDefManager::registerAlias(const std::string &name,
const std::string &convert_to)
{
if (m_item_definitions.find(name) == m_item_definitions.end()) {
verbosestream<<"ItemDefManager: setting alias "<<name
<<" -> "<<convert_to<<std::endl;
m_aliases[name] = convert_to;
}
}
/******************************************************************************/
void CItemDefManager::serialize(std::ostream &os, u16 protocol_version)
{
writeU8(os, 0); // version
u16 count = m_item_definitions.size();
writeU16(os, count);
for (std::map<std::string, ItemDefinition *>::const_iterator
it = m_item_definitions.begin();
it != m_item_definitions.end(); ++it) {
ItemDefinition *def = it->second;
// Serialize ItemDefinition and write wrapped in a string
std::ostringstream tmp_os(std::ios::binary);
def->serialize(tmp_os, protocol_version);
os << serializeString(tmp_os.str());
}
writeU16(os, m_aliases.size());
for (StringMap::const_iterator
it = m_aliases.begin();
it != m_aliases.end(); ++it) {
os << serializeString(it->first);
os << serializeString(it->second);
}
}
/******************************************************************************/
void CItemDefManager::deSerialize(std::istream &is)
{
// Clear everything
clear();
// Deserialize
int version = readU8(is);
if(version != 0)
throw SerializationError("unsupported ItemDefManager version");
u16 count = readU16(is);
for (u16 i=0; i<count; i++) {
// Deserialize a string and grab an ItemDefinition from it
std::istringstream tmp_is(deSerializeString(is), std::ios::binary);
ItemDefinition def;
def.deSerialize(tmp_is);
// Register
registerItem(def);
}
u16 num_aliases = readU16(is);
for (u16 i=0; i<num_aliases; i++) {
std::string name = deSerializeString(is);
std::string convert_to = deSerializeString(is);
registerAlias(name, convert_to);
}
}
/******************************************************************************/
void CItemDefManager::processQueue(IGameDef *gamedef)
{
#ifndef SERVER
//NOTE this is only thread safe for ONE consumer thread!
while (!m_get_clientcached_queue.empty()) {
GetRequest<std::string, ClientCached*, u8, u8>
request = m_get_clientcached_queue.pop();
m_get_clientcached_queue.pushResult(request,
createClientCachedDirect(request.key, gamedef));
} }
#endif #endif
} void clear()
{
for(std::map<std::string, ItemDefinition*>::const_iterator
i = m_item_definitions.begin();
i != m_item_definitions.end(); ++i)
{
delete i->second;
}
m_item_definitions.clear();
m_aliases.clear();
#ifndef SERVER // Add the four builtin items:
/******************************************************************************/ // "" is the hand
void CItemDefManager::createNodeItemTexture(const std::string& name, // "unknown" is returned whenever an undefined item
const ItemDefinition& def, INodeDefManager* nodedef, // is accessed (is also the unknown node)
ClientCached* cc, IGameDef* gamedef, ITextureSource* tsrc) const // "air" is the air node
{ // "ignore" is the ignore node
// Get node properties
content_t id = nodedef->getId(name);
const ContentFeatures& f = nodedef->get(id);
bool need_rtt_mesh = cc->inventory_texture == NULL;
// Keep this in sync with WieldMeshSceneNode::setItem()
bool need_wield_mesh = !(f.mesh_ptr[0] || f.drawtype == NDT_NORMAL
|| f.drawtype == NDT_ALLFACES || f.drawtype == NDT_AIRLIKE);
scene::IMesh* node_mesh = NULL;
if (need_rtt_mesh || need_wield_mesh) { ItemDefinition* hand_def = new ItemDefinition;
hand_def->name = "";
hand_def->wield_image = "wieldhand.png";
hand_def->tool_capabilities = new ToolCapabilities;
m_item_definitions.insert(std::make_pair("", hand_def));
u8 param1 = 0; ItemDefinition* unknown_def = new ItemDefinition;
if (f.param_type == CPT_LIGHT) unknown_def->type = ITEM_NODE;
param1 = 0xee; unknown_def->name = "unknown";
m_item_definitions.insert(std::make_pair("unknown", unknown_def));
/* ItemDefinition* air_def = new ItemDefinition;
Make a mesh from the node air_def->type = ITEM_NODE;
*/ air_def->name = "air";
MeshMakeData mesh_make_data(gamedef, false); m_item_definitions.insert(std::make_pair("air", air_def));
u8 param2 = 0;
if (f.param_type_2 == CPT2_WALLMOUNTED)
param2 = 1;
MapNode mesh_make_node(id, param1, param2); ItemDefinition* ignore_def = new ItemDefinition;
mesh_make_data.fillSingleNode(&mesh_make_node); ignore_def->type = ITEM_NODE;
MapBlockMesh mapblock_mesh(&mesh_make_data, v3s16(0, 0, 0)); ignore_def->name = "ignore";
node_mesh = mapblock_mesh.getMesh(); m_item_definitions.insert(std::make_pair("ignore", ignore_def));
node_mesh->grab();
video::SColor c(255, 255, 255, 255);
setMeshColor(node_mesh, c);
// scale and translate the mesh so it's a
// unit cube centered on the origin
scaleMesh(node_mesh, v3f(1.0 / BS, 1.0 / BS, 1.0 / BS));
translateMesh(node_mesh, v3f(-1.0, -1.0, -1.0));
} }
/* virtual void registerItem(const ItemDefinition &def)
Draw node mesh into a render target texture {
*/ verbosestream<<"ItemDefManager: registering \""<<def.name<<"\""<<std::endl;
if (need_rtt_mesh) { // Ensure that the "" item (the hand) always has ToolCapabilities
if(def.name == "")
FATAL_ERROR_IF(!def.tool_capabilities, "Hand does not have ToolCapabilities");
TextureFromMeshParams params; if(m_item_definitions.count(def.name) == 0)
params.mesh = node_mesh; m_item_definitions[def.name] = new ItemDefinition(def);
params.dim.set(64, 64); else
params.rtt_texture_name = "INVENTORY_" + def.name + "_RTT"; *(m_item_definitions[def.name]) = def;
params.delete_texture_on_shutdown = true;
params.camera_position.set(0, 1.0, -1.5);
params.camera_position.rotateXZBy(45);
params.camera_lookat.set(0, 0, 0);
// Set orthogonal projection
params.camera_projection_matrix.buildProjectionMatrixOrthoLH(1.65,
1.65, 0, 100);
params.ambient_light.set(1.0, 0.2, 0.2, 0.2);
params.light_position.set(10, 100, -50);
params.light_color.set(1.0, 0.5, 0.5, 0.5);
params.light_radius = 1000;
cc->inventory_texture = tsrc->generateTextureFromMesh(params);
// render-to-target didn't work
if (cc->inventory_texture == NULL) {
cc->inventory_texture = tsrc->getTexture(f.tiledef[0].name); // Remove conflicting alias if it exists
bool alias_removed = (m_aliases.erase(def.name) != 0);
if(alias_removed)
infostream<<"ItemDefManager: erased alias "<<def.name
<<" because item was defined"<<std::endl;
}
virtual void registerAlias(const std::string &name,
const std::string &convert_to)
{
if(m_item_definitions.find(name) == m_item_definitions.end())
{
verbosestream<<"ItemDefManager: setting alias "<<name
<<" -> "<<convert_to<<std::endl;
m_aliases[name] = convert_to;
} }
} }
/* void serialize(std::ostream &os, u16 protocol_version)
Use the node mesh as the wield mesh {
*/ writeU8(os, 0); // version
if (need_wield_mesh) { u16 count = m_item_definitions.size();
writeU16(os, count);
cc->wield_mesh = node_mesh; for (std::map<std::string, ItemDefinition *>::const_iterator
cc->wield_mesh->grab(); it = m_item_definitions.begin();
// no way reference count can be smaller than 2 in this place! it != m_item_definitions.end(); ++it) {
assert(cc->wield_mesh->getReferenceCount() >= 2); ItemDefinition *def = it->second;
// Serialize ItemDefinition and write wrapped in a string
std::ostringstream tmp_os(std::ios::binary);
def->serialize(tmp_os, protocol_version);
os << serializeString(tmp_os.str());
}
writeU16(os, m_aliases.size());
for (StringMap::const_iterator
it = m_aliases.begin();
it != m_aliases.end(); ++it) {
os << serializeString(it->first);
os << serializeString(it->second);
}
} }
if (node_mesh) void deSerialize(std::istream &is)
node_mesh->drop(); {
} // Clear everything
#endif clear();
// Deserialize
int version = readU8(is);
if(version != 0)
throw SerializationError("unsupported ItemDefManager version");
u16 count = readU16(is);
for(u16 i=0; i<count; i++)
{
// Deserialize a string and grab an ItemDefinition from it
std::istringstream tmp_is(deSerializeString(is), std::ios::binary);
ItemDefinition def;
def.deSerialize(tmp_is);
// Register
registerItem(def);
}
u16 num_aliases = readU16(is);
for(u16 i=0; i<num_aliases; i++)
{
std::string name = deSerializeString(is);
std::string convert_to = deSerializeString(is);
registerAlias(name, convert_to);
}
}
void processQueue(IGameDef *gamedef)
{
#ifndef SERVER
//NOTE this is only thread safe for ONE consumer thread!
while(!m_get_clientcached_queue.empty())
{
GetRequest<std::string, ClientCached*, u8, u8>
request = m_get_clientcached_queue.pop();
/******************************************************************************/ m_get_clientcached_queue.pushResult(request,
createClientCachedDirect(request.key, gamedef));
}
#endif
}
private:
// Key is name
std::map<std::string, ItemDefinition*> m_item_definitions;
// Aliases
StringMap m_aliases;
#ifndef SERVER
// The id of the thread that is allowed to use irrlicht directly
threadid_t m_main_thread;
// A reference to this can be returned when nothing is found, to avoid NULLs
mutable ClientCached m_dummy_clientcached;
// Cached textures and meshes
mutable MutexedMap<std::string, ClientCached*> m_clientcached;
// Queued clientcached fetches (to be processed by the main thread)
mutable RequestQueue<std::string, ClientCached*, u8, u8> m_get_clientcached_queue;
#endif
};
IWritableItemDefManager* createItemDefManager() IWritableItemDefManager* createItemDefManager()
{ {

View File

@ -25,18 +25,9 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <set> #include <set>
#include <map>
#include "itemgroup.h" #include "itemgroup.h"
#include "sound.h" #include "sound.h"
#include "util/container.h"
#include "util/thread.h"
#ifndef SERVER
#include "client/tile.h"
#endif
class IGameDef; class IGameDef;
class INodeDefManager;
struct ToolCapabilities; struct ToolCapabilities;
/* /*
@ -48,7 +39,7 @@ enum ItemType
ITEM_NONE, ITEM_NONE,
ITEM_NODE, ITEM_NODE,
ITEM_CRAFT, ITEM_CRAFT,
ITEM_TOOL ITEM_TOOL,
}; };
struct ItemDefinition struct ItemDefinition
@ -166,77 +157,6 @@ public:
virtual void processQueue(IGameDef *gamedef)=0; virtual void processQueue(IGameDef *gamedef)=0;
}; };
class CItemDefManager: public IWritableItemDefManager
{
public:
CItemDefManager();
virtual ~CItemDefManager();
virtual const ItemDefinition& get(const std::string &name_) const;
virtual std::string getAlias(const std::string &name) const;
virtual std::set<std::string> getAll() const;
virtual bool isKnown(const std::string &name_) const;
#ifndef SERVER
// Get item inventory texture
virtual video::ITexture* getInventoryTexture(const std::string &name,
IGameDef *gamedef) const;
// Get item wield mesh
virtual scene::IMesh* getWieldMesh(const std::string &name,
IGameDef *gamedef) const;
#endif
void clear();
virtual void registerItem(const ItemDefinition &def);
virtual void registerAlias(const std::string &name,
const std::string &convert_to);
void serialize(std::ostream &os, u16 protocol_version);
void deSerialize(std::istream &is);
void processQueue(IGameDef *gamedef);
private:
#ifndef SERVER
struct ClientCached
{
video::ITexture *inventory_texture;
scene::IMesh *wield_mesh;
ClientCached();
};
void createNodeItemTexture(const std::string& name,
const ItemDefinition& def, INodeDefManager* nodedef,
ClientCached* cc, IGameDef* gamedef, ITextureSource* tsrc) const;
ClientCached* createClientCachedDirect(const std::string &name,
IGameDef *gamedef) const;
ClientCached* getClientCached(const std::string &name,
IGameDef *gamedef) const;
// The id of the thread that is allowed to use irrlicht directly
threadid_t m_main_thread;
// A reference to this can be returned when nothing is found, to avoid NULLs
mutable ClientCached m_dummy_clientcached;
// Cached textures and meshes
mutable MutexedMap<std::string, ClientCached*> m_clientcached;
// Queued clientcached fetches (to be processed by the main thread)
mutable RequestQueue<std::string, ClientCached*, u8, u8> m_get_clientcached_queue;
#endif
// Key is name
std::map<std::string, ItemDefinition*> m_item_definitions;
// Aliases
std::map<std::string, std::string> m_aliases;
};
IWritableItemDefManager* createItemDefManager(); IWritableItemDefManager* createItemDefManager();
#endif #endif