Skip to content

Commit

Permalink
Moved file_utils to utils
Browse files Browse the repository at this point in the history
  • Loading branch information
Zylann committed Mar 26, 2024
1 parent feaf313 commit 4b4b2f7
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 77 deletions.
1 change: 1 addition & 0 deletions common.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ def get_sources(env, is_editor_build):
"util/godot/direct_mesh_instance.cpp",
"util/godot/direct_multimesh_instance.cpp",
"util/godot/direct_static_body.cpp",
"util/godot/file_utils.cpp",
"util/godot/shader_material_pool.cpp",

"util/io/*.cpp",
Expand Down
16 changes: 16 additions & 0 deletions streams/region/file_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef VOXEL_REGION_FILE_UTILS_H
#define VOXEL_REGION_FILE_UTILS_H

#include "../../engine/voxel_engine.h"
#include "../../util/godot/file_utils.h"

namespace zylann::voxel {

inline Error check_directory_created_with_file_locker(const String &fpath_base_dir) {
VoxelFileLockerWrite file_wlock(zylann::godot::to_std_string(fpath_base_dir));
return zylann::godot::check_directory_created(fpath_base_dir);
}

} // namespace zylann::voxel

#endif // VOXEL_REGION_FILE_UTILS_H
32 changes: 17 additions & 15 deletions streams/region/region_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "../../util/io/log.h"
#include "../../util/profiling.h"
#include "../../util/string_funcs.h"
#include "../file_utils.h"
#include "file_utils.h"
#include <algorithm>

namespace zylann::voxel {
Expand Down Expand Up @@ -69,7 +69,7 @@ bool save_header(
// `f` could be anywhere in the file, we seek to ensure we start at the beginning
f.seek(0);

godot::store_buffer(f, Span<const uint8_t>(reinterpret_cast<const uint8_t *>(FORMAT_REGION_MAGIC), 4));
zylann::godot::store_buffer(f, Span<const uint8_t>(reinterpret_cast<const uint8_t *>(FORMAT_REGION_MAGIC), 4));
f.store_8(version);

f.store_8(format.block_size_po2);
Expand Down Expand Up @@ -98,7 +98,7 @@ bool save_header(
}

// TODO Deal with endianess, this should be little-endian
godot::store_buffer(f,
zylann::godot::store_buffer(f,
Span<const uint8_t>(reinterpret_cast<const uint8_t *>(block_infos.data()),
block_infos.size() * sizeof(RegionBlockInfo)));

Expand All @@ -117,7 +117,8 @@ bool load_header(

FixedArray<char, 5> magic;
fill(magic, '\0');
ERR_FAIL_COND_V(godot::get_buffer(f, Span<uint8_t>(reinterpret_cast<uint8_t *>(magic.data()), 4)) != 4, false);
ERR_FAIL_COND_V(
zylann::godot::get_buffer(f, Span<uint8_t>(reinterpret_cast<uint8_t *>(magic.data()), 4)) != 4, false);
ERR_FAIL_COND_V(strcmp(magic.data(), FORMAT_REGION_MAGIC) != 0, false);

const uint8_t version = f.get_8();
Expand Down Expand Up @@ -163,7 +164,7 @@ bool load_header(

// TODO Deal with endianess
const size_t blocks_len = out_block_infos.size() * sizeof(RegionBlockInfo);
const size_t read_size = godot::get_buffer(f, Span<uint8_t>((uint8_t *)out_block_infos.data(), blocks_len));
const size_t read_size = zylann::godot::get_buffer(f, Span<uint8_t>((uint8_t *)out_block_infos.data(), blocks_len));
ERR_FAIL_COND_V(read_size != blocks_len, false);

return true;
Expand Down Expand Up @@ -193,20 +194,21 @@ Error RegionFile::open(const String &fpath, bool create_if_not_found) {
Error file_error;
// Open existing file for read and write permissions. This should not create the file if it doesn't exist.
// Note, there is no read-only mode supported, because there was no need for it yet.
Ref<FileAccess> f = godot::open_file(fpath, FileAccess::READ_WRITE, file_error);
Ref<FileAccess> f = zylann::godot::open_file(fpath, FileAccess::READ_WRITE, file_error);
if (file_error != OK) {
if (create_if_not_found) {
CRASH_COND(f != nullptr);

// Checking folders, needed for region "forests"
const CharString fpath_base_dir = fpath.get_base_dir().utf8();
const Error dir_err = check_directory_created_using_file_locker(fpath_base_dir.get_data());
const String fpath_base_dir = fpath.get_base_dir();
const Error dir_err = check_directory_created_with_file_locker(fpath_base_dir);

if (dir_err != OK) {
return ERR_CANT_CREATE;
}

// This time, we attempt to create the file
f = godot::open_file(fpath, FileAccess::WRITE_READ, file_error);
f = zylann::godot::open_file(fpath, FileAccess::WRITE_READ, file_error);
if (file_error != OK) {
ERR_PRINT(String("Failed to create file {0}").format(varray(fpath)));
return file_error;
Expand Down Expand Up @@ -386,7 +388,7 @@ Error RegionFile::save_block(Vector3i position, VoxelBuffer &block) {
ERR_FAIL_COND_V(!res.success, ERR_INVALID_PARAMETER);
f.store_32(res.data.size());
const unsigned int written_size = sizeof(uint32_t) + res.data.size();
godot::store_buffer(f, to_span(res.data));
zylann::godot::store_buffer(f, to_span(res.data));

const unsigned int end_pos = f.get_position();
CRASH_COND_MSG(written_size != (end_pos - block_offset),
Expand Down Expand Up @@ -433,7 +435,7 @@ Error RegionFile::save_block(Vector3i position, VoxelBuffer &block) {
f.seek(block_offset);

f.store_32(data.size());
godot::store_buffer(f, to_span(data));
zylann::godot::store_buffer(f, to_span(data));

const size_t end_pos = f.get_position();
CRASH_COND(written_size != (end_pos - block_offset));
Expand All @@ -451,7 +453,7 @@ Error RegionFile::save_block(Vector3i position, VoxelBuffer &block) {
f.seek(block_offset);

f.store_32(data.size());
godot::store_buffer(f, to_span(data));
zylann::godot::store_buffer(f, to_span(data));

const size_t end_pos = f.get_position();
CRASH_COND(written_size != (end_pos - block_offset));
Expand Down Expand Up @@ -522,11 +524,11 @@ void RegionFile::remove_sectors_from_block(Vector3i block_pos, unsigned int p_se
// Erase sectors from file
while (src_offset < old_end_offset) {
f.seek(src_offset);
const size_t read_bytes = godot::get_buffer(f, to_span(temp));
const size_t read_bytes = zylann::godot::get_buffer(f, to_span(temp));
CRASH_COND(read_bytes != sector_size); // Corrupted file

f.seek(dst_offset);
godot::store_buffer(f, to_span(temp));
zylann::godot::store_buffer(f, to_span(temp));

src_offset += sector_size;
dst_offset += sector_size;
Expand Down Expand Up @@ -587,7 +589,7 @@ bool RegionFile::migrate_from_v2_to_v3(FileAccess &f, RegionFormat &format) {
const unsigned int extra_bytes_needed = new_header_size - old_header_size;

f.seek(MAGIC_AND_VERSION_SIZE);
godot::insert_bytes(f, extra_bytes_needed);
zylann::godot::insert_bytes(f, extra_bytes_needed);

// Set version because otherwise `save_header` will attempt to migrate again causing stack-overflow
_header.version = FORMAT_VERSION;
Expand Down
4 changes: 2 additions & 2 deletions streams/region/voxel_stream_region_files.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "../../util/math/box3i.h"
#include "../../util/profiling.h"
#include "../../util/string_funcs.h"
#include "file_utils.h"

#include <algorithm>

Expand Down Expand Up @@ -290,8 +291,7 @@ zylann::godot::FileResult VoxelStreamRegionFiles::save_meta() {

// Make sure the directory exists
{
const CharString directory_path_utf8 = _directory_path.utf8();
Error err = check_directory_created_using_file_locker(directory_path_utf8.get_data());
const Error err = check_directory_created_with_file_locker(_directory_path);
if (err != OK) {
ERR_PRINT("Could not save meta");
return FILE_CANT_OPEN;
Expand Down
2 changes: 1 addition & 1 deletion streams/region/voxel_stream_region_files.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

#include "../../util/containers/fixed_array.h"
#include "../../util/containers/std_vector.h"
#include "../../util/godot/file_utils.h"
#include "../../util/thread/mutex.h"
#include "../file_utils.h"
#include "../voxel_stream.h"
#include "region_file.h"

Expand Down
49 changes: 6 additions & 43 deletions streams/file_utils.cpp → util/godot/file_utils.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "file_utils.h"
#include "../engine/voxel_engine.h"
#include "../util/containers/std_vector.h"
#include "../util/godot/classes/directory.h"
#include "../containers/std_vector.h"
#include "classes/directory.h"

namespace zylann::godot {

Expand All @@ -15,10 +14,6 @@ const char *to_string(FileResult res) {
return "Doesn't exist";
case FILE_UNEXPECTED_EOF:
return "Unexpected end of file";
case FILE_INVALID_MAGIC:
return "Invalid magic";
case FILE_INVALID_VERSION:
return "Invalid version";
case FILE_INVALID_DATA:
return "Invalid data";
default:
Expand All @@ -27,40 +22,17 @@ const char *to_string(FileResult res) {
}
}

FileResult check_magic_and_version(
FileAccess &f, uint8_t expected_version, const char *expected_magic, uint8_t &out_version) {
uint8_t magic[5] = { '\0' };
const size_t count = get_buffer(f, Span<uint8_t>(magic, 4));
if (count != 4) {
return FILE_UNEXPECTED_EOF;
}
for (int i = 0; i < 4; ++i) {
if (magic[i] != expected_magic[i]) {
return FILE_INVALID_MAGIC;
}
}

out_version = f.get_8();
if (out_version != expected_version) {
return FILE_INVALID_VERSION;
}

return FILE_OK;
}

Error check_directory_created(const StdString &p_directory_path) {
const String directory_path(p_directory_path.c_str());

Ref<DirAccess> d = open_directory(directory_path);
Error check_directory_created(const String &p_directory_path) {
Ref<DirAccess> d = open_directory(p_directory_path);

if (d.is_null()) {
ERR_PRINT("Could not access to filesystem");
return ERR_FILE_CANT_OPEN;
}

if (!directory_exists(**d, directory_path)) {
if (!directory_exists(**d, p_directory_path)) {
// Create if not exist
const Error err = d->make_dir_recursive(directory_path);
const Error err = d->make_dir_recursive(p_directory_path);
if (err != OK) {
ERR_PRINT("Could not create directory");
return err;
Expand Down Expand Up @@ -111,12 +83,3 @@ void insert_bytes(FileAccess &f, size_t count, size_t temp_chunk_size) {
}

} // namespace zylann::godot

namespace zylann::voxel {

Error check_directory_created_using_file_locker(const StdString &directory_path) {
VoxelFileLockerWrite file_wlock(directory_path);
return zylann::godot::check_directory_created(directory_path);
}

} // namespace zylann::voxel
25 changes: 9 additions & 16 deletions streams/file_utils.h → util/godot/file_utils.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#ifndef FILE_UTILS_H
#define FILE_UTILS_H
#ifndef ZN_GODOT_FILE_UTILS_H
#define ZN_GODOT_FILE_UTILS_H

#include "../util/godot/classes/file_access.h"
#include "../util/math/vector3i.h"
#include "../util/std_string.h"
#include "../math/vector3i.h"
#include "classes/file_access.h"
#include "core/string.h"

namespace zylann::godot {

Expand Down Expand Up @@ -35,27 +35,20 @@ inline void store_vec3u32(FileAccess &f, const Vector3i v) {
f.store_32(v.z);
}

enum FileResult {
enum FileResult { //
FILE_OK = 0,
FILE_CANT_OPEN,
FILE_DOES_NOT_EXIST,
FILE_UNEXPECTED_EOF,
FILE_INVALID_MAGIC,
FILE_INVALID_VERSION,
FILE_INVALID_DATA
};

const char *to_string(FileResult res);
FileResult check_magic_and_version(
FileAccess &f, uint8_t expected_version, const char *expected_magic, uint8_t &out_version);

Error check_directory_created(const String &p_directory_path);

void insert_bytes(FileAccess &f, size_t count, size_t temp_chunk_size = 512);

} // namespace zylann::godot

namespace zylann::voxel {
// Specific to voxel because it uses a global lock found only in VoxelServer
Error check_directory_created_using_file_locker(const StdString &directory_path);
} // namespace zylann::voxel

#endif // FILE_UTILS_H
#endif // ZN_GODOT_FILE_UTILS_H

0 comments on commit 4b4b2f7

Please sign in to comment.