diff --git a/.vscode/settings.json b/.vscode/settings.json index 6bc7f76..57bf6c7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,5 +1,9 @@ { "clang.cflags": [ + "-std=c11", + "-I${workspaceRoot}/include" + ], + "clang.cxxflags": [ "-std=c++17", "-I${workspaceRoot}/include" ] diff --git a/include/gp/exception.hpp b/include/gp/exception.hpp index e571b52..1acdd5e 100644 --- a/include/gp/exception.hpp +++ b/include/gp/exception.hpp @@ -1,6 +1,5 @@ #pragma once #include "gp_config.hpp" -#include namespace gp{ class runtime_error{ diff --git a/include/gp/function.hpp b/include/gp/function.hpp index ad52f32..25401c6 100644 --- a/include/gp/function.hpp +++ b/include/gp/function.hpp @@ -2,13 +2,134 @@ #include "gp/exception.hpp" #include "gp/algorithm/tmp_manip.hpp" #include "gp/algorithm/move.hpp" +#include "gp/algorithm/modifiers.hpp" namespace gp{ - - template + template class function; - template + template + class function{ + using fn_ptr = char*; + + using invoke_fn_t = ret (*)(fn_ptr, args&&...); + using condestruct_fn_t = void (*) (fn_ptr, fn_ptr); + using allocator_t = typename gp::either< + copy_allocator, + allocator, + gp::reference_wrapper + >::type; + + allocator_t alloc; + invoke_fn_t invokator; + condestruct_fn_t condestructor; + fn_ptr data_ptr; + size_t data_size; + + + template + static ret invoke(func* fn, args&&... fw_args) { + return (*fn)(gp::forward(fw_args)...); + } + + template + static void condestruct(func* dest, func* src) { + if(dest != nullptr) { + new (dest) func(*src); + } else { + src->~func(); + } + } + + static void nop_condestruct(char*, char*) { + return; + } + + public: +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnull-dereference" +#pragma gcc diagnostic push +#pragma gcc diagnostic ignored "-Wnull-dereference" + function(allocator_t alloc_v = gp::reference_wrapper{*reinterpret_cast(0)}) +#pragma gcc pop +#pragma clang pop + : alloc(alloc_v) + , invokator(nullptr) + , condestructor(nullptr) + , data_ptr(nullptr) + , data_size(0) + {} + + template + function(func f, allocator_t alloc_v) + : alloc(alloc_v) + , invokator(reinterpret_cast(invoke)) + , condestructor(reinterpret_cast(condestruct)) + , data_ptr((char*)((allocator&)alloc).allocate(sizeof(func))) + , data_size(sizeof(func)) + { + gp_config::assertion(data_ptr != nullptr, "allocator failed in function"); + if(data_ptr != nullptr) this->condestructor(data_ptr, reinterpret_cast(&f)); + } + + function(function const& rhs) + : alloc(rhs.alloc) + , invokator(rhs.invokator) + , condestructor(rhs.condestructor) + , data_ptr(rhs.data_size != 0 ? (char*)((allocator&)alloc).allocate(rhs.data_size) : nullptr) + , data_size(rhs.data_size) + { + gp_config::assertion(data_ptr != nullptr, "allocator failed in function"); + if( + data_ptr != nullptr + and rhs.data_ptr != nullptr + ) this->condestructor(data_ptr, rhs.data_ptr); + } + + function(function&& rhs) + : alloc(rhs.alloc) + , invokator(rhs.invokator) + , condestructor(rhs.condestructor) + , data_ptr(rhs.data_ptr) + , data_size(rhs.data_size) + { + rhs.data_ptr = nullptr; + } + + constexpr function(ret(*fn)(args...), allocator_t alloc_v = allocator_t{}) + : alloc(alloc_v) + , invokator(reinterpret_cast(invoke)) + , condestructor(nop_condestruct) + , data_ptr(reinterpret_cast(fn)) + , data_size(0) + {} + + ~function(){ + if(data_size == 0) { + return; + } + if(data_ptr != nullptr) { + condestructor(nullptr, data_ptr); + ((allocator&)alloc).deallocate(data_ptr); + data_ptr = nullptr; + } + } + + function& operator=(function&& rhs) { + gp::swap(alloc, rhs.alloc); + gp::swap(invokator, rhs.invokator); + gp::swap(condestructor, rhs.condestructor); + gp::swap(data_ptr,rhs.data_ptr); + gp::swap(data_size,rhs.data_size); + return *this; + } + + ret operator()(args&&... argv) { + return invokator(data_ptr, gp::forward(argv)...); + } + }; + + /*template class function{ struct virtual_callable { @@ -66,7 +187,7 @@ namespace gp{ state_t state{}; union{ virtual_callable* functor = nullptr; - char inplace[12]; + char inplace[16]; } self; public: @@ -211,6 +332,6 @@ namespace gp{ } } - }; + };*/ } \ No newline at end of file diff --git a/include/gp/indexed_array.hpp b/include/gp/indexed_array.hpp index 8d8874a..2080bfb 100644 --- a/include/gp/indexed_array.hpp +++ b/include/gp/indexed_array.hpp @@ -3,6 +3,8 @@ #include "gp_config.hpp" #include "gp/algorithm/move.hpp" #include "gp/iterator.hpp" +#include "gp/array.hpp" + namespace gp{ template class indexed_array{ @@ -10,7 +12,7 @@ namespace gp{ size_t available_indexes_top = 0; size_t remove_top = 0; - T data_table[_capacity]; + gp::array data_table; size_t available_indexes[_capacity]; size_t translation_table[_capacity]; size_t reverse_translation_table[_capacity]; @@ -30,7 +32,7 @@ namespace gp{ index = data_top; } - new(&data_table[data_top]) T(gp::move(value)); + new(&(data_table.as_buffer().template cast()[data_top])) T(gp::move(value)); translation_table[index] = data_top; reverse_translation_table[data_top] = index; @@ -49,9 +51,9 @@ namespace gp{ --data_top; if(v_idx < data_top) { size_t u_idx = reverse_translation_table[data_top]; - data_table[v_idx] = gp::move(data_table[data_top]); - ::operator delete(&data_table[data_top], &data_table[data_top]); - data_table[data_top].~T(); + data_table.as_buffer().template cast()[v_idx] = gp::move(data_table[data_top]); + ::operator delete(&data_table.as_buffer().template cast()[data_top], &(data_table.as_buffer().template cast()[data_top])); + data_table.as_buffer().template cast()[data_top].~T(); translation_table[u_idx] = v_idx; reverse_translation_table[v_idx] = u_idx; } @@ -96,22 +98,22 @@ namespace gp{ pointer_iterator begin() { - return data_table; + return data_table.as_buffer().template cast().begin(); } pointer_iterator end() { - return data_table+data_top; + return data_table.as_buffer().template cast().begin()+data_top; } const_pointer_iterator cbegin() { - return data_table; + return data_table.as_buffer().template cast().cbegin(); } const_pointer_iterator cend() { - return data_table+data_top; + return data_table.as_buffer().template cast().cbegin()+data_top; } size_t size() { @@ -124,7 +126,7 @@ namespace gp{ T& operator[](size_t idx) { gp_config::assertion(idx < data_top, "Bad indexed array access"); - return data_table[translation_table[idx]]; + return data_table.as_buffer().template cast()[translation_table[idx]]; } }; } \ No newline at end of file diff --git a/include/gp/math/fp_math.hpp b/include/gp/math/fp_math.hpp index a021b93..0275639 100644 --- a/include/gp/math/fp_math.hpp +++ b/include/gp/math/fp_math.hpp @@ -49,7 +49,7 @@ namespace gp{ float floor(float value) { static_assert(sizeof(float) == 4, "bad float size"); if( - value >= std::numeric_limits::max() + value >= 16777216 || value <= std::numeric_limits::min() || value != value ) { @@ -68,7 +68,7 @@ namespace gp{ double floor(double value) { static_assert(sizeof(double) == 8, "bad double size"); if( - value >= std::numeric_limits::max() + value >= 9007199254740992 || value <= std::numeric_limits::min() || value != value ) { diff --git a/include/gp/rendering/bmp_viewport.hpp b/include/gp/rendering/bmp_viewport.hpp index 5f63c42..b272dcd 100644 --- a/include/gp/rendering/bmp_viewport.hpp +++ b/include/gp/rendering/bmp_viewport.hpp @@ -9,12 +9,14 @@ #include namespace gp{ - template + template class bmp_viewport { + public: using src_t = typename gp::either)>, + gp::function), allocator>, gp::buffer> >::type; + private: src_t source; gp::vec2_g resolution; color_type get(int32_t x, int32_t y) { diff --git a/include/gp/rendering/renderer.hpp b/include/gp/rendering/renderer.hpp index fc5b362..9a43d61 100644 --- a/include/gp/rendering/renderer.hpp +++ b/include/gp/rendering/renderer.hpp @@ -4,6 +4,7 @@ #include "gp/function.hpp" #include "gp/algorithm/min_of.hpp" #include "gp/indexed_array.hpp" +#include "gp/allocator/buddy.hpp" using vec2 = gp::vec2_g<>; using vec3 = gp::vec3_g<>; @@ -27,8 +28,8 @@ struct render_point{ } }; -using sdf_t = gp::function; -using material_t = gp::function; +using sdf_t = gp::function>; +using material_t = gp::function>; class renderer { using g_t = gp_config::rendering::default_type; @@ -36,7 +37,8 @@ class renderer { public: gp::indexed_array scene_elements; gp::indexed_array materials; - material_t sky_box = [](vec3) -> color_t { return vec4{0,0,0,0};}; + gp::buddy<> allocator; + material_t sky_box; vec2 _resolution{128,64}; camera _camera{{0, 0, -1}, {0, 0, 0}}; vec2 _fov{90, 45}; @@ -44,9 +46,12 @@ public: distance_t projection_end = 50; size_t passes = 12; - renderer() = default; + renderer(gp::buffer allocation_buffer) + : allocator(allocation_buffer.begin().data, allocation_buffer.size()) + , sky_box{gp::reference_wrapper>{allocator}} + {} - render_point sdf(vec3 render_target) { + render_point sdf(vec3& render_target) { return gp::min_of( scene_elements.begin(), scene_elements.end(), @@ -56,6 +61,10 @@ public: ); } + auto& get_allocator() { + return allocator; + } + color_t render(vec2 pixel) { g_t depth = projection_start; vec3 target = _camera.normal; diff --git a/include/gp/ring_list.hpp b/include/gp/ring_list.hpp index 62b24b6..3c62204 100644 --- a/include/gp/ring_list.hpp +++ b/include/gp/ring_list.hpp @@ -5,7 +5,7 @@ #include "gp_config.hpp" namespace gp { - template + template class ring_list{ public: class explorer; diff --git a/include/gp/runtime.hpp b/include/gp/runtime.hpp new file mode 100644 index 0000000..e69de29 diff --git a/include/gp/variant.hpp b/include/gp/variant.hpp index 05a30f3..8b15df4 100644 --- a/include/gp/variant.hpp +++ b/include/gp/variant.hpp @@ -4,6 +4,7 @@ #include #include "gp_config.hpp" #include "gp/exception.hpp" +#include "gp/allocator/dummy.hpp" #include "gp/memory.hpp" #include "gp/function.hpp" @@ -14,7 +15,7 @@ namespace gp{ class fixed_variant{ std::size_t index = std::numeric_limits::max(); char buffer[max_size()]; - gp::function dtor = [](void*){}; + gp::function dtor = [](void*){}; static_assert(all_of_fixed_size::value, "not fixed"); public: template::value,int>::type> @@ -22,7 +23,7 @@ namespace gp{ : index{r_index_of::value} { new(buffer) U(value); - dtor = gp::function([](void* thing){((U*)thing)->~U();}); + dtor = gp::function([](void* thing){((U*)thing)->~U();}); } template::value,int>::type> @@ -30,7 +31,7 @@ namespace gp{ : index{r_index_of::value} { new(buffer) U(std::move(value)); - dtor = gp::function([](void* thing){((U*)thing)->~U();}); + dtor = gp::function([](void* thing){((U*)thing)->~U();}); } @@ -94,7 +95,7 @@ namespace gp{ } }; - template + /*template class variant{ std::size_t index = std::numeric_limits::max(); void* ptr; @@ -177,5 +178,5 @@ namespace gp{ return false; } } - }; + };*/ } \ No newline at end of file diff --git a/tests/math.cpp b/tests/math.cpp index 4d559a6..b6c1a09 100644 --- a/tests/math.cpp +++ b/tests/math.cpp @@ -44,42 +44,43 @@ struct render_test : public test_scaffold { virtual int run() { int res = 0; - renderer a; + gp::array allocation_buffer; + renderer a{allocation_buffer.as_buffer()}; a._resolution = vec2{128,64}; a.passes = 5; a.projection_end = 3; - a.sky_box = [](vec3) -> color_t { + a.sky_box = material_t([](vec3) -> color_t { color_t ret; ret.r() = 0.5; ret.g() = 0.5; ret.b() = 1; ret.a() = 1; return ret; - }; + }, a.get_allocator()); auto red = a.materials.push( - [&](vec3 p) -> color_t { + material_t([&](vec3 p) -> color_t { color_t ret; ret.r() = 1; ret.g() = 0; ret.b() = 0; ret.a() = 1; return ret; - } + }, a.get_allocator()) ); auto green = a.materials.push( - [&](vec3 p) -> color_t { + material_t([&](vec3 p) -> color_t { color_t ret; ret.r() = 0; ret.g() = 1; ret.b() = 0; ret.a() = 1; return ret; - } + }, a.get_allocator()) ); auto sphere = a.scene_elements.push( - [&](vec3 pos) -> render_point { + sdf_t([&](vec3 pos) -> render_point { auto l_sdf = gp::difference_sdf( gp::sphere_sdf({0.0,0.0,0.0}, 1.0), gp::sphere_sdf({-0.75,0.0,0.0}, 1.0) @@ -88,27 +89,28 @@ struct render_test : public test_scaffold { ret.distance = l_sdf(pos); ret.material = red; return ret; - } + }, a.get_allocator()) ); auto sphere2 = a.scene_elements.push( - [&](vec3 pos) -> render_point { + sdf_t([&](vec3 pos) -> render_point { auto l_sdf_b = gp::sphere_sdf({-0.75,0.0,0.0}, 1.0); render_point ret; ret.distance = l_sdf_b(pos); ret.material = green; return ret; - } + }, a.get_allocator()) ); a._camera.position = vec3{0, 0, -2}; a._camera.normal = vec3{0, 0, 1}; using pic_color = gp::vec4_g; + using viewport = gp::bmp_viewport>; - gp::bmp_viewport vp{ + viewport vp{ {128,64}, - [&](gp::vec2_g p) -> pic_color { + viewport::src_t{[&](gp::vec2_g p) -> pic_color { auto orig = a.render({(float)p.x,(float)p.y}); pic_color ret{}; ret.x = (uint8_t)(orig.x*255); @@ -116,7 +118,7 @@ struct render_test : public test_scaffold { ret.z = (uint8_t)(orig.z*255); ret.w = (uint8_t)(orig.w*255); return ret; - } + }, a.get_allocator()} }; gp::array* buff = new gp::array(); @@ -156,9 +158,13 @@ struct function_test : public test_scaffold { virtual int run() { int res = 0; - gp::function l_sdf_b{gp::sphere_sdf({0.0,0.0,0.0}, 1.0)}; + + gp::array allocation_buffer; + gp::buddy<> allocator{allocation_buffer.begin().data, allocation_buffer.size()}; + + gp::function> l_sdf_b{gp::sphere_sdf({0.0,0.0,0.0}, 1.0), allocator}; { - gp::function sdf{l_sdf_b}; + gp::function> sdf{l_sdf_b}; gp_config::assertion(l_sdf_b(vec3(0,0,0)) == -1 && sdf(vec3(0,0,0)) == -1, "Bad sdf"); }