diff --git a/builtin/ground_plane_lighting/ground_plane_lighting.cpp b/builtin/ground_plane_lighting/ground_plane_lighting.cpp index 278e660..f34bbc8 100644 --- a/builtin/ground_plane_lighting/ground_plane_lighting.cpp +++ b/builtin/ground_plane_lighting/ground_plane_lighting.cpp @@ -272,61 +272,66 @@ struct CInstance: public ground_plane_lighting::Instance void on_node_volume_updated(const voxelworld::NodeVolumeUpdated &event) { - if(!event.is_static_chunk) - return; - if(event.scene != m_scene_ref) - return; - log_v(MODULE, "Checking ground level in chunk " PV3I_FORMAT, - PV3I_PARAMS(event.chunk_p)); - const pv::Vector3DInt32 &chunk_p = event.chunk_p; - voxelworld::access(m_server, [&](voxelworld::Interface *ivoxelworld) - { - voxelworld::Instance *world = - check(ivoxelworld->get_instance(m_scene_ref)); - interface::VoxelRegistry *voxel_reg = world->get_voxel_reg(); - //const auto &chunk_size_voxels = world->get_chunk_size_voxels(); - pv::Region chunk_region = - world->get_chunk_region_voxels(chunk_p); + try { + if(!event.is_static_chunk) + return; + if(event.scene != m_scene_ref) + return; + log_v(MODULE, "Checking ground level in chunk " PV3I_FORMAT, + PV3I_PARAMS(event.chunk_p)); + const pv::Vector3DInt32 &chunk_p = event.chunk_p; + voxelworld::access(m_server, [&](voxelworld::Interface *ivoxelworld) + { + voxelworld::Instance *world = + check(ivoxelworld->get_instance(m_scene_ref)); + interface::VoxelRegistry *voxel_reg = world->get_voxel_reg(); + //const auto &chunk_size_voxels = world->get_chunk_size_voxels(); + pv::Region chunk_region = + world->get_chunk_region_voxels(chunk_p); - auto lc = chunk_region.getLowerCorner(); - auto uc = chunk_region.getUpperCorner(); - //log_nv(MODULE, "yst=["); - for(int z = lc.getZ(); z <= uc.getZ(); z++){ - for(int x = lc.getX(); x <= uc.getX(); x++){ - int32_t yst0 = get_yst(x, z); - if(yst0 > uc.getY()){ - // Y-seethrough doesn't reach here - continue; - } - int y = uc.getY(); - for(;; y--){ - VoxelInstance v = world->get_voxel( - pv::Vector3DInt32(x, y, z), true); - if(v.get_id() == interface::VOXELTYPEID_UNDEFINED){ - // NOTE: This leaves the chunks below unhandled; - // there would have to be some kind of a dirty - // flag based on which this seach would be - // continued at a later point when the chunk - // gets loaded - break; + auto lc = chunk_region.getLowerCorner(); + auto uc = chunk_region.getUpperCorner(); + //log_nv(MODULE, "yst=["); + for(int z = lc.getZ(); z <= uc.getZ(); z++){ + for(int x = lc.getX(); x <= uc.getX(); x++){ + int32_t yst0 = get_yst(x, z); + if(yst0 > uc.getY()){ + // Y-seethrough doesn't reach here + continue; } - const auto *def = voxel_reg->get_cached(v); - if(!def) - throw Exception(ss_()+"Undefined voxel: "+ - itos(v.get_id())); - bool light_passes = (!def || !def->physically_solid); - if(!light_passes) - break; + int y = uc.getY(); + for(;; y--){ + VoxelInstance v = world->get_voxel( + pv::Vector3DInt32(x, y, z), true); + if(v.get_id() == interface::VOXELTYPEID_UNDEFINED){ + // NOTE: This leaves the chunks below unhandled; + // there would have to be some kind of a dirty + // flag based on which this seach would be + // continued at a later point when the chunk + // gets loaded + break; + } + const auto *def = voxel_reg->get_cached(v); + if(!def) + throw Exception(ss_()+"Undefined voxel: "+ + itos(v.get_id())); + bool light_passes = (!def || !def->physically_solid); + if(!light_passes) + break; + } + // The first voxel downwards from the top of the world that + // doesn't pass light + int32_t yst1 = y; + //log_nv(MODULE, "%i -> %i, ", yst0, yst1); + set_yst(x, z, yst1); } - // The first voxel downwards from the top of the world that - // doesn't pass light - int32_t yst1 = y; - //log_nv(MODULE, "%i -> %i, ", yst0, yst1); - set_yst(x, z, yst1); } - } - //log_v(MODULE, "]"); - }); + //log_v(MODULE, "]"); + }); + } catch(NullptrCatch &e){ + // Something was probably deleted or unloaded + log_v(MODULE, "NullptrCatch: %s", e.what()); + } } void send_initial_sectors(int peer) diff --git a/builtin/main_context/main_context.cpp b/builtin/main_context/main_context.cpp index cfcede3..42f52ee 100644 --- a/builtin/main_context/main_context.cpp +++ b/builtin/main_context/main_context.cpp @@ -217,7 +217,7 @@ struct Module: public interface::Module, public main_context::Interface { Scene *scene = find_scene(ref); if(!scene) - throw Exception("check_scene(): Scene not found"); + throw NullptrCatch("check_scene(): Scene not found"); return scene; } diff --git a/builtin/worldgen/worldgen.cpp b/builtin/worldgen/worldgen.cpp index 7671dc4..3b012d7 100644 --- a/builtin/worldgen/worldgen.cpp +++ b/builtin/worldgen/worldgen.cpp @@ -94,22 +94,27 @@ struct CInstance: public worldgen::Instance // queued but instead sectors get queued in the event queue. void generate_next_section() { - if(!m_enabled) - throw Exception("generate_next_section(): Not enabled"); - if(m_queued_sections.empty()) - return; - const pv::Vector3DInt16 section_p = m_queued_sections.front(); - m_queued_sections.pop_front(); + try { + if(!m_enabled) + throw Exception("generate_next_section(): Not enabled"); + if(m_queued_sections.empty()) + return; + const pv::Vector3DInt16 section_p = m_queued_sections.front(); + m_queued_sections.pop_front(); - log_v(MODULE, "Generating section (%i, %i, %i); queue size: %zu", - section_p.getX(), section_p.getY(), section_p.getZ(), - m_queued_sections.size()); + log_v(MODULE, "Generating section (%i, %i, %i); queue size: %zu", + section_p.getX(), section_p.getY(), section_p.getZ(), + m_queued_sections.size()); - if(m_generator) - m_generator->generate_section(m_server, m_scene_ref, section_p); + if(m_generator) + m_generator->generate_section(m_server, m_scene_ref, section_p); - m_server->emit_event("worldgen:queue_modified", - new QueueModifiedEvent(m_scene_ref, m_queued_sections.size())); + m_server->emit_event("worldgen:queue_modified", + new QueueModifiedEvent(m_scene_ref, m_queued_sections.size())); + } catch(NullptrCatch &e){ + // Something was probably deleted or unloaded + log_v(MODULE, "NullptrCatch: %s", e.what()); + } } // Interface diff --git a/doc/conventions.txt b/doc/conventions.txt index 26ff8fd..4b50aa8 100644 --- a/doc/conventions.txt +++ b/doc/conventions.txt @@ -73,7 +73,7 @@ Non-exception throwing and exception-throwing methods ----------------------------------------------------- - get_x: Returns nullptr or equivalent if not found - find_x: Returns nullptr or equivalent if not found -- check_x: Throws exception if not found +- check_x: Throws NullptrCatch if not found To check for nullptr returned by get_x() or find_x(), use the check() function in core/types.h. diff --git a/src/core/types.h b/src/core/types.h index b0c0112..f43ef0c 100644 --- a/src/core/types.h +++ b/src/core/types.h @@ -66,7 +66,9 @@ struct Exception: public std::exception { } }; #define DEFINE_EXCEPTION(name, base) struct name: public base \ -{name(const ss_ &msg = ""): base(ss_()+#name+msg){}} +{name(const ss_ &msg): base(msg){}} + +DEFINE_EXCEPTION(NullptrCatch, Exception); static inline ss_ itos(int64_t i){ char buf[22]; @@ -152,13 +154,13 @@ static inline cc_* cs(const T &v){ template static inline T* check(T *v){ if(v == nullptr) - throw Exception("check(): nullptr"); + throw NullptrCatch("check(): nullptr"); return v; } template static inline const T* check(const T *v){ if(v == nullptr) - throw Exception("check(): nullptr"); + throw NullptrCatch("check(): nullptr"); return v; } diff --git a/src/server/state.cpp b/src/server/state.cpp index f32c4a7..841d9ed 100644 --- a/src/server/state.cpp +++ b/src/server/state.cpp @@ -315,7 +315,7 @@ void ModuleThread::handle_direct_cb( log_t(MODULE, "M[%s] ~direct_cb(): Executed", cs(mc->info.name)); } catch(...){ - log_v(MODULE, "M[%s] ~direct_cb() failed (exception)", + log_t(MODULE, "M[%s] ~direct_cb() failed (exception)", cs(mc->info.name)); // direct_cb() exception should not directly shutdown the // server; instead they are passed to the caller. Eventually