Skip to content

Commit

Permalink
version bump 1.0.4
Browse files Browse the repository at this point in the history
actually implemented the newline conversion
fixed vec2 and vec3 saving and loading to be 1 save call (1 separator at the end)
added new methods to cxio and cxstring.h
added more tests to persist to check vec2 and vec3
added support for vec and vec3 datatypes to import header
added tests for new import header implementations
  • Loading branch information
gk646 committed May 17, 2024
1 parent ef7c462 commit 3848e9f
Show file tree
Hide file tree
Showing 23 changed files with 287 additions and 330 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ set(BUILD_SHARED_LIBS ON CACHE BOOL "" FORCE) # Build as shared lib
option(RN_ENABLE_SANITIZER "Set to compile with adress sanitizer (MSVC)") # set(RN_ENABLE_SANITIZER ON)
option(RN_BUILD_TESTS "Set to compile the test executable") # set(RN_BUILD_TESTS ON)
option(RN_BUILD_RELEASE "Set to build the release archives") # set(RN_BUILD_RELEASE ON) # You don't really need this
set(RN_VERSION "1.0.3")
set(RN_VERSION "1.0.4")

# Compiler options for MSVC and GCC
include(cmake/CompilerOptions.cmake)
Expand All @@ -33,7 +33,7 @@ add_subdirectory(src/plugins)
add_subdirectory(src/import)

# Add all the dependencies to the executable
add_dependencies(raynodes BuiltIns QuestScript)
add_dependencies(raynodes BuiltIns QuestScript Logics)

if (RN_BUILD_TESTS)
enable_testing()
Expand Down
1 change: 0 additions & 1 deletion cmake/LoadInternalLibs.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,4 @@ include_directories(

add_subdirectory("${DEPENDENCIES_PATH}/raylib" raylib)


add_library(nativefiledialogs STATIC "${DEPENDENCIES_PATH}/tinyfiledialogs/tinyfiledialogs.c")
23 changes: 23 additions & 0 deletions cmake/PluginDefinition.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# This script expects PLUGIN_NAME and PLUGIN_FILES to be set before including it.

if(NOT DEFINED PLUGIN_NAME)
message(FATAL_ERROR "PLUGIN_NAME is not defined")
message("Use set(PLUGIN_NAME MyPlugin) to set the name")
endif()

if(NOT DEFINED PLUGIN_FILES)
message(FATAL_ERROR "PLUGIN_FILES is not defined")
message("Use set(PLUGIN_NAME MyPlugin) to set the name")

endif()

add_library(${PLUGIN_NAME} SHARED ${PLUGIN_FILES})

set_target_properties(${PLUGIN_NAME} PROPERTIES
PREFIX ""
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/plugins"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/plugins"
)

target_include_directories(${PLUGIN_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src/raynodes)
target_link_libraries(${PLUGIN_NAME} PRIVATE editor)
209 changes: 28 additions & 181 deletions src/external/cxstructs/include/cxutil/cxio.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,20 @@
#ifndef CXSTRUCTS_SRC_CXIO_H_
# define CXSTRUCTS_SRC_CXIO_H_

#include "../cxconfig.h"
# include "../cxconfig.h"
# include <cstring>

// Simple, readable and fast *symmetric* serialization structure with loading
// and saving. Each line is a concatenated list of values and separator SEPARATOR
// and saving. Each line is a concatenated list of values and a separator
// 13|3.145|This is a string|56|

// I didnt find a way around hard coding the separator...

// Using the CXX23 std::print() is about 10% slower

namespace cxstructs {

static constexpr int MAX_SECTION_SIZE = 16;
# define NEW_LINE_SUB '\036'

//-----------SHARED-----------//
namespace {
Expand Down Expand Up @@ -77,9 +79,17 @@ inline void io_save_newline(FILE* file) {
fputc('\n', file);
}

// Writes a string value to file
// Writes a string value to file, replacing newlines with the SEPARATOR
inline void io_save(FILE* file, const char* value) {
fprintf(file, "%s\037", value);
while (*value != '\0') {
if (*value == '\n') {
fputc(NEW_LINE_SUB, file); // Replace newline with SEPARATOR
} else {
fputc(*value, file); // Write the character as is
}
++value;
}
fputc('\037', file); // Add SEPARATOR at the end
}

// Writes an integer or enum property to the file
Expand All @@ -97,9 +107,13 @@ inline void io_save(FILE* file, const float value) {
fprintf(file, "%.3f\037", value);
}

// Writes three floats to the file
// Writes three floats to the file - separated by ";"
inline void io_save(FILE* file, const float value, const float value2, const float value3) {
fprintf(file, "%.3f\037%.3f\037%.3f\037", value, value2, value3);
fprintf(file, "%.6f;%.6f;%.6f\037", value, value2, value3);
}
// Writes three floats to the file - separated by ";"
inline void io_save(FILE* file, const float value, const float value2) {
fprintf(file, "%.6f;%.6f\037", value, value2);
}

// Buffers the given SaveFunc to memory so the file is only written if it
Expand Down Expand Up @@ -216,6 +230,7 @@ inline void io_load(FILE* file, std::string& s) {
//s.reserve(reserve_amount); // Dont need to reserve - string shouldnt allocate below 15 characters
char ch;
while (fread(&ch, 1, 1, file) == 1 && ch != '\037') {
if (ch == NEW_LINE_SUB) [[unlikely]] { ch = '\n'; }
s.push_back(ch);
}
while (ch != '\37' && fread(&ch, 1, 1, file) == 1) {}
Expand All @@ -226,6 +241,7 @@ inline int io_load(FILE* file, char* buffer, size_t buffer_size) {
int count = 0;
char ch;
while (count < buffer_size - 1 && fread(&ch, 1, 1, file) == 1 && ch != '\037') {
if (ch == NEW_LINE_SUB) [[unlikely]] { ch = '\n'; }
buffer[count++] = ch;
}
buffer[count] = '\0';
Expand All @@ -251,181 +267,12 @@ inline void io_load(FILE* file, float& f) {

// Directly load three floats from the file
inline void io_load(FILE* file, float& f, float& f2, float& f3) {
fscanf(file, "%f\037%f\037%f\037", &f, &f2, &f3);
}
} // namespace cxstructs

# ifdef CX_INCLUDE_TESTS
# include <chrono>
namespace cxtests {
using namespace cxstructs;
using namespace std::chrono;
static void benchMark() {
FILE* file;
const char* filename = "hello.txt";
constexpr int num = 1000;
int val = 5;
auto start_write = high_resolution_clock::now();
fopen_s(&file, filename, "wb");
if (file != nullptr) {
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
io_save(file, j);
}
io_save_newline(file);
}
fclose(file);
}
auto end_write = high_resolution_clock::now();
auto start_read = high_resolution_clock::now();

fopen_s(&file, filename, "rb");
if (file != nullptr) {
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
io_load(file, val);
}
}
fclose(file);
}
auto end_read = high_resolution_clock::now();
auto duration_write = duration_cast<milliseconds>(end_write - start_write).count();
auto duration_read = duration_cast<milliseconds>(end_read - start_read).count();
printf("Write time: %lld ms\n", duration_write);
printf("Read time: %lld ms\n", duration_read);
}
void test_save_load_string() {
const char* test_filename = "test_string.txt";
const char* original_string = "Hello, world!";
char buffer[256];

// Save
FILE* file = std::fopen(test_filename, "wb");
cxstructs::io_save(file, original_string);
cxstructs::io_save_newline(file);
std::fclose(file);

// Load
file = std::fopen(test_filename, "rb");
cxstructs::io_load(file, buffer, sizeof(buffer));
std::fclose(file);

// Assert
CX_ASSERT(std::strcmp(original_string, buffer) == 0, "String save/load failed");
}
void test_save_load_int() {
const char* test_filename = "test_int.txt";
const int original_int = 42;
int loaded_int;

// Save
FILE* file = std::fopen(test_filename, "wb");
cxstructs::io_save(file, original_int);
cxstructs::io_save_newline(file);
std::fclose(file);

// Load
file = std::fopen(test_filename, "rb");
cxstructs::io_load(file, loaded_int);
std::fclose(file);

// Assert
CX_ASSERT(original_int == loaded_int, "Int save/load failed");
fscanf(file, "%f;%f;%f\037", &f, &f2, &f3);
}
void test_save_load_float() {
const char* test_filename = "test_float.txt";
constexpr float original_float = 3.141;
float loaded_float;

// Save
FILE* file;
fopen_s(&file, test_filename, "wb");
cxstructs::io_save(file, original_float);
cxstructs::io_save_newline(file);
std::fclose(file);

// Load
fopen_s(&file, test_filename, "rb");
cxstructs::io_load(file, loaded_float);
std::fclose(file);

// Assert
CX_ASSERT(original_float == loaded_float, "Float save/load failed");
}
void delete_test_files() {
// List of test files to delete
const char* files[] = {"test_string.txt", "test_int.txt", "test_float.txt", "test_complex.txt", "hello.txt"};

// Iterate over the array and delete each file
for (const char* filename : files) {
if (std::remove(filename) != 0) {
perror("Error deleting file");
} else {
printf("%s deleted successfully.\n", filename);
}
}
// Directly load three floats from the file
inline void io_load(FILE* file, float& f, float& f2) {
fscanf(file, "%f;%f\037", &f, &f2);
}
void test_complex_save_load() {
const char* test_filename = "test_complex.txt";
const char* original_str1 = "TestString1";
const int original_int = 123;
const float original_float = 456.789f;
const char* original_str2 = "TestString2";

char buffer_str1[256];
int loaded_int = -1;
float loaded_float = -1;
std::string buffer_str2;
std::string hello;
std::string bye;
std::string hello2;

// Save complex data
FILE* file;
fopen_s(&file, test_filename, "wb");
if (file) {
cxstructs::io_save(file, original_str1);
cxstructs::io_save(file, original_int);
cxstructs::io_save(file, original_float);
cxstructs::io_save(file, original_str2);
cxstructs::io_save_newline(file);
io_save(file, "hello");
io_save(file, "bye");
io_save(file, "hello");
std::fclose(file);
}

// Load complex data
file = std::fopen(test_filename, "rb");
if (file) {
cxstructs::io_load(file, buffer_str1, sizeof(buffer_str1));
cxstructs::io_load(file, loaded_int);
cxstructs::io_load(file, loaded_float);
cxstructs::io_load(file, buffer_str2);
io_load_newline(file);
io_load(file, hello);
io_load(file, bye);
io_load(file, hello2);
std::fclose(file);
}
} // namespace cxstructs

// Assert all loaded data matches original
CX_ASSERT(std::strcmp(original_str1, buffer_str1) == 0, "String1 save/load failed");
CX_ASSERT(original_int == loaded_int, "Int save/load failed");
CX_ASSERT(std::fabs(original_float - loaded_float) < 0.001,
"Float save/load failed"); // Allow for slight floating-point inaccuracies
CX_ASSERT(std::strcmp(original_str2, buffer_str2.c_str()) == 0, "String2 save/load failed");
CX_ASSERT(hello == hello2, "");
CX_ASSERT(bye == "bye", "");
}
static void TEST_IO() {
benchMark();
test_save_load_float();
test_save_load_int();
test_save_load_string();
test_complex_save_load();
delete_test_files();
}
} // namespace cxtests
# endif
#endif // CXSTRUCTS_SRC_CXIO_H_

0 comments on commit 3848e9f

Please sign in to comment.