diff --git a/edition/voxel_tool.cpp b/edition/voxel_tool.cpp index 2bf90910..d3fd770a 100644 --- a/edition/voxel_tool.cpp +++ b/edition/voxel_tool.cpp @@ -1,6 +1,6 @@ #include "voxel_tool.h" #include "../storage/voxel_buffer_gd.h" -#include "../util/macros.h" +#include "../util/log.h" #include "../util/profiling.h" namespace zylann::voxel { diff --git a/editor/graph/voxel_graph_editor.cpp b/editor/graph/voxel_graph_editor.cpp index 4f2d136d..ae8dd194 100644 --- a/editor/graph/voxel_graph_editor.cpp +++ b/editor/graph/voxel_graph_editor.cpp @@ -2,6 +2,8 @@ #include "../../generators/graph/voxel_generator_graph.h" #include "../../generators/graph/voxel_graph_node_db.h" #include "../../terrain/voxel_node.h" +#include "../../util/godot/funcs.h" +#include "../../util/log.h" #include "../../util/macros.h" #include "voxel_graph_editor_node.h" #include "voxel_graph_editor_node_preview.h" @@ -155,7 +157,7 @@ void VoxelGraphEditor::set_voxel_node(VoxelNode *node) { ZN_PRINT_VERBOSE("Reference node for VoxelGraph gizmos: null"); _debug_renderer.set_world(nullptr); } else { - ZN_PRINT_VERBOSE(String("Reference node for VoxelGraph gizmos: {0}").format(varray(node->get_path()))); + ZN_PRINT_VERBOSE(format("Reference node for VoxelGraph gizmos: {}", String(node->get_path()))); _debug_renderer.set_world(_voxel_node->get_world_3d().ptr()); } } @@ -619,7 +621,7 @@ void VoxelGraphEditor::update_previews() { } uint64_t time_taken = Time::get_singleton()->get_ticks_usec() - time_before; - ZN_PRINT_VERBOSE(String("Previews generated in {0} us").format(varray(time_taken))); + ZN_PRINT_VERBOSE(format("Previews generated in {} us", time_taken)); } void VoxelGraphEditor::update_range_analysis_previews() { diff --git a/editor/graph/voxel_graph_node_inspector_wrapper.cpp b/editor/graph/voxel_graph_node_inspector_wrapper.cpp index bce2c09e..e117f5c9 100644 --- a/editor/graph/voxel_graph_node_inspector_wrapper.cpp +++ b/editor/graph/voxel_graph_node_inspector_wrapper.cpp @@ -1,7 +1,7 @@ #include "voxel_graph_node_inspector_wrapper.h" #include "../../generators/graph/voxel_graph_node_db.h" #include "../../util/godot/funcs.h" -#include "../../util/macros.h" +#include "../../util/log.h" #include "voxel_graph_editor.h" #include diff --git a/generators/graph/voxel_generator_graph.cpp b/generators/graph/voxel_generator_graph.cpp index 8d97ff1b..7c3154d4 100644 --- a/generators/graph/voxel_generator_graph.cpp +++ b/generators/graph/voxel_generator_graph.cpp @@ -2,6 +2,7 @@ #include "../../storage/voxel_buffer_internal.h" #include "../../util/expression_parser.h" #include "../../util/godot/funcs.h" +#include "../../util/log.h" #include "../../util/macros.h" #include "../../util/profiling.h" #include "../../util/profiling_clock.h" @@ -1021,7 +1022,7 @@ VoxelGraphRuntime::CompilationResult VoxelGeneratorGraph::compile() { _runtime = r; const int64_t time_spent = Time::get_singleton()->get_ticks_usec() - time_before; - ZN_PRINT_VERBOSE(String("Voxel graph compiled in {0} us").format(varray(time_spent))); + ZN_PRINT_VERBOSE(format("Voxel graph compiled in {} us", time_spent)); return result; } diff --git a/generators/graph/voxel_graph_runtime.cpp b/generators/graph/voxel_graph_runtime.cpp index 46f7292c..79d7c144 100644 --- a/generators/graph/voxel_graph_runtime.cpp +++ b/generators/graph/voxel_graph_runtime.cpp @@ -1,6 +1,7 @@ #include "voxel_graph_runtime.h" #include "../../util/expression_parser.h" #include "../../util/funcs.h" +#include "../../util/log.h" #include "../../util/macros.h" #include "../../util/profiling.h" #include "voxel_generator_graph.h" @@ -680,9 +681,8 @@ VoxelGraphRuntime::CompilationResult VoxelGraphRuntime::_compile(const ProgramGr _program.buffer_count = mem.next_address; - ZN_PRINT_VERBOSE(String("Compiled voxel graph. Program size: {0}b, buffers: {1}") - .format(varray(ZN_SIZE_T_TO_VARIANT(_program.operations.size() * sizeof(uint16_t)), - ZN_SIZE_T_TO_VARIANT(_program.buffer_count)))); + ZN_PRINT_VERBOSE(format("Compiled voxel graph. Program size: {}b, buffers: {}", + _program.operations.size() * sizeof(uint16_t), _program.buffer_count)); CompilationResult result; result.success = true; diff --git a/meshers/blocky/voxel_blocky_library.cpp b/meshers/blocky/voxel_blocky_library.cpp index 325b2879..ed50a374 100644 --- a/meshers/blocky/voxel_blocky_library.cpp +++ b/meshers/blocky/voxel_blocky_library.cpp @@ -1,5 +1,5 @@ #include "voxel_blocky_library.h" -#include "../../util/macros.h" +#include "../../util/log.h" #include #include @@ -182,7 +182,7 @@ void VoxelBlockyLibrary::bake() { generate_side_culling_matrix(); uint64_t time_spent = Time::get_singleton()->get_ticks_usec() - time_before; - ZN_PRINT_VERBOSE(String("Took {0} us to bake VoxelLibrary").format(varray(time_spent))); + ZN_PRINT_VERBOSE(format("Took {} us to bake VoxelLibrary", time_spent)); } void VoxelBlockyLibrary::generate_side_culling_matrix() { diff --git a/register_types.cpp b/register_types.cpp index 404384c6..3a955a14 100644 --- a/register_types.cpp +++ b/register_types.cpp @@ -149,18 +149,18 @@ void register_voxel_types() { // Engine::get_singleton()->add_singleton(Engine::Singleton("SingletonName",singleton_instance)); // Reminders - ZN_PRINT_VERBOSE(String("Size of Variant: {0}").format(varray((int)sizeof(Variant)))); - ZN_PRINT_VERBOSE(String("Size of Object: {0}").format(varray((int)sizeof(Object)))); - ZN_PRINT_VERBOSE(String("Size of RefCounted: {0}").format(varray((int)sizeof(RefCounted)))); - ZN_PRINT_VERBOSE(String("Size of Node: {0}").format(varray((int)sizeof(Node)))); - ZN_PRINT_VERBOSE(String("Size of Node3D: {0}").format(varray((int)sizeof(Node3D)))); - ZN_PRINT_VERBOSE(String("Size of gd::VoxelBuffer: {0}").format(varray((int)sizeof(gd::VoxelBuffer)))); - ZN_PRINT_VERBOSE(String("Size of VoxelBufferInternal: {0}").format(varray((int)sizeof(VoxelBufferInternal)))); - ZN_PRINT_VERBOSE(String("Size of VoxelMeshBlock: {0}").format(varray((int)sizeof(VoxelMeshBlock)))); - ZN_PRINT_VERBOSE(String("Size of VoxelTerrain: {0}").format(varray((int)sizeof(VoxelTerrain)))); - ZN_PRINT_VERBOSE(String("Size of VoxelLodTerrain: {0}").format(varray((int)sizeof(VoxelLodTerrain)))); - ZN_PRINT_VERBOSE(String("Size of VoxelInstancer: {0}").format(varray((int)sizeof(VoxelInstancer)))); - ZN_PRINT_VERBOSE(String("Size of VoxelDataMap: {0}").format(varray((int)sizeof(VoxelDataMap)))); + ZN_PRINT_VERBOSE(format("Size of Variant: {}", sizeof(Variant))); + ZN_PRINT_VERBOSE(format("Size of Object: {}", sizeof(Object))); + ZN_PRINT_VERBOSE(format("Size of RefCounted: {}", sizeof(RefCounted))); + ZN_PRINT_VERBOSE(format("Size of Node: {}", sizeof(Node))); + ZN_PRINT_VERBOSE(format("Size of Node3D: {}", sizeof(Node3D))); + ZN_PRINT_VERBOSE(format("Size of gd::VoxelBuffer: {}", sizeof(gd::VoxelBuffer))); + ZN_PRINT_VERBOSE(format("Size of VoxelBufferInternal: {}", sizeof(VoxelBufferInternal))); + ZN_PRINT_VERBOSE(format("Size of VoxelMeshBlock: {}", sizeof(VoxelMeshBlock))); + ZN_PRINT_VERBOSE(format("Size of VoxelTerrain: {}", sizeof(VoxelTerrain))); + ZN_PRINT_VERBOSE(format("Size of VoxelLodTerrain: {}", sizeof(VoxelLodTerrain))); + ZN_PRINT_VERBOSE(format("Size of VoxelInstancer: {}", sizeof(VoxelInstancer))); + ZN_PRINT_VERBOSE(format("Size of VoxelDataMap: {}", sizeof(VoxelDataMap))); #ifdef TOOLS_ENABLED EditorPlugins::add_by_type(); diff --git a/server/generate_block_task.cpp b/server/generate_block_task.cpp index da57d40a..357cc67a 100644 --- a/server/generate_block_task.cpp +++ b/server/generate_block_task.cpp @@ -1,7 +1,7 @@ #include "generate_block_task.h" #include "../storage/voxel_buffer_internal.h" #include "../util/godot/funcs.h" -#include "../util/macros.h" +#include "../util/log.h" #include "../util/profiling.h" #include "save_block_data_task.h" #include "voxel_server.h" @@ -48,8 +48,7 @@ void GenerateBlockTask::run(zylann::ThreadedTaskContext ctx) { // TODO In some cases we dont want this to run all the time, do we? // Like in full load mode, where non-edited blocks remain generated on the fly... if (stream.is_valid() && stream->get_save_generator_output()) { - ZN_PRINT_VERBOSE( - String("Requesting save of generator output for block {0} lod {1}").format(varray(position, lod))); + ZN_PRINT_VERBOSE(format("Requesting save of generator output for block {} lod {}", position, lod)); // TODO Optimization: `voxels` doesnt actually need to be shared std::shared_ptr voxels_copy = gd_make_shared(); diff --git a/server/load_all_blocks_data_task.cpp b/server/load_all_blocks_data_task.cpp index 786c293b..94831325 100644 --- a/server/load_all_blocks_data_task.cpp +++ b/server/load_all_blocks_data_task.cpp @@ -1,5 +1,5 @@ #include "load_all_blocks_data_task.h" -#include "../util/macros.h" +#include "../util/log.h" #include "../util/profiling.h" #include "voxel_server.h" @@ -14,8 +14,7 @@ void LoadAllBlocksDataTask::run(zylann::ThreadedTaskContext ctx) { stream->load_all_blocks(_result); - ZN_PRINT_VERBOSE(String("Loaded {0} blocks for volume {1}") - .format(varray(ZN_SIZE_T_TO_VARIANT(_result.blocks.size()), volume_id))); + ZN_PRINT_VERBOSE(format("Loaded {} blocks for volume {}", _result.blocks.size(), volume_id)); } int LoadAllBlocksDataTask::get_priority() { diff --git a/server/load_block_data_task.cpp b/server/load_block_data_task.cpp index 140d96d4..006e5432 100644 --- a/server/load_block_data_task.cpp +++ b/server/load_block_data_task.cpp @@ -1,7 +1,7 @@ #include "load_block_data_task.h" #include "../storage/voxel_buffer_internal.h" #include "../util/godot/funcs.h" -#include "../util/macros.h" +#include "../util/log.h" #include "../util/profiling.h" #include "generate_block_task.h" #include "voxel_server.h" diff --git a/server/mesh_block_task.cpp b/server/mesh_block_task.cpp index 8542ba16..ad89e5fc 100644 --- a/server/mesh_block_task.cpp +++ b/server/mesh_block_task.cpp @@ -1,5 +1,5 @@ #include "mesh_block_task.h" -#include "../util/macros.h" +#include "../util/log.h" #include "../util/profiling.h" #include "voxel_server.h" diff --git a/server/save_block_data_task.cpp b/server/save_block_data_task.cpp index 1fb7a341..2bf9a7fa 100644 --- a/server/save_block_data_task.cpp +++ b/server/save_block_data_task.cpp @@ -1,7 +1,7 @@ #include "save_block_data_task.h" #include "../storage/voxel_buffer_internal.h" #include "../util/godot/funcs.h" -#include "../util/macros.h" +#include "../util/log.h" #include "../util/profiling.h" #include "generate_block_task.h" #include "voxel_server.h" @@ -76,8 +76,7 @@ void SaveBlockDataTask::run(zylann::ThreadedTaskContext ctx) { // On the other hand, if we want to represent the fact that "everything was deleted here", // this should not be null. - ZN_PRINT_VERBOSE(String("Saving instance block {0} lod {1} with data {2}") - .format(varray(_position, _lod, ptr2s(_instances.get())))); + ZN_PRINT_VERBOSE(format("Saving instance block {} lod {} with data {}", _position, _lod, _instances.get())); VoxelStream::InstancesQueryData instances_query{ std::move(_instances), _position, _lod }; stream->save_instance_blocks(Span(&instances_query, 1)); diff --git a/server/voxel_server.cpp b/server/voxel_server.cpp index a47178c0..0ffdb1f0 100644 --- a/server/voxel_server.cpp +++ b/server/voxel_server.cpp @@ -3,6 +3,7 @@ #include "../storage/voxel_memory_pool.h" #include "../util/funcs.h" #include "../util/godot/funcs.h" +#include "../util/log.h" #include "../util/macros.h" #include "../util/profiling.h" #include "generate_block_task.h" @@ -39,7 +40,7 @@ VoxelServer::VoxelServer() { CRASH_COND(ProjectSettings::get_singleton() == nullptr); const int hw_threads_hint = std::thread::hardware_concurrency(); - ZN_PRINT_VERBOSE(String("Voxel: HW threads hint: {0}").format(varray(hw_threads_hint))); + ZN_PRINT_VERBOSE(format("Voxel: HW threads hint: {}", hw_threads_hint)); // Compute thread count for general pool. // Note that the I/O thread counts as one used thread and will always be present. @@ -79,7 +80,7 @@ VoxelServer::VoxelServer() { // `-1` is for the stream thread const int thread_count_by_ratio = int(Math::round(float(threads_ratio) * hw_threads_hint)) - 1; const int thread_count = math::clamp(thread_count_by_ratio, minimum_thread_count, maximum_thread_count); - ZN_PRINT_VERBOSE(String("Voxel: automatic thread count set to {0}").format(varray(thread_count))); + ZN_PRINT_VERBOSE(format("Voxel: automatic thread count set to {}", thread_count)); if (thread_count > hw_threads_hint) { WARN_PRINT("Configured thread count exceeds hardware thread count. Performance may not be optimal"); @@ -102,9 +103,9 @@ VoxelServer::VoxelServer() { // Init world _world.shared_priority_dependency = gd_make_shared(); - ZN_PRINT_VERBOSE(String("Size of LoadBlockDataTask: {0}").format(varray((int)sizeof(LoadBlockDataTask)))); - ZN_PRINT_VERBOSE(String("Size of SaveBlockDataTask: {0}").format(varray((int)sizeof(SaveBlockDataTask)))); - ZN_PRINT_VERBOSE(String("Size of MeshBlockTask: {0}").format(varray((int)sizeof(MeshBlockTask)))); + ZN_PRINT_VERBOSE(format("Size of LoadBlockDataTask: {}", sizeof(LoadBlockDataTask))); + ZN_PRINT_VERBOSE(format("Size of SaveBlockDataTask: {}", sizeof(SaveBlockDataTask))); + ZN_PRINT_VERBOSE(format("Size of MeshBlockTask: {}", sizeof(MeshBlockTask))); } VoxelServer::~VoxelServer() { @@ -340,7 +341,7 @@ void VoxelServer::request_block_generate( } void VoxelServer::request_all_stream_blocks(uint32_t volume_id) { - ZN_PRINT_VERBOSE(String("Request all blocks for volume {0}").format(varray(volume_id))); + ZN_PRINT_VERBOSE(format("Request all blocks for volume {}", volume_id)); const Volume &volume = _world.volumes.get(volume_id); ERR_FAIL_COND(volume.stream.is_null()); CRASH_COND(volume.stream_dependency == nullptr); diff --git a/server/voxel_server_updater.cpp b/server/voxel_server_updater.cpp index b50f35d5..eaef0e6f 100644 --- a/server/voxel_server_updater.cpp +++ b/server/voxel_server_updater.cpp @@ -1,5 +1,5 @@ #include "voxel_server_updater.h" -#include "../util/macros.h" +#include "../util/log.h" #include "voxel_server.h" // Needed for doing `Node *root = SceneTree::get_root()`, Window* is forward-declared diff --git a/storage/voxel_data_block.h b/storage/voxel_data_block.h index 0d818fe5..b9c42b7a 100644 --- a/storage/voxel_data_block.h +++ b/storage/voxel_data_block.h @@ -2,7 +2,7 @@ #define VOXEL_DATA_BLOCK_H #include "../storage/voxel_buffer_internal.h" -#include "../util/macros.h" +#include "../util/log.h" #include "../util/ref_count.h" #include @@ -51,7 +51,7 @@ public: void set_modified(bool modified) { #ifdef TOOLS_ENABLED if (_modified == false && modified) { - ZN_PRINT_VERBOSE(String("Marking block {0} as modified").format(varray(position))); + ZN_PRINT_VERBOSE(format("Marking block {} as modified", position)); } #endif _modified = modified; diff --git a/storage/voxel_data_map.cpp b/storage/voxel_data_map.cpp index 35ae6cba..93c4dd69 100644 --- a/storage/voxel_data_map.cpp +++ b/storage/voxel_data_map.cpp @@ -190,8 +190,8 @@ VoxelDataBlock *VoxelDataMap::set_block_buffer( block->set_voxels(buffer); } else { VOXEL_PROFILE_MESSAGE("Redundant data block"); - ZN_PRINT_VERBOSE(String("Discarded block {0} lod {1}, there was already data and overwriting is not enabled") - .format(varray(bpos, _lod_index))); + ZN_PRINT_VERBOSE(format( + "Discarded block {} lod {}, there was already data and overwriting is not enabled", bpos, _lod_index)); } return block; } @@ -374,8 +374,7 @@ void preload_box(VoxelDataLodMap &data, Box3i voxel_box, VoxelGenerator *generat for (uint8_t lod_index = 0; lod_index < data.lod_count; ++lod_index) { const Box3i block_box = voxel_box.downscaled(data_block_size << lod_index); - ZN_PRINT_VERBOSE( - String("Preloading box {0} at lod {1} synchronously").format(varray(block_box.to_string(), lod_index))); + ZN_PRINT_VERBOSE(format("Preloading box {} at lod {} synchronously", block_box, lod_index)); VoxelDataLodMap::Lod &data_lod = data.lods[lod_index]; const unsigned int prev_size = todo.size(); diff --git a/storage/voxel_memory_pool.h b/storage/voxel_memory_pool.h index 4d783009..af3fcbc1 100644 --- a/storage/voxel_memory_pool.h +++ b/storage/voxel_memory_pool.h @@ -53,6 +53,7 @@ private: public: static void create_singleton(); static void destroy_singleton(); + // TODO Return a reference, it must not be null when called static VoxelMemoryPool *get_singleton(); VoxelMemoryPool(); diff --git a/streams/region/region_file.cpp b/streams/region/region_file.cpp index c73320ec..1728dd49 100644 --- a/streams/region/region_file.cpp +++ b/streams/region/region_file.cpp @@ -1,5 +1,7 @@ #include "region_file.h" #include "../../streams/voxel_block_serializer.h" +#include "../../util/godot/funcs.h" +#include "../../util/log.h" #include "../../util/macros.h" #include "../../util/profiling.h" #include "../file_utils.h" @@ -559,7 +561,7 @@ bool RegionFile::save_header(FileAccess *f) { } bool RegionFile::migrate_from_v2_to_v3(FileAccess *f, RegionFormat &format) { - ZN_PRINT_VERBOSE(String("Migrating region file {0} from v2 to v3").format(varray(_file_path))); + ZN_PRINT_VERBOSE(zylann::format("Migrating region file {} from v2 to v3", _file_path)); // We can migrate if we know in advance what format the file should contain. ERR_FAIL_COND_V_MSG(format.block_size_po2 == 0, false, "Cannot migrate without knowing the correct format"); diff --git a/streams/region/voxel_stream_region_files.cpp b/streams/region/voxel_stream_region_files.cpp index 7bec3f14..020866de 100644 --- a/streams/region/voxel_stream_region_files.cpp +++ b/streams/region/voxel_stream_region_files.cpp @@ -1,6 +1,7 @@ #include "voxel_stream_region_files.h" #include "../../server/voxel_server.h" -#include "../../util/macros.h" +#include "../../util/godot/funcs.h" +#include "../../util/log.h" #include "../../util/math/box3i.h" #include "../../util/profiling.h" @@ -592,7 +593,7 @@ void VoxelStreamRegionFiles::_convert_files(Meta new_meta) { } old_stream->set_directory(old_dir); - ZN_PRINT_VERBOSE("Data backed up as " + old_dir); + ZN_PRINT_VERBOSE(format("Data backed up as {}", old_dir)); } struct PositionAndLod { @@ -663,7 +664,7 @@ void VoxelStreamRegionFiles::_convert_files(Meta new_meta) { continue; } - ZN_PRINT_VERBOSE(String("Converting region lod{0}/{1}").format(varray(region_info.lod, region_info.position))); + ZN_PRINT_VERBOSE(format("Converting region lod{}/{}", region_info.lod, region_info.position)); const unsigned int blocks_count = old_region->region.get_header_block_count(); for (unsigned int j = 0; j < blocks_count; ++j) { diff --git a/streams/sqlite/voxel_stream_sqlite.cpp b/streams/sqlite/voxel_stream_sqlite.cpp index 7b7cf8c0..4cdc0618 100644 --- a/streams/sqlite/voxel_stream_sqlite.cpp +++ b/streams/sqlite/voxel_stream_sqlite.cpp @@ -1,7 +1,7 @@ #include "voxel_stream_sqlite.h" #include "../../thirdparty/sqlite/sqlite3.h" #include "../../util/godot/funcs.h" -#include "../../util/macros.h" +#include "../../util/log.h" #include "../../util/profiling.h" #include "../compressed_data.h" @@ -820,8 +820,8 @@ void VoxelStreamSQLite::load_all_blocks(FullLoadingResult &result) { Context *ctx = reinterpret_cast(callback_data); if (voxel_data.size() == 0 && instances_data.size() == 0) { - ZN_PRINT_VERBOSE(String("Unexpected empty voxel data and instances data at {0} lod {1}") - .format(varray(Vector3(location.x, location.y, location.z), location.lod))); + ZN_PRINT_VERBOSE(format("Unexpected empty voxel data and instances data at {} lod {}", + Vector3i(location.x, location.y, location.z), location.lod)); return; } @@ -874,8 +874,7 @@ void VoxelStreamSQLite::flush_cache() { // This function does not lock any mutex for internal use. void VoxelStreamSQLite::flush_cache(VoxelStreamSQLiteInternal *con) { VOXEL_PROFILE_SCOPE(); - ZN_PRINT_VERBOSE(String("VoxelStreamSQLite: Flushing cache ({0} elements)") - .format(varray(_cache.get_indicative_block_count()))); + ZN_PRINT_VERBOSE(format("VoxelStreamSQLite: Flushing cache ({} elements)", _cache.get_indicative_block_count())); ERR_FAIL_COND(con == nullptr); ERR_FAIL_COND(con->begin_transaction() == false); diff --git a/streams/vox_data.cpp b/streams/vox_data.cpp index 3793cf80..e79fe6ef 100644 --- a/streams/vox_data.cpp +++ b/streams/vox_data.cpp @@ -1,5 +1,6 @@ #include "vox_data.h" -#include "../util/macros.h" +#include "../util/godot/funcs.h" +#include "../util/log.h" #include "../util/profiling.h" #include @@ -199,7 +200,7 @@ Error Data::_load_from_file(String fpath) { // https://github.com/ephtracy/voxel-model/blob/master/MagicaVoxel-file-format-vox.txt // https://github.com/ephtracy/voxel-model/blob/master/MagicaVoxel-file-format-vox-extension.txt - ZN_PRINT_VERBOSE(String("Loading ") + fpath); + ZN_PRINT_VERBOSE(format("Loading {}", fpath)); Error open_err; FileAccessRef f_ref = FileAccess::open(fpath, FileAccess::READ, &open_err); @@ -228,8 +229,7 @@ Error Data::_load_from_file(String fpath) { const uint32_t chunk_size = f.get_32(); f.get_32(); // child_chunks_size - ZN_PRINT_VERBOSE(String("Reading chunk {0} at {1}, size={2}") - .format(varray(chunk_id, ZN_SIZE_T_TO_VARIANT(f.get_position()), chunk_size))); + ZN_PRINT_VERBOSE(format("Reading chunk {} at {}, size={}", chunk_id, f.get_position(), chunk_size)); if (strcmp(chunk_id, "SIZE") == 0) { Vector3i size; @@ -472,7 +472,7 @@ Error Data::_load_from_file(String fpath) { _materials.insert(std::make_pair(material_id, std::move(material_ptr))); } else { - ZN_PRINT_VERBOSE(String("Skipping chunk ") + chunk_id); + ZN_PRINT_VERBOSE(format("Skipping chunk {}", chunk_id)); // Ignore chunk f.seek(f.get_position() + chunk_size); } @@ -552,7 +552,7 @@ Error Data::_load_from_file(String fpath) { ERR_FAIL_COND_V_MSG(_root_node_id == -1, ERR_INVALID_DATA, "Root node not found"); } - ZN_PRINT_VERBOSE(String("Done loading ") + fpath); + ZN_PRINT_VERBOSE(format("Done loading {}", fpath)); return OK; } diff --git a/terrain/fixed_lod/voxel_terrain.cpp b/terrain/fixed_lod/voxel_terrain.cpp index abdb8647..3f68e16c 100644 --- a/terrain/fixed_lod/voxel_terrain.cpp +++ b/terrain/fixed_lod/voxel_terrain.cpp @@ -893,15 +893,14 @@ void VoxelTerrain::send_block_data_requests() { // Blocks to save if (_stream.is_valid()) { for (unsigned int i = 0; i < _blocks_to_save.size(); ++i) { - ZN_PRINT_VERBOSE(String("Requesting save of block {0}").format(varray(_blocks_to_save[i].position))); + ZN_PRINT_VERBOSE(format("Requesting save of block {}", _blocks_to_save[i].position)); const BlockToSave b = _blocks_to_save[i]; // TODO Batch request VoxelServer::get_singleton().request_voxel_block_save(_volume_id, b.voxels, b.position, 0); } } else { if (_blocks_to_save.size() > 0) { - ZN_PRINT_VERBOSE(String("Not saving {0} blocks because no stream is assigned") - .format(varray(ZN_SIZE_T_TO_VARIANT(_blocks_to_save.size())))); + ZN_PRINT_VERBOSE(format("Not saving {} blocks because no stream is assigned", _blocks_to_save.size())); } } @@ -1206,9 +1205,10 @@ void VoxelTerrain::apply_data_block_response(VoxelServer::BlockDataOutput &ob) { if (ob.dropped) { // That block was cancelled by the server, but we are still expecting it. // We'll have to request it again. - ZN_PRINT_VERBOSE(String("Received a block loading drop while we were still expecting it: " - "lod{0} ({1}, {2}, {3}), re-requesting it") - .format(varray(ob.lod, ob.position.x, ob.position.y, ob.position.z))); + ZN_PRINT_VERBOSE(format("Received a block loading drop while we were still expecting it: " + "lod{} ({}, {}, {}), re-requesting it", + ob.lod, ob.position.x, ob.position.y, ob.position.z)); + ++_stats.dropped_block_loads; _blocks_pending_load.push_back(ob.position); diff --git a/terrain/instancing/voxel_instancer.cpp b/terrain/instancing/voxel_instancer.cpp index 2896023a..49cb8d3c 100644 --- a/terrain/instancing/voxel_instancer.cpp +++ b/terrain/instancing/voxel_instancer.cpp @@ -1084,7 +1084,7 @@ void VoxelInstancer::save_block(Vector3i data_grid_pos, int lod_index) const { VOXEL_PROFILE_SCOPE(); ERR_FAIL_COND(_library.is_null()); - ZN_PRINT_VERBOSE(String("Requesting save of instance block {0} lod {1}").format(varray(data_grid_pos, lod_index))); + ZN_PRINT_VERBOSE(format("Requesting save of instance block {} lod {}", data_grid_pos, lod_index)); const Lod &lod = _lods[lod_index]; diff --git a/terrain/variable_lod/voxel_lod_terrain.cpp b/terrain/variable_lod/voxel_lod_terrain.cpp index aadd7235..2ea7e051 100644 --- a/terrain/variable_lod/voxel_lod_terrain.cpp +++ b/terrain/variable_lod/voxel_lod_terrain.cpp @@ -6,7 +6,7 @@ #include "../../server/voxel_server_updater.h" #include "../../util/funcs.h" #include "../../util/godot/funcs.h" -#include "../../util/macros.h" +#include "../../util/log.h" #include "../../util/profiling.h" #include "../../util/profiling_clock.h" #include "../../util/tasks/async_dependency_tracker.h" @@ -1283,8 +1283,7 @@ void VoxelLodTerrain::apply_data_block_response(VoxelServer::BlockDataOutput &ob if (!ob.initial_load) { if (!thread_safe_contains(lod.loading_blocks, ob.position, lod.loading_blocks_mutex)) { // That block was not requested, or is no longer needed. drop it... - ZN_PRINT_VERBOSE(String("Ignoring block {0} lod {1}, it was not in loading blocks") - .format(varray(ob.position, ob.lod))); + ZN_PRINT_VERBOSE(format("Ignoring block {} lod {}, it was not in loading blocks", ob.position, ob.lod)); ++_stats.dropped_block_loads; return; } diff --git a/terrain/variable_lod/voxel_lod_terrain_update_task.cpp b/terrain/variable_lod/voxel_lod_terrain_update_task.cpp index cd512cb2..f0189988 100644 --- a/terrain/variable_lod/voxel_lod_terrain_update_task.cpp +++ b/terrain/variable_lod/voxel_lod_terrain_update_task.cpp @@ -1135,7 +1135,7 @@ void VoxelLodTerrainUpdateTask::send_block_save_requests(uint32_t volume_id, BufferedTaskScheduler &task_scheduler) { for (unsigned int i = 0; i < blocks_to_save.size(); ++i) { VoxelLodTerrainUpdateData::BlockToSave &b = blocks_to_save[i]; - ZN_PRINT_VERBOSE(String("Requesting save of block {0} lod {1}").format(varray(b.position, b.lod))); + ZN_PRINT_VERBOSE(format("Requesting save of block {} lod {}", b.position, b.lod)); request_voxel_block_save( volume_id, b.voxels, b.position, b.lod, stream_dependency, data_block_size, task_scheduler); } @@ -1278,7 +1278,7 @@ static std::shared_ptr preload_boxes_async(VoxelLodTerra } } - ZN_PRINT_VERBOSE(String("Preloading boxes with {1} tasks").format(varray(ZN_SIZE_T_TO_VARIANT(todo.size())))); + ZN_PRINT_VERBOSE(format("Preloading boxes with {} tasks", todo.size())); std::shared_ptr tracker = nullptr; diff --git a/util/godot/funcs.cpp b/util/godot/funcs.cpp index ec017efa..6b4e3b0e 100644 --- a/util/godot/funcs.cpp +++ b/util/godot/funcs.cpp @@ -7,6 +7,7 @@ #include #include #include +#include namespace zylann { @@ -282,3 +283,10 @@ PackedStringArray to_godot(const std::vector &sv) { } } // namespace zylann + +std::stringstream &operator<<(std::stringstream &ss, GodotStringWrapper s) { + const CharString cs = s.s.utf8(); + // String has non-explicit constructors from various types making this ambiguous + ss.std::stringstream::operator<<(cs.get_data()); + return ss; +} diff --git a/util/godot/funcs.h b/util/godot/funcs.h index f1653ac5..9ed143ef 100644 --- a/util/godot/funcs.h +++ b/util/godot/funcs.h @@ -7,6 +7,7 @@ #include +#include #include class Mesh; @@ -137,4 +138,13 @@ inline String ptr2s(const void *p) { } // namespace zylann +// I gave up trying to nicely convert Godot's String here... it has non-explicit `const char*` constructor, that makes +// other overloads ambiguous... +//std::stringstream &operator<<(std::stringstream &ss, const String &s); +struct GodotStringWrapper { + GodotStringWrapper(const String &p_s) : s(p_s) {} + const String &s; +}; +std::stringstream &operator<<(std::stringstream &ss, GodotStringWrapper s); + #endif // VOXEL_UTILITY_GODOT_FUNCS_H diff --git a/util/macros.cpp b/util/log.cpp similarity index 56% rename from util/macros.cpp rename to util/log.cpp index 9e2495d4..0616c3c4 100644 --- a/util/macros.cpp +++ b/util/log.cpp @@ -6,4 +6,12 @@ bool is_verbose_output_enabled() { return OS::get_singleton()->is_stdout_verbose(); } +void println(const char *cstr) { + print_line(cstr); +} + +void println(const std::string &s) { + print_line(s.c_str()); +} + } // namespace zylann diff --git a/util/log.h b/util/log.h new file mode 100644 index 00000000..8fc06d11 --- /dev/null +++ b/util/log.h @@ -0,0 +1,76 @@ +#ifndef ZYLANN_LOG_H +#define ZYLANN_LOG_H + +#include +#include +#include + +// print_verbose() is used everywhere in Godot, but its drawback is that even if you turn it off, strings +// you print are still allocated and formatted, to not be used. This macro avoids the string. +#define ZN_PRINT_VERBOSE(msg) \ + if (zylann::is_verbose_output_enabled()) { \ + zylann::println(msg); \ + } + +namespace zylann { + +bool is_verbose_output_enabled(); + +// TODO Can't use `print_line` because Godot defines it as a macro +void println(const char *cstr); +void println(const std::string &s); + +template +std::string_view consume_next_format_placeholder(std::string_view fmt, std::stringstream &ss, const T &a) { + const size_t pi = fmt.find("{}"); + if (pi == std::string_view::npos) { + // Too many arguments supplied? + ss << fmt << " [...]"; + return ""; + } + ss << fmt.substr(0, pi); + ss << a; + return fmt.substr(pi + 2); +} + +template +std::string format(std::string_view fmt, T a) { + std::stringstream ss; + fmt = consume_next_format_placeholder(fmt, ss, a); + ss << fmt; + return ss.str(); +} + +template +std::string format(std::string_view fmt, T0 a0, T1 a1) { + std::stringstream ss; + fmt = consume_next_format_placeholder(fmt, ss, a0); + fmt = consume_next_format_placeholder(fmt, ss, a1); + ss << fmt; + return ss.str(); +} + +template +std::string format(std::string_view fmt, T0 a0, T1 a1, T2 a2) { + std::stringstream ss; + fmt = consume_next_format_placeholder(fmt, ss, a0); + fmt = consume_next_format_placeholder(fmt, ss, a1); + fmt = consume_next_format_placeholder(fmt, ss, a2); + ss << fmt; + return ss.str(); +} + +template +std::string format(std::string_view fmt, T0 a0, T1 a1, T2 a2, T3 a3) { + std::stringstream ss; + fmt = consume_next_format_placeholder(fmt, ss, a0); + fmt = consume_next_format_placeholder(fmt, ss, a1); + fmt = consume_next_format_placeholder(fmt, ss, a2); + fmt = consume_next_format_placeholder(fmt, ss, a3); + ss << fmt; + return ss.str(); +} + +} // namespace zylann + +#endif // ZYLANN_LOG_H diff --git a/util/macros.h b/util/macros.h index 38c399cf..a5d8c0e9 100644 --- a/util/macros.h +++ b/util/macros.h @@ -1,14 +1,9 @@ #ifndef VOXEL_MACROS_H #define VOXEL_MACROS_H -#include +#include -// print_verbose() is used everywhere in the engine, but its drawback is that even if you turn it off, strings -// you print are still allocated and formatted, to not be used. This macro avoids the string. -#define ZN_PRINT_VERBOSE(msg) \ - if (is_verbose_output_enabled()) { \ - print_line(msg); \ - } +// Macros I couldn't put anywhere specific // TODO Waiting for a fix, Variant() can't be constructed from `size_t` on JavaScript and OSX builds. // See https://github.com/godotengine/godot/issues/36690 @@ -24,10 +19,4 @@ #define ZN_TTR(msg) msg #endif -namespace zylann { - -bool is_verbose_output_enabled(); - -} // namespace zylann - #endif // VOXEL_MACROS_H diff --git a/util/math/box3i.cpp b/util/math/box3i.cpp new file mode 100644 index 00000000..376a2e9f --- /dev/null +++ b/util/math/box3i.cpp @@ -0,0 +1,16 @@ +#include "box3i.h" +#include + +namespace zylann { + +std::stringstream &operator<<(std::stringstream &ss, const Box3i &box) { + // TODO For some reason the one-liner version didn't compile? + ss << "(o:"; + ss << box.pos; + ss << ", s:"; + ss << box.size; + ss << ")"; + return ss; +} + +} // namespace zylann diff --git a/util/math/box3i.h b/util/math/box3i.h index 8062e578..86e8fbf8 100644 --- a/util/math/box3i.h +++ b/util/math/box3i.h @@ -1,8 +1,8 @@ -#ifndef BOX3I_H -#define BOX3I_H +#ifndef ZYLANN_BOX3I_H +#define ZYLANN_BOX3I_H #include "vector3i.h" -#include +#include namespace zylann { @@ -70,10 +70,6 @@ public: other_end.z <= end.z; } - String to_string() const { - return String("(o:{0}, s:{1})").format(varray(pos, size)); - } - bool intersects(const Box3i &other) const { if (pos.x >= other.pos.x + other.size.x) { return false; @@ -358,6 +354,8 @@ inline bool operator==(const Box3i &a, const Box3i &b) { return a.pos == b.pos && a.size == b.size; } +std::stringstream &operator<<(std::stringstream &ss, const Box3i &box); + } // namespace zylann -#endif // BOX3I_H +#endif // ZYLANN_BOX3I_H diff --git a/util/math/vector3i.cpp b/util/math/vector3i.cpp new file mode 100644 index 00000000..93f5e70e --- /dev/null +++ b/util/math/vector3i.cpp @@ -0,0 +1,7 @@ +#include "vector3i.h" +#include + +std::stringstream &operator<<(std::stringstream &ss, const Vector3i &v) { + ss << "(" << v.x << ", " << v.y << ", " << v.z << ")"; + return ss; +} diff --git a/util/math/vector3i.h b/util/math/vector3i.h index dba1e185..7e0ec727 100644 --- a/util/math/vector3i.h +++ b/util/math/vector3i.h @@ -5,7 +5,7 @@ #include "funcs.h" #include #include -#include +#include #if VOXEL_CUSTOM_VECTOR3I struct Vector3i { @@ -366,6 +366,8 @@ inline Vector3i operator&(const Vector3i &a, uint32_t b) { #endif // VOXEL_CUSTOM_VECTOR3I +std::stringstream &operator<<(std::stringstream &ss, const Vector3i &v); + // For Godot struct Vector3iHasher { static _FORCE_INLINE_ uint32_t hash(const Vector3i &v) {