添加外部内存数据源
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
#include <atomic>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
#ifdef RENDERIVE_WITH_GTEST
|
||||
#include <gtest/gtest.h>
|
||||
#endif
|
||||
#include "../src/renderive/base/property/Property.hpp"
|
||||
#include "../src/renderive/renderable/Renderable.hpp"
|
||||
#include "../src/renderive/scene/Scene.hpp"
|
||||
#include "../src/renderive/state/State_Strategy.hpp"
|
||||
struct Radio_State {
|
||||
struct Even_Validator {
|
||||
void operator()(const int& value) const {
|
||||
if (value % 2 != 0) {
|
||||
throw std::invalid_argument("buffer_count must be even");
|
||||
}
|
||||
}
|
||||
};
|
||||
Range_Value<int, 1, 65535> port{8080};
|
||||
Validated_Value<int, Even_Validator> buffer_count{2};
|
||||
int low_watermark{};
|
||||
int high_watermark{};
|
||||
};
|
||||
struct Radio_Base {
|
||||
Radio_Base(int id, std::string name) : id(id), name(std::move(name)) {}
|
||||
static void validate_state(const Radio_State& state) {
|
||||
if (state.low_watermark > state.high_watermark) {
|
||||
throw std::invalid_argument("low_watermark must not exceed high_watermark");
|
||||
}
|
||||
}
|
||||
int id;
|
||||
std::string name;
|
||||
};
|
||||
struct Demo_Renderable : Renderable_Base {
|
||||
explicit Demo_Renderable(Scene_Base& scene) : Renderable_Base(scene, {.cache_enabled = true}) {}
|
||||
void render(const Scene_Render_Context&) override {
|
||||
++render_count;
|
||||
}
|
||||
std::atomic<int> render_count{};
|
||||
};
|
||||
using Radio_Strategy = Double_State_Strategy<Radio_Base, Radio_State>;
|
||||
using Radio = Attach_State_Builder<Radio_Strategy, Radio_State>;
|
||||
int run_main_flow() {
|
||||
auto radio = Radio::Builder{}
|
||||
.set < &Radio_State::port > (9000)
|
||||
.set<&Radio_State::buffer_count>(8)
|
||||
.configure([](Radio_State& state) {
|
||||
state.low_watermark = 16;
|
||||
state.high_watermark = 64;
|
||||
})
|
||||
.build(1, "primary");
|
||||
radio->set < &Radio_State::port > (9100);
|
||||
radio->publish();
|
||||
Scene2D_Context<> scene;
|
||||
auto renderable = std::make_shared<Demo_Renderable>(scene);
|
||||
scene.attach_renderable(renderable);
|
||||
scene.render();
|
||||
scene.wait_for_render();
|
||||
const auto& state = radio->render_use_state();
|
||||
std::cout << radio->id << ' ' << radio->name << ' ' << state.port.get() << ' ' << state.buffer_count.get() << ' ' << renderable->render_count.load() << ' ' << scene.frame_control.frequency_hz() << '\n';
|
||||
return 0;
|
||||
}
|
||||
int main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) {
|
||||
#ifdef RENDERIVE_WITH_GTEST
|
||||
if (argc > 1 && std::string(argv[1]) == "--gtest") {
|
||||
--argc;
|
||||
++argv;
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
#endif
|
||||
return run_main_flow();
|
||||
}
|
||||
@@ -9,5 +9,7 @@ TEST(color_cache_test, composites_source_values_in_order) {
|
||||
second.append(2);
|
||||
result.composite(first);
|
||||
result.composite(second);
|
||||
EXPECT_EQ(result.values, (std::vector<std::uint64_t>{1, 2}));
|
||||
EXPECT_EQ(result.values.size(), 2);
|
||||
EXPECT_EQ(result.values.at(0), 1);
|
||||
EXPECT_EQ(result.values.at(1), 2);
|
||||
}
|
||||
|
||||
@@ -29,5 +29,7 @@ TEST(scene2d_render_order_test, separates_dependency_order_from_display_order) {
|
||||
scene.render();
|
||||
scene.wait_for_render();
|
||||
EXPECT_EQ(state.render_order, (std::vector<std::uint64_t>{1, 2}));
|
||||
EXPECT_EQ(scene.final_color_cache.values, (std::vector<std::uint64_t>{2, 1}));
|
||||
EXPECT_EQ(scene.final_color_cache.values.size(), 2);
|
||||
EXPECT_EQ(scene.final_color_cache.values.at(0), 2);
|
||||
EXPECT_EQ(scene.final_color_cache.values.at(1), 1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <memory_resource>
|
||||
#include <vector>
|
||||
#include "renderive/base/property/Property.hpp"
|
||||
#include "renderive/real_time_data/Real_Time_Data.hpp"
|
||||
#include "renderive/renderable/Renderable.hpp"
|
||||
#include "renderive/scene/Scene.hpp"
|
||||
class Scene_Memory_Resource_Test_Resource : public std::pmr::memory_resource {
|
||||
public:
|
||||
std::size_t allocation_count() const noexcept {
|
||||
return allocation_count_.load(std::memory_order_acquire);
|
||||
}
|
||||
std::size_t deallocation_count() const noexcept {
|
||||
return deallocation_count_.load(std::memory_order_acquire);
|
||||
}
|
||||
private:
|
||||
void* do_allocate(std::size_t bytes, std::size_t alignment) override {
|
||||
allocation_count_.fetch_add(1, std::memory_order_release);
|
||||
return std::pmr::new_delete_resource()->allocate(bytes, alignment);
|
||||
}
|
||||
void do_deallocate(void* pointer, std::size_t bytes, std::size_t alignment) override {
|
||||
deallocation_count_.fetch_add(1, std::memory_order_release);
|
||||
std::pmr::new_delete_resource()->deallocate(pointer, bytes, alignment);
|
||||
}
|
||||
bool do_is_equal(const std::pmr::memory_resource& other) const noexcept override {
|
||||
return this == &other;
|
||||
}
|
||||
std::atomic<std::size_t> allocation_count_{};
|
||||
std::atomic<std::size_t> deallocation_count_{};
|
||||
};
|
||||
struct Scene_Memory_Resource_Test_Renderable : Renderable_Base {
|
||||
explicit Scene_Memory_Resource_Test_Renderable(Scene_Base& scene) : Renderable_Base(scene, {.cache_enabled = false}) {}
|
||||
void build_task_graph(Renderable_Task_Graph& graph) override {
|
||||
auto first = graph.emplace([](const Scene_Render_Context&) {}, "prepare_memory_resource_test");
|
||||
auto second = graph.emplace([](const Scene_Render_Context&) {}, "render_memory_resource_test");
|
||||
graph.precede(first, second);
|
||||
}
|
||||
};
|
||||
struct Scene_Memory_Resource_Test_Product {
|
||||
explicit Scene_Memory_Resource_Test_Product(int value) : value(value) {}
|
||||
int value;
|
||||
};
|
||||
struct Scene_Memory_Resource_Test_Properties {
|
||||
int value{};
|
||||
};
|
||||
struct Scene_Memory_Resource_Test_Property_Product {
|
||||
Scene_Memory_Resource_Test_Property_Product(const Scene_Memory_Resource_Test_Properties& properties, int offset) : value(properties.value + offset) {}
|
||||
int value;
|
||||
};
|
||||
TEST(scene_memory_resource_test, propagates_thread_safe_scene_memory_domain) {
|
||||
Scene_Memory_Resource_Test_Resource upstream;
|
||||
Scene2D_Context<> scene(upstream);
|
||||
EXPECT_EQ(&scene.upstream_memory_resource(), &upstream);
|
||||
EXPECT_NE(&scene.memory_resource(), &upstream);
|
||||
auto factory_renderable = scene.make_renderable<Scene_Memory_Resource_Test_Renderable>();
|
||||
auto independent_renderable = std::make_shared<Scene_Memory_Resource_Test_Renderable>(scene);
|
||||
EXPECT_EQ(&factory_renderable->memory_resource(), &scene.memory_resource());
|
||||
EXPECT_EQ(&independent_renderable->memory_resource(), &scene.memory_resource());
|
||||
scene.attach_renderable(factory_renderable);
|
||||
scene.attach_renderable(independent_renderable);
|
||||
scene.render();
|
||||
scene.wait_for_render();
|
||||
EXPECT_GT(upstream.allocation_count(), 0);
|
||||
}
|
||||
TEST(scene_memory_resource_test, keeps_factory_memory_domain_alive_until_renderable_release) {
|
||||
Scene_Memory_Resource_Test_Resource upstream;
|
||||
std::shared_ptr<Scene_Memory_Resource_Test_Renderable> renderable;
|
||||
{
|
||||
Scene2D_Context<> scene(upstream);
|
||||
renderable = scene.make_renderable<Scene_Memory_Resource_Test_Renderable>();
|
||||
renderable->task_graph();
|
||||
}
|
||||
renderable.reset();
|
||||
EXPECT_GT(upstream.deallocation_count(), 0);
|
||||
}
|
||||
TEST(scene_memory_resource_test, supports_independent_resource_aware_components) {
|
||||
Scene_Memory_Resource_Test_Resource memory_resource;
|
||||
Flow_Refresh_Strategy<Scene2D_Frame_Data> flow(memory_resource);
|
||||
{
|
||||
auto painter = flow.acquire_painter();
|
||||
EXPECT_TRUE(painter);
|
||||
}
|
||||
auto renderer = flow.acquire_renderer();
|
||||
EXPECT_TRUE(renderer);
|
||||
History_Real_Time_Data<int, std::pmr::vector<int>> history(memory_resource);
|
||||
history.update(1);
|
||||
history.update(2);
|
||||
EXPECT_EQ(history.size(), 2);
|
||||
Property_Builder<Scene_Memory_Resource_Test_Property_Product, Scene_Memory_Resource_Test_Properties> builder({3});
|
||||
auto product = builder.build_with_resource(memory_resource, 4);
|
||||
auto unique_product = builder.build_unique_with_resource(memory_resource, 5);
|
||||
EXPECT_EQ(product->value, 7);
|
||||
EXPECT_EQ(unique_product->value, 8);
|
||||
EXPECT_GT(memory_resource.allocation_count(), 0);
|
||||
}
|
||||
Reference in New Issue
Block a user