Initial commit

This commit is contained in:
Mario Romero 2023-07-28 21:56:18 -04:00
commit 6073e7d3f6
36 changed files with 1106 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "vendor/bgfx.cmake"]
path = vendor/bgfx.cmake
url = https://github.com/bkaradzic/bgfx.cmake
[submodule "vendor/CrossWindow"]
path = vendor/CrossWindow
url = https://github.com/alaingalvan/CrossWindow

67
CMakeLists.txt Normal file
View File

@ -0,0 +1,67 @@
cmake_minimum_required(VERSION 3.14)
project(weasel)
include(cmake/bgfx_shaders.cmake)
set(SOURCE_FILES
weasel.hpp
core/app.hpp
core/app.cpp
core/event.hpp
core/event.cpp
ec/entity.hpp
ec/component.hpp
ec/comp/sprite_component.hpp
ec/comp/sprite_component.cpp
gfx/renderer.hpp
gfx/renderer.cpp
gfx/texture.hpp
gfx/vertex.hpp
util/color.hpp
util/color.cpp
util/n_ary_tree.hpp
util/n_ary_tree.tpp
util/vector.hpp
win/system_events.hpp
win/system_events.cpp
win/window.hpp
win/window.cpp
)
list(TRANSFORM SOURCE_FILES PREPEND src/)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_subdirectory(vendor/CrossWindow)
add_subdirectory(vendor/bgfx.cmake)
add_shader_cmd(
FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/gfx/shader/mesh/mesh.vsh
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader/mesh.vsh.bin
TYPE VERTEX)
add_shader_cmd(
FILE ${CMAKE_CURRENT_SOURCE_DIR}/src/gfx/shader/mesh/mesh.fsh
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/shader/mesh.fsh.bin
TYPE FRAGMENT)
add_custom_target(compile_shaders ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/shader/mesh.vsh.bin ${CMAKE_CURRENT_BINARY_DIR}/shader/mesh.fsh.bin)
add_library(weasel ${SOURCE_FILES})
target_include_directories(weasel PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src)
target_compile_features(weasel PUBLIC cxx_std_17)
target_link_libraries(weasel CrossWindow bgfx bx)
if(WIN32)
target_link_libraries(weasel
Dwmapi)
endif()
target_compile_definitions(CrossWindow PRIVATE _WIN32_WINNT=0x0A00)
add_subdirectory(examples)

57
cmake/bgfx_shaders.cmake Normal file
View File

@ -0,0 +1,57 @@
# Configure a command to compile a single shader
# add_shader_cmd(
# FILE file
# OUTPUT output
# TYPE type
#)
function (add_shader_cmd)
cmake_parse_arguments(SHADER "" "FILE;OUTPUT;TYPE;LANG" "" ${ARGN})
message(${SHADER_FILE} ${SHADER_OUTPUT} ${SHADER_TYPE} ${SHADER_LANG})
set(BGFX_PATH ${CMAKE_CURRENT_SOURCE_DIR}/vendor/bgfx.cmake/bgfx)
set(VARYING_DEF "C:/Users/romer/Documents/Projects/weasel/src/gfx/shader/varying.def.sc")
message("checking platform")
if(WIN32)
set(SHADERC_PLATFORM_ARG WINDOWS)
message("platform = " ${SHADERC_PLATFORM_ARG})
elseif(APPLE)
set(SHADERC_PLATFORM_ARG OSX)
elseif(UNIX)
set(SHADERC_PLATFORM_ARG LINUX)
endif()
# shaderc_parse(
# FILE filename
# OUTPUT filename
# FRAGMENT|VERTEX|COMPUTE
# ANDROID|ASM_JS|IOS|LINUX|NACL|OSX|WINDOWS
# [PROFILE profile]
# [O 0|1|2|3]
# [VARYINGDEF filename]
# [BIN2C filename]
# [INCLUDES include;include]
# [DEFINES include;include]
# [DEPENDS]
# [PREPROCESS]
# [RAW]
# [VERBOSE]
# [DEBUG]
# [DISASM]
# [WERROR]
# )
shaderc_parse(SHADERC_ARGS
FILE ${SHADER_FILE}
OUTPUT ${SHADER_OUTPUT}
${SHADER_TYPE}
${SHADERC_PLATFORM_ARG}
PROFILE ${SHADER_LANG}
VARYINGDEF ${VARYING_DEF}
INCLUDES ${BGFX_PATH}/src
)
list( APPEND SHADER_COMPILE_CMD shaderc ${SHADERC_ARGS} )
add_custom_command(
OUTPUT ${SHADER_OUTPUT}
COMMAND ${SHADER_COMPILE_CMD})
endfunction()

View File

@ -0,0 +1,6 @@
project(example_0_hello_world)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} weasel)
#target_link_directories(${PROJECT_NAME} ${CMAKE_SOURCE_DIR}/src)

View File

@ -0,0 +1,25 @@
#include <weasel.hpp>
class hello_world : public wsl::app {
public:
void init() override {
wsl::entity::entity e;
hierarchy.root.add_child(e);
hierarchy.root.add_child(e);
hierarchy.root.add_child(e);
hierarchy.root.child_at(0).add_child(e);
renderer.draw_test_triangle();
window.internal_window.get()->setSize(640,480);
}
void update() override {
renderer.draw();
}
};
int main() {
hello_world app;
app.start("Hello World", 640, 480);
return 0;
}

View File

@ -0,0 +1,5 @@
project(example_1_double_pendulum)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} weasel)

View File

@ -0,0 +1,30 @@
#include <weasel.hpp>
class double_pendulum : public wsl::app {
public:
void init() override {
wsl::entity::entity e;
hierarchy.root.add_child(e);
hierarchy.root.add_child(e);
hierarchy.root.add_child(e);
hierarchy.root.child_at(0).add_child(e);
renderer.queue_triangle(
wsl::vec2f{320.0f, 480.0f},
wsl::vec2f{0.0f, 0.0f},
wsl::vec2f{640.0f, 0.0f},
wsl::color::red
);
window.internal_window.get()->setSize(640,480);
}
void update() override {
renderer.draw();
}
};
int main() {
double_pendulum app;
app.start("Double Pendulum", 640, 480);
return 0;
}

2
examples/CMakeLists.txt Normal file
View File

@ -0,0 +1,2 @@
add_subdirectory(0_hello_world)
add_subdirectory(1_double_pendulum)

34
src/core/app.cpp Normal file
View File

@ -0,0 +1,34 @@
#include "core/app.hpp"
wsl::app::app() : renderer(&window), hierarchy(wsl::entity::entity{}) {}
void wsl::app::start(const char* title, unsigned int width,
unsigned int height) {
if (window.init(title, width, height) && renderer.init(wsl::gfx::api::opengl)) {
is_running = true;
window.events.quit.add_listener([&]() {
window.close();
is_running = false;
});
init();
init_entities();
while (is_running) {
renderer.clear(color::solid{0x00, 0x00, 0x00});
window.events.update();
update();
update_entities();
renderer.update();
}
} else
std::cout << "error opening window" << std::endl;
}
void wsl::app::init_entities() {
for (wsl::n_ary_tree<wsl::entity::entity>::node& leaf : hierarchy) {
std::cout << &leaf << ": " << leaf.value.uid << std::endl;
}
}
void wsl::app::update_entities() {
}

31
src/core/app.hpp Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include <iostream>
#include "gfx/renderer.hpp"
#include "win/window.hpp"
#include "util/n_ary_tree.hpp"
#include "ec/entity.hpp"
namespace wsl {
class app {
public:
app();
window window;
gfx::renderer renderer;
void start(const char* title, unsigned int width, unsigned int height);
wsl::n_ary_tree<wsl::entity::entity> hierarchy;
protected:
virtual void init() = 0;
virtual void update() = 0;
void init_entities();
void update_entities();
private:
bool is_running;
};
} // namespace wsl

13
src/core/event.cpp Normal file
View File

@ -0,0 +1,13 @@
#include "core/event.hpp"
void wsl::event::event::add_listener(std::function<void()> callback_fn) {
listeners.push_back(callback_fn);
}
void wsl::event::event::update() {
if (dispatch_condition()) dispatch();
}
void wsl::event::event::dispatch() {
for (std::function<void()> fn : listeners) fn();
}

33
src/core/event.hpp Normal file
View File

@ -0,0 +1,33 @@
#pragma once
#include <functional>
#include <vector>
namespace wsl {
namespace event {
class event {
public:
void add_listener(std::function<void()> callback_fn);
/**
* @brief Check if event meet the requirement to notify the listening
* functions
*/
void update();
protected:
virtual bool dispatch_condition() = 0;
private:
std::vector<std::function<void()>> listeners;
/**
* @brief Fire up the event and invoke the listening functions
*/
void dispatch();
};
} // namespace event
} // namespace wsl

View File

@ -0,0 +1,21 @@
#include <bgfx/bgfx.h>
#include <bx/math.h>
#include <fstream>
#include <memory>
#include <sstream>
#include <array>
#include "util/color.hpp"
#include "util/vector.hpp"
#include "win/window.hpp"
#include "sprite_component.hpp"
void wsl::entity::comp::sprite::init() {
//renderer.draw_sprite()
}
void wsl::entity::comp::sprite::update(double delta_time) {}
void wsl::entity::comp::sprite::render() {}

View File

@ -0,0 +1,24 @@
#pragma once
#include "ec/component.hpp"
#include "gfx/renderer.hpp"
namespace wsl {
namespace entity {
namespace comp {
class sprite : component {
public:
gfx::renderer renderer;
void init();
void update(double delta_time);
void render();
};
} // namespace comp
} // namespace entity
} // namespace wsl

16
src/ec/component.hpp Normal file
View File

@ -0,0 +1,16 @@
#pragma once
namespace wsl {
namespace entity {
class component {
public:
virtual void init() = 0;
virtual void update(double delta_time) = 0;
virtual void render() = 0;
};
} // namespace entity
} // namespace wsl

44
src/ec/entity.hpp Normal file
View File

@ -0,0 +1,44 @@
#pragma once
#include <memory>
#include <vector>
#include "ec/component.hpp"
namespace wsl {
namespace entity {
class entity {
public:
const unsigned long uid = get_new_uid();
static unsigned long get_new_uid() { return last_uid++; }
template <typename T, typename... Args>
void add_component(Args... args) {
components.push_back(std::make_shared<T>(args...));
}
void init() {
for (std::shared_ptr<component> component : components)
component->init();
}
void update(double delta_time) {
for (std::shared_ptr<component> component : components)
component->update(delta_time);
}
void render() {
for (std::shared_ptr<component> component : components)
component->render();
}
private:
inline static unsigned long last_uid = 0;
std::vector<std::shared_ptr<component>> components;
};
} // namespace entity
} // namespace wsl

146
src/gfx/renderer.cpp Normal file
View File

@ -0,0 +1,146 @@
#include "renderer.hpp"
bool wsl::gfx::renderer::init(api graphics_api) {
bgfx::Init bgfx_init;
bgfx_init.platformData.nwh = window->internal_window->getHwnd();
this->graphics_api = graphics_api;
bgfx_init.type = bgfx_renderer_type(graphics_api);
xwin::UVec2 window_size = window->internal_window->getWindowSize();
// bgfx_init.resolution.width = window_size.x;
// bgfx_init.resolution.height = window_size.y;
bgfx_init.resolution.width = 640;
bgfx_init.resolution.height = 480;
bgfx_init.resolution.reset = BGFX_RESET_VSYNC;
return bgfx::init(bgfx_init);
}
void wsl::gfx::renderer::clear(color::solid clear_color) {
bgfx::touch(0);
bgfx::setViewClear(0, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, clear_color,
1.0f, 0);
vec2u size = window->size();
bgfx::setViewRect(0, 0, 0, size.x, size.y);
}
void wsl::gfx::renderer::update() { bgfx::frame(); }
void wsl::gfx::renderer::draw() {
std::cout << "draw call" << std::endl;
vec2u size = window->size();
float view[16], proj[16];
bx::mtxIdentity(view);
bx::mtxOrtho(proj, 0.0f, size.x, 0.0f, size.y, -1.0f, 1.0f, 0.0f, false);
bgfx::setViewTransform(0, view, proj);
bgfx::setVertexBuffer(0, vbo, 0, 8);
bgfx::setIndexBuffer(ibo, 0, 3);
bgfx::setState(BGFX_STATE_DEFAULT);
bgfx::submit(0, program, 0, BGFX_DISCARD_ALL);
}
void wsl::gfx::renderer::queue_triangle(vec2f point_1, vec2f point_2,
vec2f point_3,
color::solid fill_color) {
bgfx::VertexLayout vertex_layout;
triangle = new gfx::vsh::triangle(
vec3f{320.0f, 480.0f, 0.0f}, (vec4f)(color::transparent)fill_color,
vec3f{0.0f, 0.0f, 0.0f}, (vec4f)(color::transparent)fill_color,
vec3f{640.0f, 0.0f, 0.0f}, (vec4f)(color::transparent)fill_color);
vertex_layout.begin(bgfx_renderer_type(graphics_api));
vertex_layout.add(bgfx::Attrib::Enum::Position, 3,
bgfx::AttribType::Enum::Float);
vertex_layout.add(bgfx::Attrib::Enum::Color0, 4,
bgfx::AttribType::Enum::Float);
vertex_layout.end();
vbo = create_vertex_buffer(triangle->vertices, triangle->size(), vertex_layout);
ibo = create_index_buffer(indices, sizeof(indices));
program =
bgfx::createProgram(load_shader("C:/Users/romer/Documents/Projects/"
"weasel/build/shader/mesh.vsh.bin"),
load_shader("C:/Users/romer/Documents/Projects/"
"weasel/build/shader/mesh.fsh.bin"),
false);
}
void wsl::gfx::renderer::queue_triangle(vec2f point_1, vec2f point_2,
vec2f point_3,
color::solid color_1, color::solid color_2,
color::solid color_3) {
bgfx::VertexLayout vertex_layout;
triangle = new gfx::vsh::triangle(
vec3f{320.0f, 480.0f, 0.0f}, (vec4f)(color::transparent)color_1,
vec3f{0.0f, 0.0f, 0.0f}, (vec4f)(color::transparent)color_2,
vec3f{640.0f, 0.0f, 0.0f}, (vec4f)(color::transparent)color_3);
vertex_layout.begin(bgfx_renderer_type(graphics_api));
vertex_layout.add(bgfx::Attrib::Enum::Position, 3,
bgfx::AttribType::Enum::Float);
vertex_layout.add(bgfx::Attrib::Enum::Color0, 4,
bgfx::AttribType::Enum::Float);
vertex_layout.end();
vbo = create_vertex_buffer(triangle->vertices, triangle->size(), vertex_layout);
ibo = create_index_buffer(indices, sizeof(indices));
program =
bgfx::createProgram(load_shader("C:/Users/romer/Documents/Projects/"
"weasel/build/shader/mesh.vsh.bin"),
load_shader("C:/Users/romer/Documents/Projects/"
"weasel/build/shader/mesh.fsh.bin"),
false);
}
bgfx::ShaderHandle wsl::gfx::renderer::load_shader(const std::string& path) {
std::ifstream ifs(path);
std::stringstream buffer;
buffer << ifs.rdbuf();
ifs.close();
std::cout << buffer.str() << std::endl;
return bgfx::createShader(
bgfx::copy(buffer.str().c_str(), buffer.str().size()));
}
bgfx::RendererType::Enum wsl::gfx::renderer::bgfx_renderer_type(api wsl_api) {
switch (graphics_api) {
case api::automatic:
return bgfx::RendererType::Enum::Count;
break;
case api::d3d11:
return bgfx::RendererType::Enum::Direct3D11;
break;
case api::d3d12:
return bgfx::RendererType::Enum::Direct3D12;
break;
case api::metal:
return bgfx::RendererType::Enum::Metal;
break;
case api::opengl:
return bgfx::RendererType::Enum::OpenGL;
break;
case api::opengles:
return bgfx::RendererType::Enum::OpenGLES;
break;
case api::vulkan:
return bgfx::RendererType::Enum::Vulkan;
break;
default:
return bgfx::RendererType::Enum::Noop;
break;
}
}
bgfx::IndexBufferHandle wsl::gfx::renderer::create_index_buffer(
const void* indices, std::size_t size) {
return bgfx::createIndexBuffer(bgfx::makeRef(indices, size));
}
bgfx::VertexBufferHandle wsl::gfx::renderer::create_vertex_buffer(
const void* vertices, std::size_t size, bgfx::VertexLayout layout) {
return bgfx::createVertexBuffer(bgfx::makeRef(vertices, size), layout);
}

70
src/gfx/renderer.hpp Normal file
View File

@ -0,0 +1,70 @@
#pragma once
#include <bgfx/bgfx.h>
#include <bx/math.h>
#include <array>
#include <fstream>
#include <memory>
#include <sstream>
#include "gfx/vertex.hpp"
#include "util/color.hpp"
#include "util/vector.hpp"
#include "win/window.hpp"
namespace wsl {
namespace gfx {
enum api {
automatic,
d3d11,
d3d12,
metal,
opengl,
opengles,
vulkan,
};
class renderer {
public:
renderer(window* window) : window(window) {}
window* window;
bool init(api graphics_api = api::automatic);
void clear(color::solid clear_color);
void update();
// void draw(bgfx::ProgramHandle program, bgfx::VertexBufferHandle vbo,
// bgfx::IndexBufferHandle ibo);
void draw();
void draw_test_triangle();
bgfx::ShaderHandle load_shader(const std::string& path);
void queue_triangle(vec2f point_1, vec2f point_2, vec2f point_3,
color::solid color);
bgfx::IndexBufferHandle create_index_buffer(const void* indices,
std::size_t size);
bgfx::VertexBufferHandle create_vertex_buffer(const void* vertices,
std::size_t size,
bgfx::VertexLayout layout);
private:
bgfx::RendererType::Enum bgfx_renderer_type(api wsl_api);
api graphics_api;
bgfx::VertexBufferHandle vbo;
bgfx::IndexBufferHandle ibo;
bgfx::ProgramHandle program;
gfx::vsh::triangle* triangle;
/*
*/
unsigned short indices[3] = {0, 1, 2};
};
} // namespace gfx
} // namespace wsl

View File

@ -0,0 +1,5 @@
$input v_color0, v_texcoord0
#include <bgfx_shader.sh>
void main() {
gl_FragColor = v_color0;
}

View File

@ -0,0 +1,9 @@
$input a_position, a_color0
$output v_color0, v_texcoord0
#include <bgfx_shader.sh>
void main() {
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0));
v_color0 = a_color0;
}

View File

@ -0,0 +1,10 @@
vec4 v_color0 : COLOR0 = vec4(1.0, 0.0, 0.0, 1.0);
vec4 v_color1 : COLOR1 = vec4(0.0, 1.0, 0.0, 1.0);
vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
vec3 v_normal : TEXCOORD1 = vec3(0.0, 1.0, 0.0);
vec3 a_position : POSITION;
vec3 a_normal : NORMAL0;
vec4 a_color0 : COLOR0;
vec4 a_color1 : COLOR1;
vec2 a_texcoord0 : TEXCOORD0;

9
src/gfx/texture.hpp Normal file
View File

@ -0,0 +1,9 @@
#include <weasel.hpp>
namespace wsl {
class texture {
void create_texture_from_file(const std::string& path);
private:
bgfx::TextureHandle internal_texture;
};
}

49
src/gfx/vertex.hpp Normal file
View File

@ -0,0 +1,49 @@
#pragma once
#include <memory>
#include <iostream>
#include "util/vector.hpp"
namespace wsl {
namespace gfx {
namespace vsh {
struct vertex {};
namespace vertex_types {
struct shape2d : vertex {
vec3f position;
vec4f color;
};
} // namespace vertex_types
template<typename T, int N>
struct shape {
T* vertices;
constexpr std::size_t size() {
std::cout << sizeof(T) * N;
return sizeof(T) * N;
};
};
struct triangle : shape<vertex_types::shape2d, 3> {
triangle(vec3f point_1, vec4f color_1, vec3f point_2, vec4f color_2,
vec3f point_3, vec4f color_3) {
vertices = new vertex_types::shape2d[3]{
vertex_types::shape2d{{}, point_1, color_1},
vertex_types::shape2d{{}, point_2, color_2},
vertex_types::shape2d{{}, point_3, color_3}};
}
~triangle() { delete vertices; }
};
} // namespace vsh
} // namespace gfx
} // namespace wsl

9
src/util/color.cpp Normal file
View File

@ -0,0 +1,9 @@
#include "util/color.hpp"
wsl::color::solid::operator wsl::color::transparent() const {
return transparent{red, green, blue, 0xFF};
}
wsl::color::solid::operator unsigned() const {
return static_cast<transparent>(*this);
}

54
src/util/color.hpp Normal file
View File

@ -0,0 +1,54 @@
#pragma once
#include "util/vector.hpp"
namespace wsl {
namespace color {
struct transparent;
struct solid {
unsigned char red;
unsigned char green;
unsigned char blue;
operator vec3<float>() {
return vec3<float>{static_cast<float>(red) / 255.0f,
static_cast<float>(green) / 255.0f,
static_cast<float>(blue) / 255.0f};
};
operator transparent() const;
operator unsigned() const;
};
struct transparent {
unsigned char red;
unsigned char green;
unsigned char blue;
unsigned char alpha;
operator vec4<float>() {
return vec4<float>{static_cast<float>(red) / 255.0f,
static_cast<float>(green) / 255.0f,
static_cast<float>(blue) / 255.0f,
static_cast<float>(alpha) / 255.0f};
};
operator solid() const { return solid{red, green, blue}; }
operator unsigned() const {
return ((red << 8 | green) << 8 | blue) << 8 | alpha;
}
};
static solid white{0xFF, 0xFF, 0xFF};
static solid black{0x00, 0x00, 0x00};
static solid red{0xFF, 0x00, 0x00};
static solid green{0x00, 0xFF, 0x00};
static solid blue{0x00, 0x00, 0xFF};
} // namespace color
} // namespace wsl

47
src/util/n_ary_tree.hpp Normal file
View File

@ -0,0 +1,47 @@
#pragma once
#include <list>
namespace wsl {
template <typename T>
class n_ary_tree {
public:
class node {
public:
node(node* parent, T value);
node* parent;
T value;
node& add_child(T value);
int children_count();
node& child_at(int index);
unsigned index_of(node& child);
private:
std::list<node> children;
};
class iterator {
public:
iterator(n_ary_tree<T>::node* node) : node_ptr(node) {}
iterator operator++();
node& operator*();
node* operator->();
bool operator==(const iterator& other);
bool operator!=(const iterator& other);
private:
n_ary_tree<T>::node* node_ptr;
};
n_ary_tree(T root_value);
node root;
iterator begin();
iterator end();
};
} // namespace wsl
#include "util/n_ary_tree.tpp"

99
src/util/n_ary_tree.tpp Normal file
View File

@ -0,0 +1,99 @@
#pragma once
template <typename T>
wsl::n_ary_tree<T>::node::node(n_ary_tree<T>::node* parent, T value)
: parent(parent), value(value) {}
template <typename T>
typename wsl::n_ary_tree<T>::node& wsl::n_ary_tree<T>::node::add_child(T value) {
children.push_back(node(this, value));
return children.back();
}
template <typename T>
int wsl::n_ary_tree<T>::node::children_count() {
return children.size();
}
template <typename T>
typename wsl::n_ary_tree<T>::node& wsl::n_ary_tree<T>::node::child_at(int index) {
typename std::list<n_ary_tree<T>::node>::iterator it = children.begin();
std::advance(it, index);
return *it;
}
template <typename T>
unsigned wsl::n_ary_tree<T>::node::index_of(n_ary_tree<T>::node& child) {
int i = 0;
for (node& child_i : children) {
if (&child == &child_i) return i;
i++;
}
throw std::invalid_argument("child not found");
}
template <typename T>
typename wsl::n_ary_tree<T>::iterator
wsl::n_ary_tree<T>::iterator::operator++() {
if (node_ptr->children_count() > 0) {
// Step down the tree
node_ptr = &node_ptr->child_at(0);
return *this;
} else if (node_ptr->parent) {
// If can't move right climb up till it can jump to its
// next brother node
int index = node_ptr->parent->index_of(*node_ptr);
while (index + 1 >= node_ptr->parent->children_count()) {
node_ptr = node_ptr->parent;
if (!node_ptr->parent) {
// Reached the end
node_ptr = nullptr;
return *this;
}
index = node_ptr->parent->index_of(*node_ptr);
}
// Move to the next brother node
node_ptr = &node_ptr->parent->child_at(index + 1);
return *this;
} else {
node_ptr = nullptr;
return *this;
}
}
template <typename T>
typename wsl::n_ary_tree<T>::node& wsl::n_ary_tree<T>::iterator::operator*() {
return *node_ptr;
}
template <typename T>
typename wsl::n_ary_tree<T>::node* wsl::n_ary_tree<T>::iterator::operator->() {
return node_ptr;
}
template <typename T>
bool wsl::n_ary_tree<T>::iterator::operator==(
const n_ary_tree<T>::iterator& other) {
return node_ptr == other.node_ptr;
}
template <typename T>
bool wsl::n_ary_tree<T>::iterator::operator!=(
const n_ary_tree<T>::iterator& other) {
return node_ptr != other.node_ptr;
}
template <typename T>
wsl::n_ary_tree<T>::n_ary_tree(T root_value)
: root(node(nullptr, root_value)) {}
template <typename T>
typename wsl::n_ary_tree<T>::iterator wsl::n_ary_tree<T>::begin() {
return &root;
}
template <typename T>
typename wsl::n_ary_tree<T>::iterator wsl::n_ary_tree<T>::end() {
return nullptr;
}

62
src/util/vector.hpp Normal file
View File

@ -0,0 +1,62 @@
#pragma once
namespace wsl {
template <typename T>
struct vec3;
template <typename T>
struct vec2 {
T x, y;
template <typename U>
operator vec2<U>() {
return vec2<U>{static_cast<U>(x), static_cast<U>(y)};
}
template <typename U>
operator vec3<U>() {
return vec3<U>{static_cast<U>(x), static_cast<U>(y), 0};
}
};
typedef vec2<float> vec2f;
typedef vec2<int> vec2i;
typedef vec2<unsigned> vec2u;
template <typename T>
struct vec3 {
T x, y, z;
template <typename U>
operator vec3<U>() {
return vec3<U>{static_cast<U>(x), static_cast<U>(y), static_cast<U>(z)};
}
operator vec2<T>() { return vec2<T>{x, y}; }
};
typedef vec3<float> vec3f;
typedef vec3<int> vec3i;
typedef vec3<unsigned> vec3u;
template <typename T>
struct vec4 {
T x, y, z, w;
template <typename U>
operator vec4<U>() {
return vec4<U>{static_cast<U>(x), static_cast<U>(y), static_cast<U>(z),
static_cast<U>(w)};
}
operator vec3<T>() { return vec3<T>{x, y, z}; }
operator vec2<T>() { return vec2<T>{x, y}; }
};
typedef vec4<float> vec4f;
typedef vec4<int> vec4i;
typedef vec4<unsigned> vec4u;
} // namespace wsl

5
src/weasel.hpp Normal file
View File

@ -0,0 +1,5 @@
#pragma once
#include "core/app.hpp"
#include "win/window.hpp"

14
src/win/system_events.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "win/system_events.hpp"
wsl::event::system_event::system_event(
std::shared_ptr<xwin::EventQueue>& event_queue_ptr)
: xwin_event_queue(event_queue_ptr) {}
wsl::event::quit::quit(std::shared_ptr<xwin::EventQueue>& event_queue_ptr)
: system_event(event_queue_ptr) {}
bool wsl::event::quit::dispatch_condition() {
if (std::shared_ptr<xwin::EventQueue> event_queue = xwin_event_queue.lock())
return event_queue->front().type == xwin::EventType::Close;
return false;
}

31
src/win/system_events.hpp Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include <CrossWindow/CrossWindow.h>
#include <iostream>
#include <memory>
#include "core/event.hpp"
namespace wsl {
namespace event {
class system_event : public event {
public:
system_event(std::shared_ptr<xwin::EventQueue>& event_queue_ptr);
protected:
std::weak_ptr<xwin::EventQueue> xwin_event_queue;
};
class quit : public system_event {
public:
quit(std::shared_ptr<xwin::EventQueue>& event_queue_ptr);
bool dispatch_condition() override;
};
} // namespace event
} // namespace wsl

33
src/win/window.cpp Normal file
View File

@ -0,0 +1,33 @@
#include "win/window.hpp"
wsl::window::window() { internal_window = std::make_shared<xwin::Window>(); }
bool wsl::window::init(const char* title, unsigned int width,
unsigned int height) {
xwin::WindowDesc desc;
desc.title = title;
desc.width = width;
desc.height = height;
return internal_window->create(desc, *events.internal_event_queue);
}
void wsl::window::close() { internal_window->close(); }
wsl::vec2u wsl::window::size() {
xwin::UVec2 size = internal_window->getWindowSize();
std::cout << size.x << ' ' << size.y << std::endl;
std::cout << internal_window->getDesc().width << ' ' << internal_window->getDesc().height << std::endl;
return vec2u{size.x, size.y};
}
wsl::window::events::events()
: internal_event_queue(std::make_shared<xwin::EventQueue>()),
quit(internal_event_queue) {}
void wsl::window::events::update() {
internal_event_queue->update();
while (!internal_event_queue->empty()) {
quit.update();
internal_event_queue->pop();
}
}

37
src/win/window.hpp Normal file
View File

@ -0,0 +1,37 @@
#pragma once
#include <CrossWindow/CrossWindow.h>
#include <bgfx/bgfx.h>
#include <memory>
#include "win/system_events.hpp"
#include "util/vector.hpp"
namespace wsl {
class window {
public:
window();
bool init(const char* title, unsigned int width, unsigned int height);
void close();
vec2u size();
class events {
public:
events();
void update();
std::shared_ptr<xwin::EventQueue> internal_event_queue;
event::quit quit;
};
events events;
std::shared_ptr<xwin::Window> internal_window;
};
} // namespace wsl

1
vendor/CrossWindow vendored Submodule

@ -0,0 +1 @@
Subproject commit 7fc3f3fcd1917a6e1da22b7d1c9880466fdcefaa

1
vendor/bgfx.cmake vendored Submodule

@ -0,0 +1 @@
Subproject commit 9426a2f44f8c4dad6c45a3b32111974feeb4ba58