Skip to content

Commit 4d9cdfd

Browse files
authored
bump(UE) add version UE5.7, no changes necessary (#133)
bump(UE): to version 5.7 fix(snapshot): snapshot memory leak and choice tag storage refactor: removed warnings throughout the code base and removed memory leaks in test code.
1 parent 8b1fa8f commit 4d9cdfd

71 files changed

Lines changed: 1726 additions & 1407 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.clang-format-ignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
inkcpp_compiler/json.hpp

.github/workflows/build.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,20 @@ jobs:
118118
working-directory: ${{github.workspace}}/build
119119
shell: bash
120120
run: |
121+
cmake $GITHUB_WORKSPACE -DINKCPP_UNREAL_TARGET_VERSION="5.7" -DINKCPP_UNREAL=ON
122+
cmake --install . --config $BUILD_TYPE --prefix comp_unreal_5_7 --component unreal
121123
cmake $GITHUB_WORKSPACE -DINKCPP_UNREAL_TARGET_VERSION="5.6" -DINKCPP_UNREAL=ON
122124
cmake --install . --config $BUILD_TYPE --prefix comp_unreal_5_6 --component unreal
123125
cmake $GITHUB_WORKSPACE -DINKCPP_UNREAL_TARGET_VERSION="5.5" -DINKCPP_UNREAL=ON
124126
cmake --install . --config $BUILD_TYPE --prefix comp_unreal_5_5 --component unreal
125127
cmake $GITHUB_WORKSPACE -DINKCPP_UNREAL_TARGET_VERSION="5.4" -DINKCPP_UNREAL=ON
126128
cmake --install . --config $BUILD_TYPE --prefix comp_unreal_5_4 --component unreal
129+
- name: Upload UE 5.7
130+
if: ${{ matrix.unreal }}
131+
uses: actions/upload-artifact@v4
132+
with:
133+
name: unreal_5_7
134+
path: build/comp_unreal_5_7/
127135
- name: Upload UE 5.6
128136
if: ${{ matrix.unreal }}
129137
uses: actions/upload-artifact@v4

.github/workflows/release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,12 @@ jobs:
2626
run: |
2727
mkdir artifacts
2828
ID=$(gh run list -b master --limit 1 --json databaseId | jq '.[0].databaseId')
29-
gh run download $ID -D artifacts -n linux-cl -n linux-lib -n linux-clib -n unreal_5_6 -n unreal_5_5 -n unreal_5_4 -n macos-cl -n macos-lib -n macos-clib -n macos-arm-cl -n macos-arm-lib -n macos-arm-clib -n win64-cl -n win64-lib -n win64-clib -n python-package-distribution
29+
gh run download $ID -D artifacts -n linux-cl -n linux-lib -n linux-clib -n unreal_5_7 -n unreal_5_6 -n unreal_5_5 -n unreal_5_4 -n macos-cl -n macos-lib -n macos-clib -n macos-arm-cl -n macos-arm-lib -n macos-arm-clib -n win64-cl -n win64-lib -n win64-clib -n python-package-distribution
3030
mv artifacts/python-package-distribution dist
3131
- name: Zip
3232
working-directory: ${{github.workspace}}/artifacts
3333
run: |
34-
for f in linux-cl linux-lib linux-clib unreal_5_6 unreal_5_5 unreal_5_4 macos-cl macos-lib macos-clib macos-arm-cl macos-arm-lib macos-arm-clib win64-cl win64-lib win64-clib; do zip -r ../$f.zip $f; done
34+
for f in linux-cl linux-lib linux-clib unreal_5_7 unreal_5_6 unreal_5_5 unreal_5_4 macos-cl macos-lib macos-clib macos-arm-cl macos-arm-lib macos-arm-clib win64-cl win64-lib win64-clib; do zip -r ../$f.zip $f; done
3535
- name: List
3636
run: tree
3737
- name: Publish to PyPI
@@ -45,5 +45,5 @@ jobs:
4545
--repo="$GITHUB_REPOSITORY" \
4646
--title="${GITHUB_REPOSITORY#*/} ${tag#v}" \
4747
--generate-notes \
48-
"$tag" "linux-cl.zip" "linux-lib.zip" "linux-clib.zip" "unreal_5_6.zip" "unreal_5_5.zip" "unreal_5_4.zip" "macos-cl.zip" "macos-lib.zip" "macos-clib.zip" "win64-cl.zip" "macos-arm-cl.zip" "macos-arm-lib.zip" "macos-arm-clib.zip" "win64-lib.zip" "win64-clib.zip"
48+
"$tag" "linux-cl.zip" "linux-lib.zip" "linux-clib.zip" "unreal_5_7.zip" "unreal_5_6.zip" "unreal_5_5.zip" "unreal_5_4.zip" "macos-cl.zip" "macos-lib.zip" "macos-clib.zip" "win64-cl.zip" "macos-arm-cl.zip" "macos-arm-lib.zip" "macos-arm-clib.zip" "win64-lib.zip" "win64-clib.zip"
4949

.pre-commit-config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
repos:
22
- repo: https://github.com/pre-commit/mirrors-clang-format
3-
rev: v18.1.0
3+
rev: v18.1.8
44
hooks:
55
- id: clang-format
66
types_or: [c++, c, cuda]
7+
exclude: inkcpp_compiler/json.hpp
78

89
- repo: https://github.com/pre-commit/pre-commit-hooks
910
rev: v6.0.0

CMakeLists.txt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,17 @@ mark_as_advanced(PYBIND11_USE_CROSSCOMPILING)
4141
enable_testing()
4242

4343
# Project setup
44-
project(inkcpp VERSION 0.1.9)
44+
project(inkcpp VERSION 0.1.10)
4545
set(CMAKE_CXX_STANDARD 17)
4646
set(CMAKE_CXX_STANDARD_REQUIRED ON)
4747
set(CMAKE_INSTALL_LIBRARY_DIR lib)
4848
set(CMAKE_INSTALL_INCLUDE_DIR include)
49-
49+
if(MSVC)
50+
# disable: aligment problems non explicit switch case
51+
add_compile_options(/W4 /wd4820 /wd4061)
52+
else()
53+
add_compile_options(-Wall -Wextra -Wpedantic)
54+
endif()
5055
# Add subdirectories
5156
include(CMakeDependentOption)
5257
option(INKCPP_PY "Build python bindings" OFF)
@@ -62,14 +67,19 @@ set(INKCPP_INKLECATE
6267
set_property(CACHE INKCPP_INKLECATE PROPERTY STRINGS "NONE" "OS" "ALL")
6368
option(INKCPP_NO_RTTI
6469
"Disable real time type information depended code. Used to build without RTTI." OFF)
65-
option(INKCPP_NO_EXCEPTIONS "Used to build without support for exceptions, disables try/catch blocks and throws" OFF)
70+
option(INKCPP_NO_EXCEPTIONS
71+
"Used to build without support for exceptions, disables try/catch blocks and throws" OFF)
72+
option(INKCPP_NO_STD "Disables the use of C(++) std libs." OFF)
6673

6774
if(INKCPP_NO_RTTI)
6875
add_definitions(-DINKCPP_NO_RTTI)
6976
endif()
7077
if(INKCPP_NO_EXCEPTIONS)
7178
add_definitions(-DINKCPP_NO_EXCEPTIONS)
7279
endif()
80+
if(INKCPP_NO_STD)
81+
add_definitions(-DINKCPP_NO_STD)
82+
endif()
7383
string(TOUPPER "${INKCPP_INKLECATE}" inkcpp_inklecate_upper)
7484
if(inkcpp_inklecate_upper STREQUAL "ALL")
7585
FetchContent_MakeAvailable(inklecate_windows inklecate_mac inklecate_linux)

Documentation/cmake_example/main.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <ink/story.h>
55
#include <ink/compiler.h>
66

7+
#include <memory.h>
78
#include <iostream>
89

910
using namespace ink::runtime;
@@ -14,7 +15,7 @@ int main()
1415
{
1516
ink::compiler::run("test.ink.json", "test.bin");
1617
// Load ink binary story, generated from the inkCPP compiler
17-
story* myInk = story::from_file("test.bin");
18+
std::unique_ptr<story> myInk{story::from_file("test.bin")};
1819

1920
// Create a new thread
2021
runner thread = myInk->new_runner();
0 Bytes
Binary file not shown.

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ Alternativly is the latest version of the UE plugin can be downloaded from the [
4949
Place the content of this file at your plugin folder of your UE project and at the next start up it will be intigrated.
5050

5151

52-
A example project can be found [here](https://jbenda.github.io/inkcpp/unreal/InkCPP_DEMO.zip). And here the [Documentation](https://jbenda.github.io/inkcpp/html/group__unreal.html).
52+
A example project can be found [here](https://jbenda.github.io/inkcpp/unreal/InkCPP_DEMO.zip). And here the [Documentation](https://jbenda.github.io/inkcpp/html/group__unreal.html).
5353

5454
Code for the Unreal plugin is located in the `unreal` directory. In order to install it, run
5555
```sh
@@ -104,6 +104,7 @@ Instructions:
104104
#include <ink/story.h>
105105
#include <ink/runner.h>
106106
#include <ink/choice.h>
107+
#include <memory.h>
107108

108109
using namespace ink::runtime;
109110

@@ -112,7 +113,7 @@ int MyInkFunction(int a, int b) { return a + b; }
112113
...
113114

114115
// Load ink binary story, generated from the inkCPP compiler
115-
story* myInk = story::from_file("test.bin");
116+
std::unique_ptr<story> myInk{story::from_file("test.bin")};
116117

117118
// Create a new thread
118119
runner thread = myInk->new_runner();
@@ -208,6 +209,6 @@ The python bindnigs are defined in `inkcpp_python` subfolder.
208209
## Dependencies
209210
The compiler depends on Nlohmann's JSON library and the C++ STL.
210211

211-
The runtime does not depend on either. If `INK_ENABLE_STL` is defined then STL extensions are added such as stream operators and `std::string` support. If `INK_ENABLE_UNREAL`, then FStrings, Delegates and other Unreal classes will be supported.
212+
The runtime does not depend on either. If `INK_ENABLE_STL` is defined then STL extensions are added such as stream operators and `std::string` support. If `INK_ENABLE_UNREAL`, then FStrings, Delegates and other Unreal classes will be supported.
212213

213214
NOTE: There is still some lingering C standard library calls in the runtime. I will be guarding them with an `INK_ENABLE_CSTD` or something soon.

inkcpp/array.h

Lines changed: 58 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,29 @@
1515

1616
namespace ink::runtime::internal
1717
{
18-
template<typename T, bool dynamic, size_t initialCapacity>
18+
/** Managed array of objects.
19+
*
20+
* @tparam simple if the object has a trivial destructor, so delete[](char*) can be used instead of
21+
* calling the constructor.
22+
* @tparam dynamic if the memory should be allocated on the heap and grow if needed
23+
* @tparam initialCapacitiy number of elements to allocate at construction, if !dynamic, this is
24+
* allocated in place and can not be changed.
25+
*/
26+
template<typename T, bool dynamic, size_t initialCapacity, bool simple>
1927
class managed_array : public snapshot_interface
2028
{
2129
public:
2230
managed_array()
23-
: _static_data{}
24-
, _capacity{initialCapacity}
31+
: _capacity{initialCapacity}
2532
, _size{0}
33+
, _static_data{}
2634
{
2735
if constexpr (dynamic) {
28-
_dynamic_data = new T[initialCapacity];
36+
if constexpr (simple) {
37+
_dynamic_data = reinterpret_cast<T*>(new char[sizeof(T) * initialCapacity]);
38+
} else {
39+
_dynamic_data = new T[initialCapacity];
40+
}
2941
}
3042
}
3143

@@ -37,13 +49,25 @@ class managed_array : public snapshot_interface
3749
virtual ~managed_array()
3850
{
3951
if constexpr (dynamic) {
40-
delete[] _dynamic_data;
52+
if constexpr (simple) {
53+
delete[] reinterpret_cast<char*>(_dynamic_data);
54+
} else {
55+
delete[] _dynamic_data;
56+
}
4157
}
4258
}
4359

44-
const T& operator[](size_t i) const { return data()[i]; }
60+
const T& operator[](size_t i) const
61+
{
62+
inkAssert(i < _size, "Access array out of bounds, index %u in array of size %u", i, _size);
63+
return data()[i];
64+
}
4565

46-
T& operator[](size_t i) { return data()[i]; }
66+
T& operator[](size_t i)
67+
{
68+
inkAssert(i < _size, "Access array out of bounds, index %u in array of size %u", i, _size);
69+
return data()[i];
70+
}
4771

4872
const T* data() const
4973
{
@@ -75,9 +99,9 @@ class managed_array : public snapshot_interface
7599

76100
T& back() { return end()[-1]; }
77101

78-
const size_t size() const { return _size; }
102+
size_t size() const { return _size; }
79103

80-
const size_t capacity() const { return _capacity; }
104+
size_t capacity() const { return _capacity; }
81105

82106
T& push()
83107
{
@@ -146,7 +170,7 @@ class managed_array : public snapshot_interface
146170
ptr = snap_write(ptr, e, should_write);
147171
}
148172
}
149-
return ptr - data;
173+
return static_cast<size_t>(ptr - data);
150174
}
151175

152176
const unsigned char* snap_load(const unsigned char* ptr, const loader& loader)
@@ -170,10 +194,10 @@ class managed_array : public snapshot_interface
170194
}
171195

172196
private:
173-
if_t<dynamic, char, T> _static_data[dynamic ? 1 : initialCapacity];
174197
T* _dynamic_data = nullptr;
175198
size_t _capacity;
176199
size_t _size;
200+
if_t<dynamic, char, T> _static_data[dynamic ? 1 : initialCapacity];
177201
};
178202

179203
template<typename T, bool dynamic, size_t initialCapacity>
@@ -219,7 +243,7 @@ class managed_restorable_array : public managed_array<T, dynamic, initialCapacit
219243
bool should_write = data != nullptr;
220244
ptr += base::snap(ptr, snapper);
221245
ptr = base::snap_write(ptr, _last_size, should_write);
222-
return ptr - data;
246+
return static_cast<size_t>(ptr - data);
223247
}
224248

225249
const unsigned char* snap_load(const unsigned char* ptr, const snapshot_interface::loader& loader)
@@ -233,21 +257,30 @@ class managed_restorable_array : public managed_array<T, dynamic, initialCapacit
233257
size_t _last_size = 0;
234258
};
235259

236-
template<typename T, bool dynamic, size_t initialCapacity>
237-
void managed_array<T, dynamic, initialCapacity>::extend(size_t capacity)
260+
template<typename T, bool dynamic, size_t initialCapacity, bool simple>
261+
void managed_array<T, dynamic, initialCapacity, simple>::extend(size_t capacity)
238262
{
239263
static_assert(dynamic, "Can only extend if array is dynamic!");
240-
size_t new_capacity = capacity > _capacity ? capacity : 1.5f * _capacity;
264+
size_t new_capacity = capacity > _capacity ? capacity : _capacity + _capacity / 2U;
241265
if (new_capacity < 5) {
242266
new_capacity = 5;
243267
}
244-
T* new_data = new T[new_capacity];
268+
T* new_data = nullptr;
269+
if constexpr (simple) {
270+
new_data = reinterpret_cast<T*>(new char[sizeof(T) * new_capacity]);
271+
} else {
272+
new_data = new T[new_capacity];
273+
}
245274

246275
for (size_t i = 0; i < _capacity; ++i) {
247276
new_data[i] = _dynamic_data[i];
248277
}
249278

250-
delete[] _dynamic_data;
279+
if constexpr (simple) {
280+
delete[] reinterpret_cast<char*>(_dynamic_data);
281+
} else {
282+
delete[] _dynamic_data;
283+
}
251284
_dynamic_data = new_data;
252285
_capacity = new_capacity;
253286
}
@@ -459,15 +492,15 @@ class allocated_restorable_array final : public basic_restorable_array<T>
459492
T* new_buffer = new T[new_capacity];
460493
if (_buffer) {
461494
for (size_t i = 0; i < base::capacity(); ++i) {
462-
new_buffer[i] = _buffer[i];
495+
new_buffer[i] = _buffer[i];
463496
// copy temp
464-
new_buffer[i + base::capacity()] = _buffer[i + base::capacity()];
497+
new_buffer[i + n] = _buffer[i + base::capacity()];
465498
}
466499
delete[] _buffer;
467500
}
468-
for (size_t i = base::capacity(); i < new_capacity / 2; ++i) {
469-
new_buffer[i] = _initialValue;
470-
new_buffer[i + base::capacity()] = _nullValue;
501+
for (size_t i = base::capacity(); i < n; ++i) {
502+
new_buffer[i] = _initialValue;
503+
new_buffer[i + n] = _nullValue;
471504
}
472505

473506
_buffer = new_buffer;
@@ -489,7 +522,7 @@ class allocated_restorable_array final : public basic_restorable_array<T>
489522
};
490523

491524
template<typename T>
492-
inline size_t basic_restorable_array<T>::snap(unsigned char* data, const snapper& snapper) const
525+
inline size_t basic_restorable_array<T>::snap(unsigned char* data, const snapper&) const
493526
{
494527
unsigned char* ptr = data;
495528
bool should_write = data != nullptr;
@@ -500,12 +533,12 @@ inline size_t basic_restorable_array<T>::snap(unsigned char* data, const snapper
500533
ptr = snap_write(ptr, _array[i], should_write);
501534
ptr = snap_write(ptr, _temp[i], should_write);
502535
}
503-
return ptr - data;
536+
return static_cast<size_t>(ptr - data);
504537
}
505538

506539
template<typename T>
507540
inline const unsigned char*
508-
basic_restorable_array<T>::snap_load(const unsigned char* data, const loader& loader)
541+
basic_restorable_array<T>::snap_load(const unsigned char* data, const loader&)
509542
{
510543
auto ptr = data;
511544
ptr = snap_read(ptr, _saved);

inkcpp/avl_array.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@
4444

4545
#include "system.h"
4646

47-
#include <cstdint>
48-
4947
/**
5048
* \param Key The key type. The type (class) must provide a 'less than' and 'equal to' operator
5149
* \param T The Data type
@@ -72,7 +70,7 @@ class avl_array
7270
ink::runtime::internal::if_t<dynamic, std::int8_t*, std::int8_t[Size]> balance_;
7371
ink::runtime::internal::if_t<dynamic, child_type*, child_type[Size]> child_;
7472
size_type size_; // actual size
75-
size_t _capacity;
73+
size_type _capacity;
7674
size_type root_; // root node
7775
ink::runtime::internal::if_t<dynamic, size_type*, size_type[Fast ? Size : 1]> parent_;
7876

@@ -114,6 +112,12 @@ class avl_array
114112
return *this;
115113
}
116114

115+
tag_avl_array_iterator(const tag_avl_array_iterator& other)
116+
: instance_{other.instance_}
117+
, idx_{other.idx_}
118+
{
119+
}
120+
117121
inline bool operator==(const tag_avl_array_iterator& rhs) const { return idx_ == rhs.idx_; }
118122

119123
inline bool operator!=(const tag_avl_array_iterator& rhs) const { return ! (*this == rhs); }
@@ -130,7 +134,7 @@ class avl_array
130134
// returns unique number for each entry
131135
// the numbers are unique as long no operation are executed
132136
// on the avl
133-
inline size_t temp_identifier() const { return instance_->size() - idx_ - 1; }
137+
inline size_type temp_identifier() const { return instance_->size() - idx_ - 1; }
134138

135139
// preincrement
136140
tag_avl_array_iterator& operator++()
@@ -208,6 +212,9 @@ class avl_array
208212
delete[] val_;
209213
delete[] balance_;
210214
delete[] child_;
215+
if (parent_) {
216+
delete[] parent_;
217+
}
211218
}
212219
}
213220

@@ -257,7 +264,7 @@ class avl_array
257264

258265
void extend()
259266
{
260-
size_t new_size = _capacity * 1.5;
267+
size_type new_size = _capacity + _capacity / 2;
261268
if (new_size < 5) {
262269
new_size = 5;
263270
}

0 commit comments

Comments
 (0)