diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/constants.h | 4 | ||||
-rw-r--r-- | src/debug.h | 24 | ||||
-rw-r--r-- | src/defaultsettings.cpp | 4 | ||||
-rw-r--r-- | src/exceptions.h | 8 | ||||
-rw-r--r-- | src/inventory.cpp | 6 | ||||
-rw-r--r-- | src/inventory.h | 2 | ||||
-rw-r--r-- | src/main.cpp | 97 | ||||
-rw-r--r-- | src/main.h | 8 | ||||
-rw-r--r-- | src/map.cpp | 16 | ||||
-rw-r--r-- | src/mapblock.cpp | 17 | ||||
-rw-r--r-- | src/mapnode.cpp | 22 | ||||
-rw-r--r-- | src/porting.h | 2 | ||||
-rw-r--r-- | src/tile.cpp | 43 | ||||
-rw-r--r-- | src/tile.h | 12 | ||||
-rw-r--r-- | src/utility.cpp | 43 | ||||
-rw-r--r-- | src/utility.h | 301 | ||||
-rw-r--r-- | src/voxel.cpp | 22 |
17 files changed, 405 insertions, 226 deletions
diff --git a/src/constants.h b/src/constants.h index 3c9b50eff..c3fca432f 100644 --- a/src/constants.h +++ b/src/constants.h @@ -62,8 +62,8 @@ with this program; if not, write to the Free Software Foundation, Inc., // Viewing range stuff -//#define FREETIME_RATIO 0.2 -#define FREETIME_RATIO 0.15 +//#define FREETIME_RATIO 0.15 +#define FREETIME_RATIO 0.0 // Sectors are split to SECTOR_HEIGHTMAP_SPLIT^2 heightmaps #define SECTOR_HEIGHTMAP_SPLIT 2 diff --git a/src/debug.h b/src/debug.h index 9a2e282f5..44fcf4b51 100644 --- a/src/debug.h +++ b/src/debug.h @@ -30,29 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <jmutexautolock.h> #include <iostream> #include "common_irrlicht.h" - -/* - Compatibility stuff -*/ - -#if (defined(WIN32) || defined(_WIN32_WCE)) -typedef DWORD threadid_t; -#define __NORETURN __declspec(noreturn) -#define __FUNCTION_NAME __FUNCTION__ -#else -typedef pthread_t threadid_t; -#define __NORETURN __attribute__ ((__noreturn__)) -#define __FUNCTION_NAME __PRETTY_FUNCTION__ -#endif - -inline threadid_t get_current_thread_id() -{ -#if (defined(WIN32) || defined(_WIN32_WCE)) - return GetCurrentThreadId(); -#else - return pthread_self(); -#endif -} +#include "threads.h" /* Debug output diff --git a/src/defaultsettings.cpp b/src/defaultsettings.cpp index a9b8dc279..04cdf16bc 100644 --- a/src/defaultsettings.cpp +++ b/src/defaultsettings.cpp @@ -28,8 +28,8 @@ void set_default_settings() g_settings.setDefault("fps_max", "60"); g_settings.setDefault("viewing_range_nodes_max", "300"); g_settings.setDefault("viewing_range_nodes_min", "35"); - g_settings.setDefault("screenW", ""); - g_settings.setDefault("screenH", ""); + g_settings.setDefault("screenW", "800"); + g_settings.setDefault("screenH", "600"); g_settings.setDefault("host_game", ""); g_settings.setDefault("port", ""); g_settings.setDefault("address", ""); diff --git a/src/exceptions.h b/src/exceptions.h index 95b9eea97..40a0db4aa 100644 --- a/src/exceptions.h +++ b/src/exceptions.h @@ -132,6 +132,14 @@ public: {} }; +class ItemNotFoundException : public BaseException +{ +public: + ItemNotFoundException(const char *s): + BaseException(s) + {} +}; + /* Some "old-style" interrupts: */ diff --git a/src/inventory.cpp b/src/inventory.cpp index ba8cf4580..079be8793 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -80,10 +80,12 @@ InventoryItem* InventoryItem::deSerialize(std::istream &is) video::ITexture * MapBlockObjectItem::getImage() { if(m_inventorystring.substr(0,3) == "Rat") - return g_device->getVideoDriver()->getTexture("../data/rat.png"); + //return g_device->getVideoDriver()->getTexture("../data/rat.png"); + return g_irrlicht->getTexture("../data/rat.png"); if(m_inventorystring.substr(0,4) == "Sign") - return g_device->getVideoDriver()->getTexture("../data/sign.png"); + //return g_device->getVideoDriver()->getTexture("../data/sign.png"); + return g_irrlicht->getTexture("../data/sign.png"); return NULL; } diff --git a/src/inventory.h b/src/inventory.h index cb5b54851..59ff89ed8 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -96,7 +96,7 @@ public: if(m_content >= USEFUL_CONTENT_COUNT) return NULL; - return g_texturecache.get(g_content_inventory_textures[m_content]); + return g_irrlicht->getTexture(g_content_inventory_textures[m_content]); } #endif std::string getText() diff --git a/src/main.cpp b/src/main.cpp index 3dc111201..56e725722 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -183,6 +183,9 @@ TODO: Node cracking animation when digging - TODO: A way to generate new textures by combining textures
- TODO: Mesh update to fetch cracked faces from the former
+TODO: A thread-safe wrapper for irrlicht for threads, to get rid of
+ g_device
+
======================================================================
*/
@@ -247,28 +250,7 @@ TODO: Node cracking animation when digging #include "porting.h"
#include "guiPauseMenu.h"
-IrrlichtDevice *g_device = NULL;
-
-/*const char *g_content_filenames[MATERIALS_COUNT] =
-{
- "../data/stone.png",
- "../data/grass.png",
- "../data/water.png",
- "../data/torch_on_floor.png",
- "../data/tree.png",
- "../data/leaves.png",
- "../data/grass_footsteps.png",
- "../data/mese.png",
- "../data/mud.png",
- "../data/water.png", // CONTENT_OCEAN
-};
-
-// Material cache
-video::SMaterial g_materials[MATERIALS_COUNT];*/
-
-// Texture cache
-TextureCache g_texturecache;
-
+IrrlichtWrapper *g_irrlicht;
// All range-related stuff below is locked behind this
JMutex g_range_mutex;
@@ -852,9 +834,10 @@ void updateViewingRange(f32 frametime, Client *client) static bool fraction_is_good = false;
- float fraction_good_threshold = 0.1;
+ //float fraction_good_threshold = 0.1;
//float fraction_bad_threshold = 0.25;
- float fraction_bad_threshold = 0.1;
+ float fraction_good_threshold = 0.075;
+ float fraction_bad_threshold = 0.125;
float fraction_limit;
// Use high limit if fraction is good AND the fraction would
// lower the range. We want to keep the range fairly high.
@@ -1283,7 +1266,12 @@ int main(int argc, char *argv[]) /*
Resolution selection
*/
+
+ bool fullscreen = false;
+ u16 screenW = atoi(g_settings.get("screenW").c_str());
+ u16 screenH = atoi(g_settings.get("screenH").c_str());
+#if 0
u16 screenW;
u16 screenH;
bool fullscreen = false;
@@ -1345,6 +1333,7 @@ int main(int argc, char *argv[]) screenH = resolutions[r0-1][1];
fullscreen = resolutions[r0-1][2];
}
+#endif
//
@@ -1372,8 +1361,10 @@ int main(int argc, char *argv[]) if (device == 0)
return 1; // could not create selected driver.
+
+ g_irrlicht = new IrrlichtWrapper(device);
- g_device = device;
+ //g_device = device;
device->setResizable(true);
@@ -1432,10 +1423,11 @@ int main(int argc, char *argv[]) /*
Preload some random textures that are used in threads
*/
-
+#if 0
g_texturecache.set("torch", driver->getTexture("../data/torch.png"));
g_texturecache.set("torch_on_floor", driver->getTexture("../data/torch_on_floor.png"));
g_texturecache.set("torch_on_ceiling", driver->getTexture("../data/torch_on_ceiling.png"));
+ g_texturecache.set("crack", driver->getTexture("../data/crack.png"));
/*
Load tile textures
@@ -1452,7 +1444,11 @@ int main(int argc, char *argv[]) g_texturecache.set(name, driver->getTexture(filename.c_str()));
}
- tile_materials_preload(g_texturecache);
+#endif
+
+ //tile_materials_preload(g_texturecache);
+ tile_materials_preload(g_irrlicht);
+ //tile_materials_init();
/*
Make a scope here for the client so that it gets removed
@@ -1642,6 +1638,11 @@ int main(int argc, char *argv[]) while(device->run())
{
/*
+ Run global IrrlichtWrapper's main thread processing stuff
+ */
+ g_irrlicht->Run();
+
+ /*
Random calculations
*/
v2u32 screensize = driver->getScreenSize();
@@ -1653,7 +1654,7 @@ int main(int argc, char *argv[]) // Info text
std::wstring infotext;
- //TimeTaker //timer1("//timer1", device);
+ //TimeTaker //timer1("//timer1", g_irrlicht);
// Time of frame without fps limit
float busytime;
@@ -1843,20 +1844,20 @@ int main(int argc, char *argv[]) */
{
- //TimeTaker timer("client.step(dtime)", device);
+ //TimeTaker timer("client.step(dtime)", g_irrlicht);
client.step(dtime);
//client.step(dtime_avg1);
}
if(server != NULL)
{
- //TimeTaker timer("server->step(dtime)", device);
+ //TimeTaker timer("server->step(dtime)", g_irrlicht);
server->step(dtime);
}
v3f player_position = client.getPlayerPosition();
- //TimeTaker //timer2("//timer2", device);
+ //TimeTaker //timer2("//timer2", g_irrlicht);
/*
Mouse and camera control
@@ -1910,12 +1911,12 @@ int main(int argc, char *argv[]) }
else{
//client.m_env.getMap().updateCamera(camera_position, camera_direction);
- //TimeTaker timer("client.updateCamera", device);
+ //TimeTaker timer("client.updateCamera", g_irrlicht);
client.updateCamera(camera_position, camera_direction);
}
//timer2.stop();
- //TimeTaker //timer3("//timer3", device);
+ //TimeTaker //timer3("//timer3", g_irrlicht);
/*
Calculate what block is the crosshair pointing to
@@ -2266,7 +2267,7 @@ int main(int argc, char *argv[]) Update gui stuff (0ms)
*/
- //TimeTaker guiupdatetimer("Gui updating", device);
+ //TimeTaker guiupdatetimer("Gui updating", g_irrlicht);
{
wchar_t temptext[150];
@@ -2376,14 +2377,14 @@ int main(int argc, char *argv[]) Drawing begins
*/
- TimeTaker drawtimer("Drawing", device);
+ TimeTaker drawtimer("Drawing", g_irrlicht);
{
- TimeTaker timer("beginScene", device);
- driver->beginScene(true, true, bgcolor);
- //driver->beginScene(false, true, bgcolor);
- beginscenetime = timer.stop(true);
+ TimeTaker timer("beginScene", g_irrlicht);
+ driver->beginScene(true, true, bgcolor);
+ //driver->beginScene(false, true, bgcolor);
+ beginscenetime = timer.stop(true);
}
//timer3.stop();
@@ -2391,13 +2392,13 @@ int main(int argc, char *argv[]) //std::cout<<DTIME<<"smgr->drawAll()"<<std::endl;
{
- TimeTaker timer("smgr", device);
- smgr->drawAll();
- scenetime = timer.stop(true);
+ TimeTaker timer("smgr", g_irrlicht);
+ smgr->drawAll();
+ scenetime = timer.stop(true);
}
{
- //TimeTaker timer9("auxiliary drawings", device);
+ //TimeTaker timer9("auxiliary drawings", g_irrlicht);
// 0ms
driver->draw2DLine(displaycenter - core::vector2d<s32>(10,0),
@@ -2408,7 +2409,7 @@ int main(int argc, char *argv[]) video::SColor(255,255,255,255));
//timer9.stop();
- //TimeTaker //timer10("//timer10", device);
+ //TimeTaker //timer10("//timer10", g_irrlicht);
video::SMaterial m;
m.Thickness = 10;
@@ -2431,7 +2432,7 @@ int main(int argc, char *argv[]) }
//timer10.stop();
- //TimeTaker //timer11("//timer11", device);
+ //TimeTaker //timer11("//timer11", g_irrlicht);
/*
Draw gui
@@ -2441,9 +2442,9 @@ int main(int argc, char *argv[]) // End drawing
{
- TimeTaker timer("endScene", device);
- driver->endScene();
- endscenetime = timer.stop(true);
+ TimeTaker timer("endScene", g_irrlicht);
+ driver->endScene();
+ endscenetime = timer.stop(true);
}
drawtime = drawtimer.stop(true);
diff --git a/src/main.h b/src/main.h index 98af41249..22b5157d7 100644 --- a/src/main.h +++ b/src/main.h @@ -46,12 +46,14 @@ extern std::ostream *derr_server_ptr; #define dout_server (*dout_server_ptr) #define derr_server (*derr_server_ptr) -#ifndef SERVER +/*#ifndef SERVER #include "utility.h" extern TextureCache g_texturecache; -#endif +#endif*/ -extern IrrlichtDevice *g_device; +#include "irrlichtwrapper.h" +//extern IrrlichtDevice *g_device; +extern IrrlichtWrapper *g_irrlicht; #endif diff --git a/src/map.cpp b/src/map.cpp index acaebe257..13db92651 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -740,7 +740,7 @@ void Map::updateLighting(enum LightBank bank, } { - //TimeTaker timer("unspreadLight", g_device); + //TimeTaker timer("unspreadLight", g_irrlicht); unspreadLight(bank, unlight_from, light_sources, modified_blocks); } @@ -759,7 +759,7 @@ void Map::updateLighting(enum LightBank bank, // - Find out why it works { - //TimeTaker timer("spreadLight", g_device); + //TimeTaker timer("spreadLight", g_irrlicht); spreadLight(bank, light_sources, modified_blocks); } @@ -1065,7 +1065,7 @@ void Map::removeNodeAndUpdate(v3s16 p, #ifndef SERVER void Map::expireMeshes(bool only_daynight_diffed) { - TimeTaker timer("expireMeshes()", g_device); + TimeTaker timer("expireMeshes()", g_irrlicht); core::map<v2s16, MapSector*>::Iterator si; si = m_sectors.getIterator(); @@ -3017,7 +3017,7 @@ MapVoxelManipulator::~MapVoxelManipulator() #if 1 void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id) { - TimeTaker timer1("emerge", g_device, &emerge_time); + TimeTaker timer1("emerge", g_irrlicht, &emerge_time); // Units of these are MapBlocks v3s16 p_min = getNodeBlockPos(a.MinEdge); @@ -3041,7 +3041,7 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id) bool block_data_inexistent = false; try { - TimeTaker timer1("emerge load", g_device, &emerge_load_time); + TimeTaker timer1("emerge load", g_irrlicht, &emerge_load_time); /*dstream<<"Loading block (caller_id="<<caller_id<<")" <<" ("<<p.X<<","<<p.Y<<","<<p.Z<<")" @@ -3082,7 +3082,7 @@ void MapVoxelManipulator::emerge(VoxelArea a, s32 caller_id) #if 0 void MapVoxelManipulator::emerge(VoxelArea a) { - TimeTaker timer1("emerge", g_device, &emerge_time); + TimeTaker timer1("emerge", g_irrlicht, &emerge_time); v3s16 size = a.getExtent(); @@ -3101,7 +3101,7 @@ void MapVoxelManipulator::emerge(VoxelArea a) continue; try { - TimeTaker timer1("emerge load", g_device, &emerge_load_time); + TimeTaker timer1("emerge load", g_irrlicht, &emerge_load_time); MapNode n = m_map->getNode(a.MinEdge + p); m_data[i] = n; m_flags[i] = 0; @@ -3126,7 +3126,7 @@ void MapVoxelManipulator::blitBack if(m_area.getExtent() == v3s16(0,0,0)) return; - //TimeTaker timer1("blitBack", g_device); + //TimeTaker timer1("blitBack", g_irrlicht); /* Initialize block cache diff --git a/src/mapblock.cpp b/src/mapblock.cpp index 9372c8fb1..af08cadaa 100644 --- a/src/mapblock.cpp +++ b/src/mapblock.cpp @@ -646,7 +646,9 @@ void MapBlock::updateMesh(u32 daynight_ratio) if(f.tile.feature == TILEFEAT_NONE) { - collector.append(g_tile_materials[f.tile.id], f.vertices, 4, + /*collector.append(g_tile_materials[f.tile.id], f.vertices, 4, + indices, 6);*/ + collector.append(tile_material_get(f.tile.id), f.vertices, 4, indices, 6); } else @@ -748,16 +750,21 @@ void MapBlock::updateMesh(u32 daynight_ratio) = video::EMT_TRANSPARENT_ALPHA_CHANNEL_REF; if(dir == v3s16(0,-1,0)) buf->getMaterial().setTexture(0, - g_texturecache.get("torch_on_floor")); + g_irrlicht->getTexture("../data/torch_on_floor.png")); + //g_texturecache.get("torch_on_floor")); else if(dir == v3s16(0,1,0)) buf->getMaterial().setTexture(0, - g_texturecache.get("torch_on_ceiling")); + g_irrlicht->getTexture("../data/torch_on_ceiling.png")); + //g_texturecache.get("torch_on_ceiling")); // For backwards compatibility else if(dir == v3s16(0,0,0)) buf->getMaterial().setTexture(0, - g_texturecache.get("torch_on_floor")); + g_irrlicht->getTexture("../data/torch_on_floor.png")); + //g_texturecache.get("torch_on_floor")); else - buf->getMaterial().setTexture(0, g_texturecache.get("torch")); + buf->getMaterial().setTexture(0, + g_irrlicht->getTexture("../data/torch.png")); + //buf->getMaterial().setTexture(0, g_texturecache.get("torch")); // Add to mesh mesh_new->addMeshBuffer(buf); diff --git a/src/mapnode.cpp b/src/mapnode.cpp index 883c18842..c41560ee5 100644 --- a/src/mapnode.cpp +++ b/src/mapnode.cpp @@ -46,16 +46,16 @@ u16 g_content_tiles[USEFUL_CONTENT_COUNT][6] = const char * g_content_inventory_textures[USEFUL_CONTENT_COUNT] = { - "stone", - "grass", - "water", - "torch_on_floor", - "tree_top", - "leaves", - "grass_footsteps", - "mese", - "mud", - "water", - "cloud", + "../data/stone.png", + "../data/grass.png", + "../data/water.png", + "../data/torch_on_floor.png", + "../data/tree_top.png", + "../data/leaves.png", + "../data/grass_footsteps.png", + "../data/mese.png", + "../data/mud.png", + "../data/water.png", + "../data/cloud.png", }; diff --git a/src/porting.h b/src/porting.h index 9f139d825..5938b91d4 100644 --- a/src/porting.h +++ b/src/porting.h @@ -18,7 +18,7 @@ with this program; if not, write to the Free Software Foundation, Inc., */ /* -(c) 2010 Perttu Ahola <celeron55@gmail.com> + Random portability stuff */ #ifndef PORTING_HEADER diff --git a/src/tile.cpp b/src/tile.cpp index 5161b2284..174c72fdf 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -18,36 +18,40 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "tile.h" +#include "irrlichtwrapper.h" -const char * g_tile_texture_names[TILES_COUNT] = +// A mapping from tiles to paths of textures +const char * g_tile_texture_paths[TILES_COUNT] = { NULL, - "stone", - "water", - "grass", - "tree", - "leaves", - "grass_footsteps", - "mese", - "mud", - "tree_top", - "mud_with_grass", - "cloud", + "../data/stone.png", + "../data/water.png", + "../data/grass.png", + "../data/tree.png", + "../data/leaves.png", + "../data/grass_footsteps.png", + "../data/mese.png", + "../data/mud.png", + "../data/tree_top.png", + "../data/mud_with_grass.png", + "../data/cloud.png", }; +// A mapping from tiles to materials +// Initialized at run-time. video::SMaterial g_tile_materials[TILES_COUNT]; -void tile_materials_preload(TextureCache &cache) +void tile_materials_preload(IrrlichtWrapper *irrlicht) { for(s32 i=0; i<TILES_COUNT; i++) { - const char *name = g_tile_texture_names[i]; + const char *path = g_tile_texture_paths[i]; video::ITexture *t = NULL; - if(name != NULL) + if(path != NULL) { - t = cache.get(name); + t = irrlicht->getTexture(path); assert(t != NULL); } @@ -68,3 +72,10 @@ void tile_materials_preload(TextureCache &cache) //g_tile_materials[TILE_WATER].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR; } +video::SMaterial & tile_material_get(u32 i) +{ + assert(i < TILES_COUNT); + + return g_tile_materials[i]; +} + diff --git a/src/tile.h b/src/tile.h index f1aa100fc..d97567661 100644 --- a/src/tile.h +++ b/src/tile.h @@ -93,18 +93,16 @@ struct TileSpec } param; }; -// A mapping from tiles to names of cached textures -extern const char * g_tile_texture_names[TILES_COUNT]; - -// A mapping from tiles to materials -// Initialized at run-time. -extern video::SMaterial g_tile_materials[TILES_COUNT]; +/*extern const char * g_tile_texture_paths[TILES_COUNT]; +extern video::SMaterial g_tile_materials[TILES_COUNT];*/ /* Functions */ // Initializes g_tile_materials -void tile_materials_preload(TextureCache &cache); +void tile_materials_preload(IrrlichtWrapper *irrlicht); + +video::SMaterial & tile_material_get(u32 i); #endif diff --git a/src/utility.cpp b/src/utility.cpp index 5f3833e16..3da2f48d5 100644 --- a/src/utility.cpp +++ b/src/utility.cpp @@ -22,6 +22,49 @@ with this program; if not, write to the Free Software Foundation, Inc., */ #include "utility.h" +#include "irrlichtwrapper.h" + +TimeTaker::TimeTaker(const char *name, IrrlichtWrapper *irrlicht, u32 *result) +{ + m_name = name; + m_irrlicht = irrlicht; + m_result = result; + m_running = true; + if(irrlicht == NULL) + { + m_time1 = 0; + return; + } + m_time1 = m_irrlicht->getTime(); +} + +u32 TimeTaker::stop(bool quiet) +{ + if(m_running) + { + if(m_irrlicht == NULL) + { + /*if(quiet == false) + std::cout<<"Couldn't measure time for "<<m_name + <<": irrlicht==NULL"<<std::endl;*/ + return 0; + } + u32 time2 = m_irrlicht->getTime(); + u32 dtime = time2 - m_time1; + if(m_result != NULL) + { + (*m_result) += dtime; + } + else + { + if(quiet == false) + std::cout<<m_name<<" took "<<dtime<<"ms"<<std::endl; + } + m_running = false; + return dtime; + } + return 0; +} const v3s16 g_26dirs[26] = { diff --git a/src/utility.h b/src/utility.h index e4494948c..cde555760 100644 --- a/src/utility.h +++ b/src/utility.h @@ -17,10 +17,6 @@ with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -/* -(c) 2010 Perttu Ahola <celeron55@gmail.com> -*/ - #ifndef UTILITY_HEADER #define UTILITY_HEADER @@ -403,56 +399,23 @@ private: TimeTaker */ +class IrrlichtWrapper; + class TimeTaker { public: - TimeTaker(const char *name, IrrlichtDevice *dev, u32 *result=NULL) - { - m_name = name; - m_dev = dev; - m_result = result; - m_running = true; - if(dev == NULL) - { - m_time1 = 0; - return; - } - m_time1 = m_dev->getTimer()->getRealTime(); - } + TimeTaker(const char *name, IrrlichtWrapper *irrlicht, u32 *result=NULL); + ~TimeTaker() { stop(); } - u32 stop(bool quiet=false) - { - if(m_running) - { - if(m_dev == NULL) - { - /*if(quiet == false) - std::cout<<"Couldn't measure time for "<<m_name - <<": dev==NULL"<<std::endl;*/ - return 0; - } - u32 time2 = m_dev->getTimer()->getRealTime(); - u32 dtime = time2 - m_time1; - if(m_result != NULL) - { - (*m_result) += dtime; - } - else - { - if(quiet == false) - std::cout<<m_name<<" took "<<dtime<<"ms"<<std::endl; - } - m_running = false; - return dtime; - } - return 0; - } + + u32 stop(bool quiet=false); + private: const char *m_name; - IrrlichtDevice *m_dev; + IrrlichtWrapper *m_irrlicht; u32 m_time1; bool m_running; u32 *m_result; @@ -674,6 +637,48 @@ inline s32 stoi(std::string s) } /* + A base class for simple background thread implementation +*/ + +class SimpleThread : public JThread +{ + bool run; + JMutex run_mutex; + +public: + + SimpleThread(): + JThread(), + run(true) + { + run_mutex.Init(); + } + + virtual ~SimpleThread() + {} + + virtual void * Thread() = 0; + + bool getRun() + { + JMutexAutoLock lock(run_mutex); + return run; + } + void setRun(bool a_run) + { + JMutexAutoLock lock(run_mutex); + run = a_run; + } + + void stop() + { + setRun(false); + while(IsRunning()) + sleep_ms(100); + } +}; + +/* Config stuff */ @@ -1070,81 +1075,205 @@ private: }; /* - A thread-safe texture cache. - - This is used so that irrlicht doesn't get called from many threads + A thread-safe queue */ -class TextureCache +template<typename T> +class MutexedQueue { public: - TextureCache() + MutexedQueue() { m_mutex.Init(); - assert(m_mutex.IsInitialized()); + m_is_empty_mutex.Init(); } - - void set(std::string name, video::ITexture *texture) + u32 size() { - JMutexAutoLock lock(m_mutex); - - m_textures[name] = texture; + return m_list.size(); } - - video::ITexture* get(std::string name) + void push_back(T t) { JMutexAutoLock lock(m_mutex); + m_list.push_back(t); + + if(m_list.size() == 1) + m_is_empty_mutex.Unlock(); + } + T pop_front(bool wait_if_empty=false) + { + for(;;) + { + { + JMutexAutoLock lock(m_mutex); - core::map<std::string, video::ITexture*>::Node *n; - n = m_textures.find(name); + if(m_list.size() > 0) + { + if(m_list.size() == 1) + m_is_empty_mutex.Lock(); + + typename core::list<T>::Iterator begin = m_list.begin(); + T t = *begin; + m_list.erase(begin); + return t; + } - if(n != NULL) - return n->getValue(); + if(wait_if_empty == false) + throw ItemNotFoundException("MutexedQueue: item not found"); + } + + // To wait for an empty list, we're gonna hang on this mutex + m_is_empty_mutex.Lock(); + m_is_empty_mutex.Unlock(); - return NULL; + // Then loop to the beginning and hopefully return something + } } -private: - core::map<std::string, video::ITexture*> m_textures; + JMutex & getMutex() + { + return m_mutex; + } + + JMutex & getIsEmptyMutex() + { + return m_is_empty_mutex; + } + + core::list<T> & getList() + { + return m_list; + } + +protected: JMutex m_mutex; + // This is locked always when the list is empty + JMutex m_is_empty_mutex; + core::list<T> m_list; }; -class SimpleThread : public JThread +template<typename Caller, typename Data> +class CallerInfo { - bool run; - JMutex run_mutex; +public: + Caller caller; + Data data; +}; +template<typename Key, typename T, typename Caller, typename CallerData> +class GetResult +{ public: + Key key; + T item; + core::list<CallerInfo<Caller, CallerData> > callers; +}; - SimpleThread(): - JThread(), - run(true) +template<typename Key, typename T, typename Caller, typename CallerData> +class ResultQueue: public MutexedQueue< GetResult<Key, T, Caller, CallerData> > +{ +}; + +template<typename Key, typename T, typename Caller, typename CallerData> +class GetRequest +{ +public: + GetRequest() { - run_mutex.Init(); + dest = NULL; } + GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest) + { + dest = a_dest; + } + GetRequest(ResultQueue<Key,T, Caller, CallerData> *a_dest, + Key a_key) + { + dest = a_dest; + key = a_key; + } + ~GetRequest() + { + } + + Key key; + ResultQueue<Key, T, Caller, CallerData> *dest; + core::list<CallerInfo<Caller, CallerData> > callers; +}; - virtual ~SimpleThread() - {} - - virtual void * Thread() = 0; +/* + Quickhands for typical request-result queues. + Used for distributing work between threads. +*/ - bool getRun() +template<typename Key, typename T, typename Caller, typename CallerData> +class RequestQueue +{ +public: + u32 size() { - JMutexAutoLock lock(run_mutex); - return run; + return m_queue.size(); } - void setRun(bool a_run) + + void add(Key key, Caller caller, CallerData callerdata, + ResultQueue<Key, T, Caller, CallerData> *dest) { - JMutexAutoLock lock(run_mutex); - run = a_run; + JMutexAutoLock lock(m_queue.getMutex()); + + /* + If the caller is already on the list, only update CallerData + */ + for(typename core::list< GetRequest<Key, T, Caller, CallerData> >::Iterator + i = m_queue.getList().begin(); + i != m_queue.getList().end(); i++) + { + GetRequest<Key, T, Caller, CallerData> &request = *i; + + if(request.key == key) + { + for(typename core::list< CallerInfo<Caller, CallerData> >::Iterator + i = request.callers.begin(); + i != request.callers.end(); i++) + { + CallerInfo<Caller, CallerData> &ca = *i; + if(ca.caller == caller) + { + ca.data = callerdata; + return; + } + } + CallerInfo<Caller, CallerData> ca; + ca.caller = caller; + ca.data = callerdata; + request.callers.push_back(ca); + return; + } + } + + /* + Else add a new request to the queue + */ + + GetRequest<Key, T, Caller, CallerData> request; + request.key = key; + CallerInfo<Caller, CallerData> ca; + ca.caller = caller; + ca.data = callerdata; + request.callers.push_back(ca); + request.dest = dest; + + m_queue.getList().push_back(request); + + if(m_queue.getList().size() == 1) + m_queue.getIsEmptyMutex().Unlock(); } - void stop() + GetRequest<Key, T, Caller, CallerData> pop(bool wait_if_empty=false) { - setRun(false); - while(IsRunning()) - sleep_ms(100); + return m_queue.pop_front(wait_if_empty); } + +private: + MutexedQueue< GetRequest<Key, T, Caller, CallerData> > m_queue; }; #endif diff --git a/src/voxel.cpp b/src/voxel.cpp index f8a98942c..29f79992b 100644 --- a/src/voxel.cpp +++ b/src/voxel.cpp @@ -138,7 +138,7 @@ void VoxelManipulator::addArea(VoxelArea area) if(m_area.contains(area)) return; - TimeTaker timer("addArea", g_device, &addarea_time); + TimeTaker timer("addArea", g_irrlicht, &addarea_time); // Calculate new area VoxelArea new_area; @@ -290,7 +290,7 @@ void VoxelManipulator::interpolate(VoxelArea area) void VoxelManipulator::clearFlag(u8 flags) { // 0-1ms on moderate area - TimeTaker timer("clearFlag", g_device, &clearflag_time); + TimeTaker timer("clearFlag", g_irrlicht, &clearflag_time); v3s16 s = m_area.getExtent(); @@ -539,7 +539,7 @@ void VoxelManipulator::updateAreaWaterPressure(VoxelArea a, core::map<v3s16, u8> &active_nodes, bool checked3_is_clear) { - TimeTaker timer("updateAreaWaterPressure", g_device, + TimeTaker timer("updateAreaWaterPressure", g_irrlicht, &updateareawaterpressure_time); emerge(a, 3); @@ -585,7 +585,7 @@ void VoxelManipulator::updateAreaWaterPressure(VoxelArea a, try { // 0-1ms @ recur_count <= 100 - //TimeTaker timer("getWaterPressure", g_device); + //TimeTaker timer("getWaterPressure", g_irrlicht); pr = getWaterPressure(p, highest_y, recur_count); } catch(ProcessingLimitException &e) @@ -613,7 +613,7 @@ void VoxelManipulator::updateAreaWaterPressure(VoxelArea a, try { // 0ms - //TimeTaker timer("spreadWaterPressure", g_device); + //TimeTaker timer("spreadWaterPressure", g_irrlicht); spreadWaterPressure(p, pr, a, active_nodes, 0); } catch(ProcessingLimitException &e) @@ -653,7 +653,7 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos, //dstream<<"s1="<<s1<<", s2="<<s2<<std::endl; { - TimeTaker timer1("flowWater pre", g_device, &flowwater_pre_time); + TimeTaker timer1("flowWater pre", g_irrlicht, &flowwater_pre_time); // Load neighboring nodes emerge(VoxelArea(removed_pos - v3s16(1,1,1), removed_pos + v3s16(1,1,1)), 4); @@ -802,9 +802,9 @@ bool VoxelManipulator::flowWater(v3s16 removed_pos, debugprint, stoptime); } - if(stoptime != 0 && g_device != NULL) + if(stoptime != 0 && g_irrlicht != NULL) { - u32 timenow = g_device->getTimer()->getRealTime(); + u32 timenow = g_irrlicht->getTime(); if(timenow >= stoptime || (stoptime < 0x80000000 && timenow > 0x80000000)) { @@ -870,15 +870,15 @@ void VoxelManipulator::flowWater( return; } - //TimeTaker timer1("flowWater (active_nodes)", g_device); + //TimeTaker timer1("flowWater (active_nodes)", g_irrlicht); //dstream<<"active_nodes.size() = "<<active_nodes.size()<<std::endl; u32 stoptime = 0; - if(g_device != NULL) + if(g_irrlicht != NULL) { - stoptime = g_device->getTimer()->getRealTime() + timelimit; + stoptime = g_irrlicht->getTime() + timelimit; } // Count of handled active nodes |