diff --git a/.vscode/settings.json b/.vscode/settings.json index b9a788b..176ac7e 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -52,6 +52,7 @@ "stdexcept": "cpp", "streambuf": "cpp", "cinttypes": "cpp", - "typeinfo": "cpp" + "typeinfo": "cpp", + "iostream": "cpp" } } diff --git a/README.md b/README.md index 9353881..abc78ab 100644 --- a/README.md +++ b/README.md @@ -90,3 +90,8 @@ Read like *spike*. - spaic The core runtime + +## Build Requirements + +- emsdk + [*install guide](https://emscripten.org/docs/getting_started/downloads.html) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 76c000c..bd9dc1b 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -20,5 +20,6 @@ foreach( source ${SOURCE_LIST} ) PRIVATE Spaic SpaicCSS + SpaicDOM ) endforeach( source ${SOURCE_LIST} ) \ No newline at end of file diff --git a/examples/Counter.cpp b/examples/Counter.cpp index 3d5b178..fc96f62 100644 --- a/examples/Counter.cpp +++ b/examples/Counter.cpp @@ -1,8 +1,10 @@ #include #include +#include #include #include +#include namespace props::counter { @@ -48,10 +50,23 @@ auto counter = create_component(props::counter::all, state::counter::all, update int main() { using namespace props::counter; - auto wtf_is_this_style = css( - width = 10.0_px); - auto rendered = counter(is_dark_theme = true)("Hello, world!", 1, 2.0); + auto node = counter(is_dark_theme = true)("Hello, world!", 1, 2.0); + std::string test = "12345678"; + std::vector test2; + test2.push_back("1"); + test2.push_back(2); + test2.push_back(3.0); + + std::cout << spaic::dom::render(node) << std::endl; + std::cout << spaic::dom::render(nullptr) << std::endl; + std::cout << spaic::dom::render(NULL) << std::endl; + std::cout << spaic::dom::render(123456) << std::endl; + std::cout << spaic::dom::render(123.456) << std::endl; + std::cout << spaic::dom::render(true) << std::endl; + std::cout << spaic::dom::render(false) << std::endl; + std::cout << spaic::dom::render("WAAAY") << std::endl; + std::cout << spaic::dom::render(test2) << std::endl; return EXIT_SUCCESS; } diff --git a/include/spaic-dom/Render.hpp b/include/spaic-dom/Render.hpp new file mode 100644 index 0000000..a13e232 --- /dev/null +++ b/include/spaic-dom/Render.hpp @@ -0,0 +1,9 @@ +#pragma once + +#include +#include + +namespace spaic::dom +{ +std::string render(spaic::vnode::VNode node); +} \ No newline at end of file diff --git a/include/spaic/Component.hpp b/include/spaic/Component.hpp index c218ecf..2dc3fde 100644 --- a/include/spaic/Component.hpp +++ b/include/spaic/Component.hpp @@ -5,25 +5,41 @@ #include #include +namespace spaic::vnode +{ +class VNode; +} namespace spaic::comp { +using NativeNodeName = std::optional; -class ComponentNode +class ComponentParent { +public: + const NativeNodeName native_node_name; + const std::vector children; + + ComponentParent(NativeNodeName native_node_name, std::vector children); }; -class ComponentBody +class ComponentSingle { public: + const NativeNodeName native_node_name; + + ComponentSingle(NativeNodeName native_node_name); + template - ComponentNode operator()(T... children) noexcept; + ComponentParent operator()(T... children) noexcept; }; template class Component { public: - Component(); + const NativeNodeName native_node_name; + + Component(NativeNodeName native_node_name); template - ComponentBody operator()(T... args) noexcept; + ComponentSingle operator()(T... args) noexcept; }; } // namespace spaic::comp diff --git a/include/spaic/VNode.hpp b/include/spaic/VNode.hpp index 75a6937..b9ca3eb 100644 --- a/include/spaic/VNode.hpp +++ b/include/spaic/VNode.hpp @@ -7,11 +7,11 @@ namespace spaic::vnode { -// TODO: Array of VNode should be VNode. using VNodeBase = std::variant< - spaic::comp::ComponentBody, - spaic::comp::ComponentNode, + spaic::comp::ComponentSingle, + spaic::comp::ComponentParent, std::string, + const char *, std::nullptr_t, bool, short, @@ -34,16 +34,13 @@ using VNodeBase = std::variant< class VNode final { -private: - // I prefer `_value` - // wtf is that noexcept(noexcept()) - std::variant> _value; - public: + const std::variant> value; + template requires std::is_convertible_v, VNodeBase> || std::is_convertible_v, std::vector> - VNode(T &&v) noexcept(noexcept(std::is_constructible_v(v))>)) - : _value(std::forward(v)) {} + VNode(T &&v) noexcept(noexcept(std::is_constructible_v(v))>)) + : value(std::forward(v)) {} }; } // namespace spaic::vnode diff --git a/include/spaic/detail/Component.hpp b/include/spaic/detail/Component.hpp index ef9373d..110f47c 100644 --- a/include/spaic/detail/Component.hpp +++ b/include/spaic/detail/Component.hpp @@ -9,21 +9,21 @@ namespace spaic::comp { template -ComponentNode ComponentBody::operator()(T... children) noexcept +ComponentParent ComponentSingle::operator()(T... children) noexcept { - // TODO: ComponentBody::operator()(children) - return ComponentNode(); + // TODO: ComponentSingle::operator()(children) + return ComponentParent(this->native_node_name, {children...}); } template -Component::Component() +Component::Component(NativeNodeName native_node_name) : native_node_name(native_node_name) { } template template -ComponentBody Component::operator()(T... args) noexcept +ComponentSingle Component::operator()(T... args) noexcept { // TODO: Component::operator()(args) - return ComponentBody(); + return ComponentSingle(this->native_node_name); } } // namespace spaic::comp diff --git a/include/spaic/detail/ComponentPart.hpp b/include/spaic/detail/ComponentPart.hpp index 77b0b07..589c465 100644 --- a/include/spaic/detail/ComponentPart.hpp +++ b/include/spaic/detail/ComponentPart.hpp @@ -14,6 +14,6 @@ template Component create_component(Props props, StateSet state, Update update, Render render) { // TODO: create_component(props, state, update, render) - return Component(); + return Component(std::nullopt); } } // namespace spaic::comp diff --git a/src/spaic-dom/Render.cpp b/src/spaic-dom/Render.cpp new file mode 100644 index 0000000..e379666 --- /dev/null +++ b/src/spaic-dom/Render.cpp @@ -0,0 +1,90 @@ +#include +#include +#include +#include +#include +#include +#include + +namespace spaic::dom +{ + +template +struct overloaded : Ts... +{ + using Ts::operator()...; +}; +template +overloaded(Ts...)->overloaded; + +std::string render_base(spaic::vnode::VNodeBase node) +{ + std::ostringstream stream; + std::visit( + overloaded{ + [&](std::nullptr_t &arg) { + // do nothing, nullptr means empty string. + }, + [&](std::string &arg) { stream << arg; }, + [&](const char *&arg) { stream << arg; }, + [&](spaic::comp::ComponentParent &arg) { + if (arg.native_node_name) + { + stream << "<" << *arg.native_node_name << ">\n"; + } + for (const auto &child : arg.children) + { + stream << render(child) << "\n"; + } + if (arg.native_node_name) + { + stream << "\n"; + } + }, + [&](spaic::comp::ComponentSingle &arg) { stream << typeid(std::decay_t).name() << "(ComponentSingle)"; }, + [&](auto arg) { + using T = std::decay_t; + if constexpr (std::is_same_v) + { + stream << std::boolalpha << arg << std::noboolalpha; + } + else if constexpr (std::is_fundamental_v) + { + stream << arg; + } + else + { + stream << "비야네 당신은 틀렸어!" << typeid(T).name(); + } + }, + }, + node); + return stream.str(); +} +std::string render(spaic::vnode::VNode node) +{ + std::ostringstream stream; + std::visit( + [&](auto &&arg) { + // wtf is that fucking bitches + using T = std::decay_t; + if constexpr (std::is_same_v>) + { + for (const auto &element : arg) + { + stream << render(element); + } + } + else if constexpr (std::is_same_v) + { + stream << render_base(arg); + } + else + { + stream << "wtf is that you should report this: " << typeid(T).name(); + } + }, + node.value); + return stream.str(); +} +} // namespace spaic::dom \ No newline at end of file diff --git a/src/spaic-dom/Test.cpp b/src/spaic-dom/Test.cpp deleted file mode 100644 index e69de29..0000000 diff --git a/src/spaic/Component.cpp b/src/spaic/Component.cpp new file mode 100644 index 0000000..732cb96 --- /dev/null +++ b/src/spaic/Component.cpp @@ -0,0 +1,9 @@ +#include +#include + +namespace spaic::comp +{ +ComponentSingle::ComponentSingle(NativeNodeName native_node_name) : native_node_name(native_node_name) {} + +ComponentParent::ComponentParent(NativeNodeName native_node_name, std::vector children) : native_node_name(native_node_name), children(children) {} +} // namespace spaic::comp \ No newline at end of file