Commit for 2021.06.27 00-42-22.7z

This commit is contained in:
mrq 2021-06-27 00:42:00 -05:00
parent b513d322b5
commit 7fc997cc18
13 changed files with 593 additions and 697 deletions

View File

@ -84,8 +84,7 @@
"minima": [ null, -1.0, null ],
"maxima": [ null, 1.0, null ],
"current": [ null, 0, null ]
"current":[ null, 0, null ]
},
"settings": {
"fov" : 90,

View File

@ -8,24 +8,13 @@
#include <uf/utils/hook/hook.h>
#include <uf/utils/thread/thread.h>
#include <uf/utils/renderer/renderer.h>
#include <uf/utils/window/payloads.h>
bool client::ready = false;
bool client::terminated = false;
uf::Window client::window;
uf::Serializer client::config;
namespace pod {
namespace payloads {
struct windowMouseMoved {
std::string invoker = "";
pod::Vector2i delta;
pod::Vector2ui position;
pod::Vector2ui size;
int_fast8_t state;
};
}
}
void client::initialize() {
uf::IoStream::ncurses = true;
uf::renderer::device.window = &client::window;
@ -157,11 +146,16 @@ void client::tick() {
}
#endif
uf::hooks.call("window:Mouse.Moved", pod::payloads::windowMouseMoved{
.invoker = "client",
.delta = previous - current,
.position = current,
.size = size,
.state = 0
"window:Mouse.Moved",
"client",
{
pod::Vector2ui{ size.x, size.y },
},
{
current,
previous - current,
0
}
});
}
}

View File

@ -25,42 +25,41 @@ namespace spec {
std::queue<Event> m_events;
public:
// C-tors
/*virtual*/ void UF_API_CALL create( const spec::uni::Window::vector_t& size, const spec::uni::Window::title_t& title = L"Window" ) {} ;// = 0;
void create( const spec::uni::Window::vector_t& size, const spec::uni::Window::title_t& title = L"Window" ) {} ;// = 0;
// D-tors
/*virtual*/ void UF_API_CALL terminate();/* = 0;*/
void terminate();/* = 0;*/
// Gets
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getPosition() const;/* = 0;*/
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getSize() const;/* = 0;*/
/*virtual*/ size_t UF_API_CALL getRefreshRate() const;/* = 0;*/
spec::uni::Window::vector_t getPosition() const;/* = 0;*/
spec::uni::Window::vector_t getSize() const;/* = 0;*/
size_t getRefreshRate() const;/* = 0;*/
// Attribute modifiers
/*virtual*/ void UF_API_CALL setPosition( const spec::uni::Window::vector_t& position );/* = 0;*/
/*virtual*/ void UF_API_CALL centerWindow();/* = 0;*/
/*virtual*/ void UF_API_CALL setMousePosition( const spec::uni::Window::vector_t& position );/* = 0;*/
/*virtual*/ void UF_API_CALL setSize( const spec::uni::Window::vector_t& size );/* = 0;*/
/*virtual*/ void UF_API_CALL setTitle( const spec::uni::Window::title_t& title );/* = 0;*/
/*virtual*/ void UF_API_CALL setIcon( const spec::uni::Window::vector_t& size, uint8_t* pixels );/* = 0;*/
/*virtual*/ void UF_API_CALL setVisible( bool visibility );/* = 0;*/
/*virtual*/ void UF_API_CALL setCursorVisible( bool visibility );/* = 0;*/
/*virtual*/ void UF_API_CALL setKeyRepeatEnabled( bool state );/* = 0;*/
/*virtual*/ void UF_API_CALL setMouseGrabbed( bool state );/* = 0;*/
void setPosition( const spec::uni::Window::vector_t& position );/* = 0;*/
void centerWindow();/* = 0;*/
void setMousePosition( const spec::uni::Window::vector_t& position );/* = 0;*/
void setSize( const spec::uni::Window::vector_t& size );/* = 0;*/
void setTitle( const spec::uni::Window::title_t& title );/* = 0;*/
void setIcon( const spec::uni::Window::vector_t& size, uint8_t* pixels );/* = 0;*/
void setVisible( bool visibility );/* = 0;*/
void setCursorVisible( bool visibility );/* = 0;*/
void setKeyRepeatEnabled( bool state );/* = 0;*/
void setMouseGrabbed( bool state );/* = 0;*/
/*virtual*/ void UF_API_CALL requestFocus();/* = 0;*/
/*virtual*/ bool UF_API_CALL hasFocus() const;/* = 0;*/
void requestFocus();/* = 0;*/
bool hasFocus() const;/* = 0;*/
// Update
/*virtual*/ void UF_API_CALL processEvents();/* = 0;*/
/*
void UF_API_CALL pushEvent( const uf::ReadableHook::name_t& name, const uf::ReadableHook::argument_t& argument );
void UF_API_CALL pushEvent( const uf::OptimalHook::name_t& name, const uf::OptimalHook::argument_t& argument );
void UF_API_CALL pushEvent( const uf::ReadableHook::argument_t& serialized );
void UF_API_CALL pushEvent( const uf::OptimalHook::argument_t& userdata );
*/
void UF_API_CALL pushEvent( const uf::Hooks::name_t& name, const std::string& payload );
void UF_API_CALL pushEvent( const uf::Hooks::name_t& name, const ext::json::Value& payload );
void UF_API_CALL pushEvent( const uf::Hooks::name_t& name, const uf::Serializer& payload );
void UF_API_CALL pushEvent( const uf::Hooks::name_t& name, const uf::Hooks::argument_t& payload );
void UF_API_CALL pushEvent( const uf::Hooks::argument_t& payload );
bool UF_API_CALL pollEvents( bool block = false );
static bool UF_API_CALL isKeyPressed( const std::string& );
void processEvents();/* = 0;*/
void pushEvent( const uf::Hooks::name_t& name, const std::string& payload );
void pushEvent( const uf::Hooks::name_t& name, const ext::json::Value& payload );
void pushEvent( const uf::Hooks::name_t& name, const uf::Serializer& payload );
void pushEvent( const uf::Hooks::name_t& name, const uf::Hooks::argument_t& payload );
void pushEvent( const uf::Hooks::argument_t& payload );
template<typename T> void pushEvent( const uf::Hooks::name_t& name, const T& payload );
bool pollEvents( bool block = false );
static bool isKeyPressed( const std::string& );
};
}
}
}
#include "universal.inl"

View File

@ -0,0 +1,6 @@
template<typename T>
void spec::uni::Window::pushEvent( const uf::Hooks::name_t& name, const T& payload ) {
pod::Hook::userdata_t userdata;
userdata.create<T>( payload );
this->pushEvent( name, userdata );
}

View File

@ -169,15 +169,19 @@ pod::Transform<T>& /*UF_API*/ uf::transform::decode( const ext::json::Value& _js
// transform.position = uf::vector::decode<T, 3>(json["position"], transform.position);
// transform.scale = uf::vector::decode<T, 3>(json["scale"], transform.scale);
// transform.orientation = uf::vector::decode<T, 4>(json["orientation"], transform.orientation);
if ( ext::json::isArray(json["position"]) || ext::json::isObject(json["position"]) ) transform.position = uf::vector::decode<T, 3>(json["position"], transform.position);
if ( ext::json::isArray(json["scale"]) || ext::json::isObject(json["scale"]) ) transform.scale = uf::vector::decode<T, 3>(json["scale"], transform.scale);
if ( ext::json::isArray(json["orientation"]) || ext::json::isObject(json["orientation"]) ) transform.orientation = uf::vector::decode<T, 4>(json["orientation"], transform.orientation);
// if ( ext::json::isArray(json["position"]) || ext::json::isObject(json["position"]) )
transform.position = uf::vector::decode<T, 3>(json["position"], transform.position);
// if ( ext::json::isArray(json["scale"]) || ext::json::isObject(json["scale"]) )
transform.scale = uf::vector::decode<T, 3>(json["scale"], transform.scale);
// if ( ext::json::isArray(json["orientation"]) || ext::json::isObject(json["orientation"]) )
transform.orientation = uf::vector::decode<T, 4>(json["orientation"], transform.orientation);
if ( ext::json::isObject(json["rotation"]) && !ext::json::isNull(json["rotation"]["axis"]) && !ext::json::isNull(json["rotation"]["angle"]) ) {
pod::Vector3t<T> axis = uf::vector::decode<T, 3>(json["rotation"]["axis"]);
T angle = json["rotation"]["angle"].as<T>();
transform.orientation = uf::quaternion::axisAngle( axis, angle );
}
if ( ext::json::isArray(json["model"]) ) transform.model = uf::matrix::decode<T, 4, 4>(json["model"]);
// if ( ext::json::isArray(json["model"]) )
transform.model = uf::matrix::decode<T, 4, 4>(json["model"], transform.model);
return transform;
}
template<typename T>
@ -187,14 +191,18 @@ pod::Transform<T> /*UF_API*/ uf::transform::decode( const ext::json::Value& _jso
// transform.position = uf::vector::decode<T, 3>(json["position"], transform.position);
// transform.scale = uf::vector::decode<T, 3>(json["scale"], transform.scale);
// transform.orientation = uf::vector::decode<T, 4>(json["orientation"], transform.orientation);
if ( ext::json::isArray(json["position"]) || ext::json::isObject(json["position"]) ) transform.position = uf::vector::decode<T, 3>(json["position"], transform.position);
if ( ext::json::isArray(json["scale"]) || ext::json::isObject(json["scale"]) ) transform.scale = uf::vector::decode<T, 3>(json["scale"], transform.scale);
if ( ext::json::isArray(json["orientation"]) || ext::json::isObject(json["orientation"]) ) transform.orientation = uf::vector::decode<T, 4>(json["orientation"], transform.orientation);
// if ( ext::json::isArray(json["position"]) || ext::json::isObject(json["position"]) )
transform.position = uf::vector::decode<T, 3>(json["position"], transform.position);
// if ( ext::json::isArray(json["scale"]) || ext::json::isObject(json["scale"]) )
transform.scale = uf::vector::decode<T, 3>(json["scale"], transform.scale);
// if ( ext::json::isArray(json["orientation"]) || ext::json::isObject(json["orientation"]) )
transform.orientation = uf::vector::decode<T, 4>(json["orientation"], transform.orientation);
if ( ext::json::isObject(json["rotation"]) && !ext::json::isNull(json["rotation"]["axis"]) && !ext::json::isNull(json["rotation"]["angle"]) ) {
pod::Vector3t<T> axis = uf::vector::decode<T, 3>(json["rotation"]["axis"]);
T angle = json["rotation"]["angle"].as<T>();
transform.orientation = uf::quaternion::axisAngle( axis, angle );
}
if ( ext::json::isArray(json["model"]) ) transform.model = uf::matrix::decode<T, 4, 4>(json["model"]);
// if ( ext::json::isArray(json["model"]) )
transform.model = uf::matrix::decode<T, 4, 4>(json["model"], transform.model);
return transform;
}

View File

@ -407,11 +407,14 @@ pod::Vector<T,N>& /*UF_API*/ uf::vector::decode( const ext::json::Value& json, p
if ( ext::json::isArray(json) )
#pragma unroll // GCC unroll T::size
for ( uint_fast8_t i = 0; i < N; ++i )
v[i] = json[i].as<T>();
v[i] = json[i].as<T>(v[i]);
else if ( ext::json::isObject(json) ) {
uint_fast8_t i = 0;
ext::json::forEach(json, [&](const ext::json::Value& c){
if ( i < N ) v[i++] = uf::math::unquantize( c.as<T>() );
if ( i < N ) {
v[i] = uf::math::unquantize( c.as<T>(v[i]) );
++i;
}
});
}
return v;
@ -422,11 +425,14 @@ pod::Vector<T,N> /*UF_API*/ uf::vector::decode( const ext::json::Value& json, co
if ( ext::json::isArray(json) )
#pragma unroll // GCC unroll T::size
for ( uint_fast8_t i = 0; i < N; ++i )
v[i] = json[i].as<T>();
v[i] = json[i].as<T>(_v[i]);
else if ( ext::json::isObject(json) ) {
uint_fast8_t i = 0;
ext::json::forEach(json, [&](const ext::json::Value& c){
if ( i < N ) v[i++] = c.as<T>();
if ( i < N ) {
v[i] = c.as<T>(_v[i]);
++i;
}
});
}
return v;

View File

@ -0,0 +1,67 @@
#pragma once
#include <uf/config.h>
#include <string>
#include <uf/utils/math/vector.h>
namespace pod {
namespace payloads {
struct windowEvent {
std::string type = "";
std::string invoker = "";
};
struct windowResized : public windowEvent {
struct {
pod::Vector2ui size{};
} window;
};
struct windowFocusedChanged : public windowEvent {
struct {
int_fast8_t state{};
} window;
};
struct windowTextEntered : public windowEvent {
struct {
uint32_t utf32;
std::string unicode;
} text;
};
struct windowKey : public windowEvent {
struct {
std::string code;
uint32_t raw;
int_fast8_t state = -1;
bool async;
struct {
bool alt;
bool ctrl;
bool shift;
bool sys;
} modifier;
} key;
};
struct windowMouseWheel : public windowEvent {
struct {
pod::Vector2ui position{};
float delta = 0;
} mouse;
};
struct windowMouseClick : public windowEvent {
struct {
pod::Vector2i position = {};
pod::Vector2i delta = {};
std::string button = "";
int_fast8_t state = 0;
} mouse;
};
struct windowMouseMoved : public windowResized {
struct {
pod::Vector2ui position{};
pod::Vector2i delta{};
int_fast8_t state{};
} mouse;
};
}
}

View File

@ -17,44 +17,44 @@ namespace uf {
// C-tors
UF_API_CALL Window();
UF_API_CALL Window( const spec::uni::Window::vector_t& size, const spec::uni::Window::title_t& title = L"Window", const spec::Context::Settings& settings = spec::Context::Settings() );
/*virtual*/ void UF_API_CALL create( const spec::uni::Window::vector_t& size, const spec::uni::Window::title_t& title = L"Window", const spec::Context::Settings& settings = spec::Context::Settings() );
void UF_API_CALL create( const spec::uni::Window::vector_t& size, const spec::uni::Window::title_t& title = L"Window", const spec::Context::Settings& settings = spec::Context::Settings() );
// D-tors
/*virtual*/ ~Window();
/*virtual*/ void UF_API_CALL terminate();
~Window();
void UF_API_CALL terminate();
// Gets
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getPosition() const;
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getSize() const;
/*virtual*/ size_t UF_API_CALL getRefreshRate() const;
spec::uni::Window::vector_t UF_API_CALL getPosition() const;
spec::uni::Window::vector_t UF_API_CALL getSize() const;
size_t UF_API_CALL getRefreshRate() const;
// Attribute modifiers
/*virtual*/ void UF_API_CALL setPosition( const spec::uni::Window::vector_t& position );
/*virtual*/ void UF_API_CALL centerWindow();
/*virtual*/ void UF_API_CALL setMousePosition( const spec::uni::Window::vector_t& position );
/*virtual*/ spec::uni::Window::vector_t UF_API_CALL getMousePosition();
/*virtual*/ void UF_API_CALL setSize( const spec::uni::Window::vector_t& size );
/*virtual*/ void UF_API_CALL setTitle( const spec::uni::Window::title_t& title );
/*virtual*/ void UF_API_CALL setIcon( const spec::uni::Window::vector_t& size, uint8_t* pixels );
/*virtual*/ void UF_API_CALL setVisible( bool visibility );
/*virtual*/ void UF_API_CALL setCursorVisible( bool visibility );
/*virtual*/ void UF_API_CALL setKeyRepeatEnabled( bool state );
/*virtual*/ void UF_API_CALL setMouseGrabbed( bool state );
void UF_API_CALL setPosition( const spec::uni::Window::vector_t& position );
void UF_API_CALL centerWindow();
void UF_API_CALL setMousePosition( const spec::uni::Window::vector_t& position );
spec::uni::Window::vector_t UF_API_CALL getMousePosition();
void UF_API_CALL setSize( const spec::uni::Window::vector_t& size );
void UF_API_CALL setTitle( const spec::uni::Window::title_t& title );
void UF_API_CALL setIcon( const spec::uni::Window::vector_t& size, uint8_t* pixels );
void UF_API_CALL setVisible( bool visibility );
void UF_API_CALL setCursorVisible( bool visibility );
void UF_API_CALL setKeyRepeatEnabled( bool state );
void UF_API_CALL setMouseGrabbed( bool state );
/*virtual*/ void UF_API_CALL requestFocus();
/*virtual*/ bool UF_API_CALL hasFocus() const;
void UF_API_CALL requestFocus();
bool UF_API_CALL hasFocus() const;
static pod::Vector2ui UF_API_CALL getResolution();
/*virtual*/ void UF_API_CALL switchToFullscreen( bool borderless = false );
void UF_API_CALL switchToFullscreen( bool borderless = false );
// Update
#if defined(UF_USE_VULKAN) && UF_USE_VULKAN == 1
std::vector<std::string> getExtensions( bool validationEnabled = true );
void createSurface( VkInstance instance, VkSurfaceKHR& surface );
#endif
static bool focused;
static /*virtual*/ bool UF_API_CALL isKeyPressed(const std::string&);
/*virtual*/ void UF_API_CALL processEvents();
/*virtual*/ bool UF_API_CALL pollEvents(bool block = false);
/*virtual*/ bool UF_API_CALL setActive( bool active = true );
/*virtual*/ void UF_API_CALL display();
/*virtual*/ Window::window_t* UF_API_CALL getHandle();
/*virtual*/ const Window::window_t* UF_API_CALL getHandle() const;
static bool UF_API_CALL isKeyPressed(const std::string&);
void UF_API_CALL processEvents();
bool UF_API_CALL pollEvents(bool block = false);
bool UF_API_CALL setActive( bool active = true );
void UF_API_CALL display();
Window::window_t* UF_API_CALL getHandle();
const Window::window_t* UF_API_CALL getHandle() const;
};
}
#elif UF_USE_SFML

View File

@ -362,65 +362,52 @@ void UF_API_CALL spec::dreamcast::Window::processEvents() {
if ( ::mouse.device ) ::mouse.state = (mouse_state_t*) maple_dev_status(::mouse.device);
/* Key inputs */ if ( this->m_asyncParse ) {
std::vector<uint8_t> keys = GetKeys();
std::vector<WPARAM> keys = GetKeys();
pod::payloads::windowKey event{
"window:Key",
"os",
{
"",
0,
struct Event {
std::string type = "unknown";
std::string invoker = "???";
struct {
int state;
std::string code;
uint32_t raw;
bool async;
struct {
bool alt;
bool ctrl;
bool shift;
bool sys;
} modifier;
} key;
};
Event event; {
event.type = "window:Key";
event.invoker = "window";
event.key.state = -1;
event.key.code = "NULL";
event.key.raw = 0;
event.key.async = true;
event.key.modifier = {
.alt = GetModifier(KBD_MOD_LALT) || GetModifier(KBD_MOD_RALT),
.ctrl = GetModifier(KBD_MOD_LCTRL) || GetModifier(KBD_MOD_RCTRL),
.shift = GetModifier(KBD_MOD_LSHIFT) || GetModifier(KBD_MOD_RSHIFT),
.sys = GetModifier(KBD_MOD_S1) || GetModifier(KBD_MOD_S2),
};
}
/* Readable (JSON) + Optimal (Userdata) event */ {
uf::Serializer json;
/* Set up JSON data*/ {
json["type"] = event.type + "." + ((event.key.state == -1)?"Pressed":"Released");
json["invoker"] = event.invoker;
json["key"]["state"] = (event.key.state == -1) ? "Down" : "Up";
json["key"]["async"] = event.key.async;
json["key"]["modifier"]["alt"] = event.key.modifier.alt;
json["key"]["modifier"]["control"] = event.key.modifier.ctrl;
json["key"]["modifier"]["shift"] = event.key.modifier.shift;
json["key"]["modifier"]["system"] = event.key.modifier.sys;
}
/* Loop through key inputs */ {
for ( auto& key : keys ) {
auto code = GetKeyName(key);
event.key.code = code;
event.key.raw = key;
event.key.state = GetKeyState(key);
json["key"]["code"] = code;
json["key"]["raw"] = key;
this->pushEvent(event.type, json);
this->pushEvent(event.type + "." + code, json);
-1,
true,
{
GetModifier(KBD_MOD_LALT) || GetModifier(KBD_MOD_RALT),
GetModifier(KBD_MOD_LCTRL) || GetModifier(KBD_MOD_RCTRL),
GetModifier(KBD_MOD_LSHIFT) || GetModifier(KBD_MOD_RSHIFT),
GetModifier(KBD_MOD_S1) || GetModifier(KBD_MOD_S2),
}
}
};
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type + "." + ((event.key.state == -1)?"Pressed":"Released");
json["invoker"] = event.invoker;
json["key"]["code"] = "";
json["key"]["raw"] = 0;
json["key"]["state"] = (event.key.state == -1) ? "Down" : "Up";
json["key"]["async"] = event.key.async;
json["key"]["modifier"]["alt"] = event.key.modifier.alt;
json["key"]["modifier"]["control"] = event.key.modifier.ctrl;
json["key"]["modifier"]["shift"] = event.key.modifier.shift;
json["key"]["modifier"]["system"] = event.key.modifier.sys;
#endif
for ( auto& key : keys ) {
const auto code = GetKeyName(key);
event.key.code = code;
event.key.raw = key;
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
this->pushEvent(event.type + "." + code, event);
#endif
#if UF_USE_JSON
json["key"]["code"] = code;
json["key"]["raw"] = key;
this->pushEvent(event.type, json);
this->pushEvent(event.type + "." + code, json);
#endif
}
}
}
@ -435,22 +422,14 @@ bool UF_API_CALL spec::dreamcast::Window::pollEvents( bool block ) {
auto& event = this->m_events.front();
if ( event.payload.is<std::string>() ) {
ext::json::Value payload = uf::Serializer( event.payload.as<std::string>() );
// std::cout << event.name << " (string)\t" << payload << std::endl;
uf::hooks.call( "window:Event", payload );
uf::hooks.call( event.name, payload );
} else if ( event.payload.is<uf::Serializer>() ) {
uf::Serializer& payload = event.payload.as<uf::Serializer>();
// std::cout << event.name << " (serializer)\t" << payload << std::endl;
uf::hooks.call( "window:Event", payload );
uf::hooks.call( event.name, payload );
} else if ( event.payload.is<ext::json::Value>() ) {
ext::json::Value& payload = event.payload.as<ext::json::Value>();
// std::cout << event.name << " (json)\t" << payload << std::endl;
uf::hooks.call( "window:Event", payload );
uf::hooks.call( event.name, payload );
} else {
// std::cout << event.name << "(???)" << std::endl;
uf::hooks.call( "window:Event", event.payload );
uf::hooks.call( event.name, event.payload );
}
/*

View File

@ -2,8 +2,10 @@
#include <uf/utils/io/iostream.h>
#include <uf/utils/string/utf.h>
#include <uf/utils/serialize/serializer.h>
#include <uf/utils/window/payloads.h>
#define USE_OPTIMAL 0
#define UF_USE_USERDATA 1
#define UF_USE_JSON 1
#if UF_ENV_WINDOWS && (!UF_USE_SFML || (UF_USE_SFML && UF_USE_SFML == 0))
namespace {
@ -772,39 +774,53 @@ void UF_API_CALL spec::win32::Window::processEvents() {
}
/* Key inputs */ if ( this->m_asyncParse ) {
std::vector<WPARAM> keys = GetKeys();
pod::payloads::windowKey event{
"window:Key",
"os",
{
"",
0,
struct Event {
std::string type = "unknown";
std::string invoker = "???";
struct {
int state;
std::string code;
uint32_t raw;
bool async;
struct {
bool alt;
bool ctrl;
bool shift;
bool sys;
} modifier;
} key;
-1,
true,
{
HIWORD(GetAsyncKeyState(VK_MENU)) != 0,
HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0,
HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0,
HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN)),
}
}
};
Event event; {
event.type = "window:Key";
event.invoker = "window";
event.key.state = -1;
event.key.code = "NULL";
event.key.raw = 0;
event.key.async = true;
event.key.modifier = {
.alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0,
.ctrl = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0,
.shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0,
.sys = HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN)),
};
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type + "." + ((event.key.state == -1)?"Pressed":"Released");
json["invoker"] = event.invoker;
json["key"]["code"] = "";
json["key"]["raw"] = 0;
json["key"]["state"] = (event.key.state == -1) ? "Down" : "Up";
json["key"]["async"] = event.key.async;
json["key"]["modifier"]["alt"] = event.key.modifier.alt;
json["key"]["modifier"]["control"] = event.key.modifier.ctrl;
json["key"]["modifier"]["shift"] = event.key.modifier.shift;
json["key"]["modifier"]["system"] = event.key.modifier.sys;
#endif
for ( auto& key : keys ) {
const auto code = GetKeyName(key);
event.key.code = code;
event.key.raw = key;
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
this->pushEvent(event.type + "." + code, event);
#endif
#if UF_USE_JSON
json["key"]["code"] = code;
json["key"]["raw"] = key;
this->pushEvent(event.type, json);
this->pushEvent(event.type + "." + code, json);
#endif
}
#if 0
/* Readable (JSON) + Optimal (Userdata) event */ {
uf::Serializer json;
/* Set up JSON data*/ {
@ -830,6 +846,7 @@ void UF_API_CALL spec::win32::Window::processEvents() {
}
}
}
#endif
}
}
bool UF_API_CALL spec::win32::Window::pollEvents( bool block ) {
@ -843,32 +860,16 @@ bool UF_API_CALL spec::win32::Window::pollEvents( bool block ) {
auto& event = this->m_events.front();
if ( event.payload.is<std::string>() ) {
ext::json::Value payload = uf::Serializer( event.payload.as<std::string>() );
// std::cout << event.name << " (string)\t" << payload << std::endl;
uf::hooks.call( "window:Event", payload );
uf::hooks.call( event.name, payload );
} else if ( event.payload.is<uf::Serializer>() ) {
uf::Serializer& payload = event.payload.as<uf::Serializer>();
// std::cout << event.name << " (serializer)\t" << payload << std::endl;
uf::hooks.call( "window:Event", payload );
uf::hooks.call( event.name, payload );
} else if ( event.payload.is<ext::json::Value>() ) {
ext::json::Value& payload = event.payload.as<ext::json::Value>();
// std::cout << event.name << " (json)\t" << payload << std::endl;
uf::hooks.call( "window:Event", payload );
uf::hooks.call( event.name, payload );
} else {
// std::cout << event.name << "(???)" << std::endl;
uf::hooks.call( "window:Event", event.payload );
uf::hooks.call( event.name, event.payload );
}
/*
try {
uf::hooks.call( "window:Event", payload );
uf::hooks.call( event.name, payload );
} catch ( ... ) {
// Let the hook handler handle the exceptions
}
*/
this->m_events.pop();
}
return true;
@ -938,12 +939,13 @@ void UF_API_CALL spec::win32::Window::registerWindowClass() {
void UF_API_CALL spec::win32::Window::processEvent(UINT message, WPARAM wParam, LPARAM lParam) {
if (!this->m_handle) return;
uf::Serializer json;
std::string hook = "window:Unknown";
std::string serialized = "";
std::stringstream serializer;
bool labelAsDelta = true;
uf::Serializer json;
switch (message) {
case WM_DESTROY:
this->terminate();
@ -952,54 +954,40 @@ void UF_API_CALL spec::win32::Window::processEvent(UINT message, WPARAM wParam,
if (LOWORD(lParam) == HTCLIENT) SetCursor(this->m_cursor);
break;
case WM_CLOSE: {
struct Event {
std::string type = "unknown";
std::string invoker = "???";
pod::payloads::windowEvent event{
"window:Closed",
"os",
};
Event event; {
event.type = "window:Closed";
event.invoker = "os";
};
#if USE_OPTIMAL
this->pushEvent(event.type, uf::Userdata(uf::userdata::create(event)));
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
#endif
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type;
json["invoker"] = event.invoker;
this->pushEvent(event.type, json);
#endif
{
json["type"] = event.type;
json["invoker"] = event.invoker;
this->pushEvent(event.type, json);
}
} break;
case WM_SIZE: {
if (wParam != SIZE_MINIMIZED && !this->m_resizing && this->m_lastSize != getSize()) {
this->m_lastSize = this->getSize();
if (wParam == SIZE_MINIMIZED || this->m_resizing || this->m_lastSize == getSize()) break;
this->m_lastSize = this->getSize();
struct Event {
std::string type = "unknown";
std::string invoker = "???";
struct {
pod::Vector2i size;
} window;
};
Event event; {
event.type = "window:Resized";
event.invoker = "os";
event.window.size = this->m_lastSize;
};
#if USE_OPTIMAL
this->pushEvent(event.type, uf::Userdata(uf::userdata::create(event)));
#endif
{
json["type"] = event.type;
json["invoker"] = event.invoker;
json["window"]["size"] = uf::vector::encode(event.window.size);
// json["window"]["size"]["x"] = event.window.size.x;
// json["window"]["size"]["y"] = event.window.size.y;
this->pushEvent(event.type, json);
}
this->grabMouse(this->m_mouseGrabbed);
}
pod::payloads::windowResized event{
"window:Resized",
"os",
{ this->m_lastSize },
};
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
#endif
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type;
json["invoker"] = event.invoker;
json["window"]["size"] = uf::vector::encode(event.window.size);
this->pushEvent(event.type, json);
#endif
this->grabMouse(this->m_mouseGrabbed);
} break;
case WM_ENTERSIZEMOVE: {
this->m_resizing = true;
@ -1007,50 +995,38 @@ void UF_API_CALL spec::win32::Window::processEvent(UINT message, WPARAM wParam,
} break;
case WM_EXITSIZEMOVE:{
this->m_resizing = false;
if(this->m_lastSize != this->getSize()) {
if( this->m_lastSize != this->getSize() ) {
this->m_lastSize = this->getSize();
struct Event {
std::string type = "unknown";
std::string invoker = "???";
struct {
pod::Vector2i size;
} window;
pod::payloads::windowResized event = {
"window:Resized",
"os",
{ this->m_lastSize },
};
Event event; {
event.type = "window:Resized";
event.invoker = "os";
event.window.size = this->m_lastSize;
};
#if USE_OPTIMAL
this->pushEvent(event.type, uf::Userdata(uf::userdata::create(event)));
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
#endif
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type;
json["invoker"] = event.invoker;
json["window"]["size"] = uf::vector::encode(event.window.size);
this->pushEvent(event.type, json);
#endif
{
json["type"] = event.type;
json["invoker"] = event.invoker;
json["window"]["size"] = uf::vector::encode(event.window.size);
// json["window"]["size"]["x"] = event.window.size.x;
// json["window"]["size"]["y"] = event.window.size.y;
this->pushEvent(event.type, json);
}
} else {
struct Event {
std::string type = "unknown";
std::string invoker = "???";
pod::payloads::windowEvent event{
"window:Moved",
"os",
};
Event event; {
event.type = "window:Moved";
event.invoker = "os";
};
#if USE_OPTIMAL
this->pushEvent(event.type, uf::Userdata(uf::userdata::create(event)));
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
#endif
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type;
json["invoker"] = event.invoker;
this->pushEvent(event.type, json);
#endif
{
json["type"] = event.type;
json["invoker"] = event.invoker;
this->pushEvent(event.type, json);
}
}
this->grabMouse(this->m_mouseGrabbed);
} break;
@ -1069,35 +1045,27 @@ void UF_API_CALL spec::win32::Window::processEvent(UINT message, WPARAM wParam,
this->grabMouse(this->m_mouseGrabbed);
SetCursor(this->m_cursor);
}
struct Event {
std::string type = "unknown";
std::string invoker = "???";
struct {
int state = 0;
} window;
pod::payloads::windowFocusedChanged event{
"window:Focus.Changed",
"os",
};
Event event; {
event.type = "window:Focus.Changed";
event.invoker = "os";
switch ( message ) {
case WM_SETFOCUS: event.window.state = 1; break;
case WM_KILLFOCUS: event.window.state = -1; break;
}
};
#if USE_OPTIMAL
this->pushEvent(event.type, uf::Userdata(uf::userdata::create(event)));
#endif
{
json["type"] = event.type;
json["invoker"] = event.invoker;
switch ( message ) {
case WM_SETFOCUS: json["window"]["state"] = "Gained"; break;
case WM_KILLFOCUS: json["window"]["state"] = "Lost"; break;
}
this->pushEvent(event.type, json);
switch ( message ) {
case WM_SETFOCUS: event.window.state = 1; break;
case WM_KILLFOCUS: event.window.state = -1; break;
}
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
#endif
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type;
json["invoker"] = event.invoker;
switch ( message ) {
case WM_SETFOCUS: json["window"]["state"] = "Gained"; break;
case WM_KILLFOCUS: json["window"]["state"] = "Lost"; break;
}
this->pushEvent(event.type, json);
#endif
} break;
// Text event
case WM_CHAR: if ( /*true ||*/ this->m_syncParse ) {
@ -1120,36 +1088,26 @@ void UF_API_CALL spec::win32::Window::processEvent(UINT message, WPARAM wParam,
std::basic_string<uint32_t> utf32; utf32+=character;
std::basic_string<uint8_t> utf8; utf8.reserve(utf32.length());
uf::Utf32::toUtf8(utf32.begin(), utf32.end(), std::back_inserter(utf8));
std::stringstream to_hex;
to_hex << std::hex << character;
struct Event {
std::string type = "unknown";
std::string invoker = "???";
struct {
uint32_t utf32;
std::string unicode;
} text;
pod::payloads::windowTextEntered event{
"window:Text.Entered",
"os",
{
character,
std::string(utf8.begin(), utf8.end()),
}
};
Event event; {
event.type = "window:Text.Entered";
event.invoker = "os";
event.text.utf32 = character;
event.text.unicode = std::string(utf8.begin(), utf8.end());
};
#if USE_OPTIMAL
this->pushEvent(event.type, uf::Userdata(uf::userdata::create(event)));
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
#endif
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type;
json["invoker"] = event.invoker;
json["text"]["uint32_t"] = event.text.utf32;
json["text"]["unicode"] = std::string(utf8.begin(), utf8.end());
json["text"]["unicode"] = event.text.unicode;
this->pushEvent(event.type, json);
#endif
}
}
} break;
@ -1158,71 +1116,51 @@ void UF_API_CALL spec::win32::Window::processEvent(UINT message, WPARAM wParam,
case WM_KEYUP:
case WM_SYSKEYUP: if ( /*true ||*/ this->m_syncParse ) {
if (this->m_keyRepeatEnabled || ((HIWORD(lParam) & KF_REPEAT) == 0)) {
struct Event {
std::string type = "unknown";
std::string invoker = "???";
int_fast8_t state = 0;
switch ( message ) {
case WM_KEYDOWN:
case WM_SYSKEYDOWN: state = -1; break;
struct {
int state = -1;
std::string code;
uint32_t raw;
bool async;
struct {
bool alt;
bool ctrl;
bool shift;
bool sys;
} modifier;
} key;
};
Event event; {
event.type = "window:Key",
event.invoker = "window",
event.key.code = this->getKey(wParam, lParam),
event.key.raw = wParam,
event.key.async = false,
event.key.modifier = {
.alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0,
.ctrl = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0,
.shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0,
.sys = HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN)),
};
switch ( message ) {
case WM_KEYDOWN:
case WM_SYSKEYDOWN: event.key.state = -1; break;
case WM_KEYUP:
case WM_SYSKEYUP: event.key.state = 1; break;
}
case WM_KEYUP:
case WM_SYSKEYUP: state = 1; break;
}
// if ( USE_OPTIMAL ) this->pushEvent(event.type, uf::Userdata(uf::userdata::create(event)));
// if ( USE_OPTIMAL ) this->pushEvent(event.type + "." + event.key.code, uf::Userdata(uf::userdata::create(event)));
json["type"] = event.type + "." + ((event.key.state == -1)?"Pressed":"Released");
json["invoker"] = event.invoker;
json["key"]["state"] = (event.key.state == -1) ? "Down" : "Up";
json["key"]["async"] = event.key.async;
json["key"]["modifier"]["alt"] = event.key.modifier.alt;
json["key"]["modifier"]["control"] = event.key.modifier.ctrl;
json["key"]["modifier"]["shift"] = event.key.modifier.shift;
json["key"]["modifier"]["system"] = event.key.modifier.sys;
json["key"]["code"] = event.key.code;
json["key"]["raw"] = event.key.raw;
json["key"]["lparam"] = lParam;
// don't know why things dont like things
/*
if (event.key.state == -1) {
uf::hooks.call(event.type, json);
uf::hooks.call(event.type + "." + event.key.code, json);
} else {
pod::payloads::windowKey event{
"window:Key",
"os",
{
this->getKey(wParam, lParam),
wParam,
state,
false,
{
.alt = HIWORD(GetAsyncKeyState(VK_MENU)) != 0,
.ctrl = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0,
.shift = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0,
.sys = HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN)),
}
}
};
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
this->pushEvent(event.type + "." + event.key.code, event);
#endif
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type + "." + ((event.key.state == -1)?"Pressed":"Released");
json["invoker"] = event.invoker;
json["key"]["state"] = (event.key.state == -1) ? "Down" : "Up";
json["key"]["async"] = event.key.async;
json["key"]["modifier"]["alt"] = event.key.modifier.alt;
json["key"]["modifier"]["control"] = event.key.modifier.ctrl;
json["key"]["modifier"]["shift"] = event.key.modifier.shift;
json["key"]["modifier"]["system"] = event.key.modifier.sys;
json["key"]["code"] = event.key.code;
json["key"]["raw"] = event.key.raw;
json["key"]["lparam"] = lParam;
this->pushEvent(event.type, json);
this->pushEvent(event.type + "." + event.key.code, json);
}
*/
this->pushEvent(event.type, json);
this->pushEvent(event.type + "." + event.key.code, json);
#endif
}
} break;
case WM_MOUSEWHEEL: {
@ -1232,38 +1170,25 @@ void UF_API_CALL spec::win32::Window::processEvent(UINT message, WPARAM wParam,
ScreenToClient(this->m_handle, &position);
int16_t delta = static_cast<int16_t>(HIWORD(wParam));
struct Event {
std::string type = "unknown";
std::string invoker = "???";
struct {
pod::Vector2ui position = {};
float delta = 0;
} mouse;
pod::payloads::windowMouseWheel event{
"window:Mouse.Wheel",
"os",
{
pod::Vector2ui{ position.x, position.y },
delta,
}
};
Event event; {
event.type = "window:Mouse.Wheel";
event.invoker = "os";
event.mouse.position.x = position.x;
event.mouse.position.y = position.y;
event.mouse.delta = delta; // 120.0f;
};
#if USE_OPTIMAL
this->pushEvent(event.type, uf::Userdata(uf::userdata::create(event)));
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
#endif
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type;
json["invoker"] = event.invoker;
json["mouse"]["position"] = uf::vector::encode(event.mouse.position);
json["mouse"]["delta"] = event.mouse.delta;
this->pushEvent(event.type, json);
#endif
{
json["type"] = event.type;
json["invoker"] = event.invoker;
json["mouse"]["position"] = uf::vector::encode(event.mouse.position);
// json["mouse"]["position"]["x"] = event.mouse.position.x;
// json["mouse"]["position"]["y"] = event.mouse.position.y;
json["mouse"]["delta"] = event.mouse.delta;
this->pushEvent(event.type, json);
}
} break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
@ -1274,187 +1199,90 @@ void UF_API_CALL spec::win32::Window::processEvent(UINT message, WPARAM wParam,
case WM_XBUTTONDOWN:
case WM_XBUTTONUP: if ( true || this->m_syncParse ) {
static pod::Vector2i lastPosition = {};
struct Event {
std::string type = "unknown";
std::string invoker = "???";
const pod::Vector2i currentPosition = pod::Vector2ui{ static_cast<int16_t>(LOWORD(lParam)), static_cast<int16_t>(HIWORD(lParam)) };
std::string button = "";
int_fast8_t state = 0;
struct {
pod::Vector2i position = {};
pod::Vector2i delta = lastPosition;
std::string button = "???";
int state = 0;
} mouse;
};
Event event; {
event.type = "window:Mouse.Click";
event.invoker = "os";
switch ( message ) {
case WM_LBUTTONDOWN:
case WM_LBUTTONUP: button = "Left"; break;
case WM_RBUTTONDOWN:
case WM_RBUTTONUP: button = "Right"; break;
case WM_MBUTTONDOWN:
case WM_MBUTTONUP: button = "Middle"; break;
case WM_XBUTTONDOWN:
case WM_XBUTTONUP: button = "Aux"; break;
// event.mouse.position = this->getMousePosition();
event.mouse.position.x = static_cast<int16_t>(LOWORD(lParam));
event.mouse.position.y = static_cast<int16_t>(HIWORD(lParam));
event.mouse.delta = event.mouse.position - lastPosition;
switch ( message ) {
case WM_LBUTTONDOWN:
case WM_LBUTTONUP: event.mouse.button = "Left"; break;
case WM_RBUTTONDOWN:
case WM_RBUTTONUP: event.mouse.button = "Right"; break;
case WM_MBUTTONDOWN:
case WM_MBUTTONUP: event.mouse.button = "Middle"; break;
case WM_XBUTTONDOWN:
case WM_XBUTTONUP: event.mouse.button = "Aux"; break;
default: event.mouse.button = "???"; break;
}
switch ( message ) {
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_XBUTTONUP: event.mouse.state = 1; break;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_XBUTTONDOWN: event.mouse.state = -1; break;
default: event.mouse.state = 0; break;
}
};
if ( true || this->m_syncParse ){
#if USE_OPTIMAL
this->pushEvent(event.type, uf::Userdata(uf::userdata::create(event)));
#endif
json["type"] = event.type;
json["invoker"] = event.invoker;
json["mouse"]["position"] = uf::vector::encode(event.mouse.position);
json["mouse"]["delta"] = uf::vector::encode(event.mouse.delta);
// json["mouse"]["position"]["x"] = event.mouse.position.x;
// json["mouse"]["position"]["y"] = event.mouse.position.y;
// json["mouse"]["delta"]["x"] = event.mouse.delta.x;
// json["mouse"]["delta"]["y"] = event.mouse.delta.y;
json["mouse"]["button"] = event.mouse.button;
switch (event.mouse.state) {
case 1:
json["mouse"]["state"] = "Up";
break;
case -1:
json["mouse"]["state"] = "Down";
break;
default:
json["mouse"]["state"] = "???";
break;
}
this->pushEvent(event.type, json);
default: button = "???"; break;
}
lastPosition = event.mouse.position; //this->getMousePosition();
switch ( message ) {
case WM_LBUTTONUP:
case WM_RBUTTONUP:
case WM_MBUTTONUP:
case WM_XBUTTONUP: state = 1; break;
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
case WM_XBUTTONDOWN: state = -1; break;
default: state = 0; break;
}
pod::payloads::windowMouseClick event{
"window:Mouse.Click",
"os",
{
currentPosition,
currentPosition - lastPosition,
button,
state
}
};
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
#endif
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type;
json["invoker"] = event.invoker;
json["mouse"]["position"] = uf::vector::encode(event.mouse.position);
json["mouse"]["delta"] = uf::vector::encode(event.mouse.delta);
json["mouse"]["button"] = event.mouse.button;
switch (event.mouse.state) {
case 1: json["mouse"]["state"] = "Up"; break;
case -1: json["mouse"]["state"] = "Down"; break;
}
this->pushEvent(event.type, json);
#endif
lastPosition = currentPosition;
} break;
case WM_MOUSELEAVE:
if (this->m_mouseInside) {
if ( this->m_mouseInside ) {
this->m_mouseInside = false;
struct Event {
std::string type = "unknown";
std::string invoker = "???";
struct {
int state = 0;
} mouse;
};
Event event; {
event.type = "window:Mouse.Moved";
event.invoker = "os";
event.mouse.state = -1;
};
#if USE_OPTIMAL
this->pushEvent(event.type, uf::Userdata(uf::userdata::create(event)));
#endif
{
json["type"] = event.type;
json["invoker"] = event.invoker;
switch (event.mouse.state) {
case 1:
json["mouse"]["state"] = "Entered";
break;
case -1:
json["mouse"]["state"] = "Left";
break;
default:
json["mouse"]["state"] = "???";
break;
pod::payloads::windowMouseMoved event{
"window:Mouse.Moved",
"os",
{
{}
},
{
{},
{},
-1
}
this->pushEvent(event.type, json);
}
}
break;
case WM_MOUSEMOVE: {
static pod::Vector2i lastPosition = {};
struct Event {
std::string type = "unknown";
std::string invoker = "???";
struct {
int state = 0;
pod::Vector2i position;
pod::Vector2i delta;
pod::Vector2i size;
} mouse;
};
Event event; {
event.type = "window:Mouse.Moved";
event.invoker = "os";
};
int x = static_cast<int16_t>(LOWORD(lParam));
int y = static_cast<int16_t>(HIWORD(lParam));
RECT area;
GetClientRect(this->m_handle, &area);
if ((wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON | MK_XBUTTON1 | MK_XBUTTON2)) == 0) {
if (GetCapture() == this->m_handle) ReleaseCapture();
}
else if (GetCapture() != this->m_handle) {
SetCapture(this->m_handle);
}
if ((x < area.left) || (x > area.right) || (y < area.top) || (y > area.bottom)) {
if (this->m_mouseInside) {
this->m_mouseInside = false;
this->setTracking(false);
event.mouse.state = -1;
}
} else {
if (!this->m_mouseInside) {
this->m_mouseInside = true;
this->setTracking(true);
event.mouse.state = 1;
}
}
{
event.mouse.position.x = x;
event.mouse.position.y = y;
event.mouse.size = {area.right, area.bottom};
event.mouse.delta = event.mouse.position - lastPosition;
}
#if USE_OPTIMAL
this->pushEvent(event.type, uf::Userdata(uf::userdata::create(event)));
#endif
{
};
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
#endif
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type;
json["invoker"] = event.invoker;
// json["mouse"]["position"]["x"] = event.mouse.position.x;
// json["mouse"]["position"]["y"] = event.mouse.position.y;
// json["mouse"]["delta"]["x"] = event.mouse.delta.x;
// json["mouse"]["delta"]["y"] = event.mouse.delta.y;
// json["mouse"]["size"]["x"] = event.mouse.size.x;
// json["mouse"]["size"]["y"] = event.mouse.size.y;
json["mouse"]["position"] = uf::vector::encode(event.mouse.position);
json["mouse"]["delta"] = uf::vector::encode(event.mouse.delta);
json["mouse"]["size"] = uf::vector::encode(event.mouse.size);
switch (event.mouse.state) {
case 1:
json["mouse"]["state"] = "Entered";
@ -1467,8 +1295,78 @@ void UF_API_CALL spec::win32::Window::processEvent(UINT message, WPARAM wParam,
break;
}
this->pushEvent(event.type, json);
#endif
}
lastPosition = event.mouse.position; //this->getMousePosition();
break;
case WM_MOUSEMOVE: {
static pod::Vector2i lastPosition = {};
const pod::Vector2i currentPosition = {
static_cast<int16_t>(LOWORD(lParam)),
static_cast<int16_t>(HIWORD(lParam)),
};
RECT area;
GetClientRect(this->m_handle, &area);
if ((wParam & (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON | MK_XBUTTON1 | MK_XBUTTON2)) == 0) {
if (GetCapture() == this->m_handle) ReleaseCapture();
}
else if (GetCapture() != this->m_handle) {
SetCapture(this->m_handle);
}
int_fast8_t state{};
if ((currentPosition.x < area.left) || (currentPosition.x > area.right) || (currentPosition.y < area.top) || (currentPosition.y > area.bottom)) {
if ( this->m_mouseInside ) {
this->m_mouseInside = false;
this->setTracking(false);
state = -1;
}
} else {
if ( !this->m_mouseInside ) {
this->m_mouseInside = true;
this->setTracking(true);
state = 1;
}
}
pod::payloads::windowMouseMoved event{
"window:Mouse.Moved",
"os",
{
pod::Vector2ui{ area.right, area.bottom },
},
{
currentPosition,
currentPosition - lastPosition,
state
}
};
#if UF_USE_USERDATA
this->pushEvent(event.type, event);
#endif
#if UF_USE_JSON
uf::Serializer json;
json["type"] = event.type;
json["invoker"] = event.invoker;
json["window"]["size"] = uf::vector::encode(event.window.size);
json["mouse"]["position"] = uf::vector::encode(event.mouse.position);
json["mouse"]["delta"] = uf::vector::encode(event.mouse.delta);
switch (event.mouse.state) {
case 1:
json["mouse"]["state"] = "Entered";
break;
case -1:
json["mouse"]["state"] = "Left";
break;
default:
json["mouse"]["state"] = "???";
break;
}
this->pushEvent(event.type, json);
#endif
lastPosition = currentPosition;
break;
}
}

View File

@ -5,6 +5,7 @@
#include <uf/utils/serialize/serializer.h>
#include <uf/utils/userdata/userdata.h>
#include <uf/utils/window/window.h>
#include <uf/utils/window/payloads.h>
#include <uf/utils/camera/camera.h>
#include <uf/utils/audio/audio.h>
#include <uf/ext/openvr/openvr.h>
@ -13,18 +14,6 @@
#include <uf/utils/math/physics.h>
#include <uf/spec/controller/controller.h>
namespace pod {
namespace payloads {
struct windowMouseMoved {
std::string invoker = "";
pod::Vector2i delta;
pod::Vector2ui position;
pod::Vector2ui size;
int_fast8_t state;
};
}
}
#include <sstream>
UF_BEHAVIOR_REGISTER_CPP(ext::PlayerBehavior)
#define this (&self)
@ -111,26 +100,20 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
}
metadataJson["system"]["control"] = true;
this->addHook( "window:Mouse.CursorVisibility", [&](ext::json::Value& json){
// metadataJson["system"]["control"] = !json["state"].as<bool>();
metadata.system.control = !json["state"].as<bool>();
});
// Rotate Camera
this->addHook( "window:Mouse.Moved", [&](pod::payloads::windowMouseMoved& payload ){
pod::Vector2 relta = { (float) payload.delta.x / payload.size.x, (float) payload.delta.y / payload.size.y };
relta *= 2;
if ( (payload.delta.x == 0 && payload.delta.y == 0) || !metadata.system.control ) return;
float sensitivity = 2;
pod::Vector2 relta = { (float) sensitivity * payload.mouse.delta.x / payload.window.size.x, (float) sensitivity * payload.mouse.delta.y / payload.window.size.y };
if ( (payload.mouse.delta.x == 0 && payload.mouse.delta.y == 0) || !metadata.system.control ) return;
bool updateCamera = false;
if ( payload.delta.x != 0 ) {
double current, minima, maxima; {
current = !ext::json::isNull( metadataJson["camera"]["limit"]["current"][0] ) ? metadataJson["camera"]["limit"]["current"][0].as<double>() : NAN;
minima = !ext::json::isNull( metadataJson["camera"]["limit"]["minima"][0] ) ? metadataJson["camera"]["limit"]["minima"][0].as<double>() : NAN;
maxima = !ext::json::isNull( metadataJson["camera"]["limit"]["maxima"][0] ) ? metadataJson["camera"]["limit"]["maxima"][0].as<double>() : NAN;
}
if ( metadataJson["camera"]["invert"][0].as<bool>() ) relta.x *= -1;
current += relta.x;
if ( current != current || ( current < maxima && current > minima ) ) {
if ( payload.mouse.delta.x != 0 ) {
if ( metadata.camera.invert.x ) relta.x *= -1;
metadata.camera.limit.current.x += relta.x;
if ( metadata.camera.limit.current.x != metadata.camera.limit.current.x || ( metadata.camera.limit.current.x < metadata.camera.limit.max.x && metadata.camera.limit.current.x > metadata.camera.limit.min.x ) ) {
if ( collider.body && !collider.shared ) {
#if UF_USE_BULLET
ext::bullet::applyRotation( collider, transform.up, relta.x );
@ -138,27 +121,19 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
} else {
uf::transform::rotate( transform, transform.up, relta.x ), updateCamera = true;
}
} else current -= relta.x;
if ( !ext::json::isNull( metadataJson["camera"]["limit"]["current"][0] ) ) metadataJson["camera"]["limit"]["current"][0] = current;
} else metadata.camera.limit.current.x -= relta.x;
}
if ( payload.delta.y != 0 ) {
double current, minima, maxima; {
current = !ext::json::isNull( metadataJson["camera"]["limit"]["current"][1] ) ? metadataJson["camera"]["limit"]["current"][1].as<double>() : NAN;
minima = !ext::json::isNull( metadataJson["camera"]["limit"]["minima"][1] ) ? metadataJson["camera"]["limit"]["minima"][1].as<double>() : NAN;
maxima = !ext::json::isNull( metadataJson["camera"]["limit"]["maxima"][1] ) ? metadataJson["camera"]["limit"]["maxima"][1].as<double>() : NAN;
}
if ( metadataJson["camera"]["invert"][1].as<bool>() ) relta.y *= -1;
current += relta.y;
if ( current != current || ( current < maxima && current > minima ) ) {
if ( payload.mouse.delta.y != 0 ) {
if ( metadata.camera.invert.y ) relta.y *= -1;
metadata.camera.limit.current.y += relta.y;
if ( metadata.camera.limit.current.y != metadata.camera.limit.current.y || ( metadata.camera.limit.current.y < metadata.camera.limit.max.y && metadata.camera.limit.current.y > metadata.camera.limit.min.y ) ) {
// if ( collider.body && !collider.shared ) {
// ext::bullet::applyRotation( collider, cameraTransform.right, relta.y );
// } else {
uf::transform::rotate( cameraTransform, cameraTransform.right, relta.y );
// }
updateCamera = true;
} else current -= relta.y;
if ( !ext::json::isNull( metadataJson["camera"]["limit"]["current"][1] ) ) metadataJson["camera"]["limit"]["current"][1] = current;
} else metadata.camera.limit.current.y -= relta.y;
}
if ( updateCamera ) camera.updateView();
});
@ -259,6 +234,8 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
auto& metadataSystem = metadataJson["system"];
auto& metadataSystemPhysics = metadataSystem["physics"];
auto& metadataAudioFootstep = metadataJson["audio"]["footstep"];
auto& metadataCamera = metadataJson["camera"];
auto& metadataCameraLimit = metadataCamera["limit"];
metadataSystem["menu"] = metadata.system.menu;
metadataSystem["control"] = metadata.system.control;
@ -274,11 +251,17 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
metadataSystemPhysics["crouch"] = metadata.system.physics.crouch;
metadataAudioFootstep["list"] = metadata.audio.footstep.list;
metadataAudioFootstep["volume"] = metadata.audio.footstep.volume;
metadataCamera["invert"] = uf::vector::encode(metadata.camera.invert);
metadataCameraLimit["current"] = uf::vector::encode(metadata.camera.limit.current);
metadataCameraLimit["minima"] = uf::vector::encode(metadata.camera.limit.min);
metadataCameraLimit["maxima"] = uf::vector::encode(metadata.camera.limit.max);
};
metadata.deserialize = [&](){
auto& metadataSystem = metadataJson["system"];
auto& metadataAudioFootstep = metadataJson["audio"]["footstep"];
auto& metadataSystemPhysics = metadataSystem["physics"];
auto& metadataCamera = metadataJson["camera"];
auto& metadataCameraLimit = metadataCamera["limit"];
metadata.system.menu = metadataSystem["menu"].as<std::string>();
metadata.system.control = metadataSystem["control"].as<bool>();
@ -296,6 +279,15 @@ void ext::PlayerBehavior::initialize( uf::Object& self ) {
metadata.audio.footstep.list.emplace_back(value);
});
metadata.audio.footstep.volume = metadataAudioFootstep["volume"].as<float>();
metadata.camera.invert = uf::vector::decode( metadataCamera["invert"], pod::Vector3t<bool>{false, false, false} );
metadata.camera.limit.current = uf::vector::decode( metadataCameraLimit["current"], pod::Vector3f{NAN, NAN, NAN} );
metadata.camera.limit.min = uf::vector::decode( metadataCameraLimit["minima"], pod::Vector3f{NAN, NAN, NAN} );
metadata.camera.limit.max = uf::vector::decode( metadataCameraLimit["maxima"], pod::Vector3f{NAN, NAN, NAN} );
// for ( uint_fast8_t i = 0; i < 3; ++i ) metadata.camera.limit.current[i] = metadataCameraLimit["current"][i].as<float>(NAN);
// for ( uint_fast8_t i = 0; i < 3; ++i ) metadata.camera.limit.min[i] = metadataCameraLimit["minima"][i].as<float>(NAN);
// for ( uint_fast8_t i = 0; i < 3; ++i ) metadata.camera.limit.max[i] = metadataCameraLimit["maxima"][i].as<float>(NAN);
};
this->addHook( "object:UpdateMetadata.%UID%", metadata.deserialize);
metadata.deserialize();

View File

@ -26,11 +26,20 @@ namespace ext {
float walk = 1.0f;
pod::Vector3f jump = {0,8,0};
} physics;
bool control = true;
std::string menu = "";
bool crouching = false;
bool noclipped = false;
} system;
struct {
struct {
pod::Vector3f current = {NAN, NAN, NAN};
pod::Vector3f min = {NAN, NAN, NAN};
pod::Vector3f max = {NAN, NAN, NAN};
} limit;
pod::Vector3t<bool> invert;
} camera;
struct {
struct {
std::vector<std::string> list;

View File

@ -31,18 +31,6 @@
#include <regex>
namespace pod {
namespace payloads {
struct windowMouseMoved {
std::string invoker = "";
pod::Vector2i delta;
pod::Vector2ui position;
pod::Vector2ui size;
int_fast8_t state;
};
}
}
namespace {
#if UF_USE_FREETYPE
struct {
@ -555,51 +543,6 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
if ( metadataJson["system"]["hoverable"].as<bool>() ) {
uf::Timer<long long> hoverTimer(false);
hoverTimer.start( uf::Time<>(-1000000) );
#if 1
this->addHook( "window:Mouse.Moved", [&]( pod::payloads::windowMouseMoved& payload ){
if ( ext::json::isObject( metadataJson["events"]["hover"] ) ) {
uf::Serializer event = metadataJson["events"]["hover"];
metadataJson["events"]["hover"] = ext::json::array(); //Json::arrayValue;
metadataJson["events"]["hover"][0] = event;
} else if ( !ext::json::isArray( metadataJson["events"]["hover"] ) ) {
this->getParent().as<uf::Object>().callHook("gui:Clicked.%UID%", payload );
return;
}
for ( int i = 0; i < metadataJson["events"]["hover"].size(); ++i ) {
uf::Serializer event = metadataJson["events"]["hover"][i];
uf::Serializer payload = event["payload"];
float delay = event["delay"].as<float>();
if ( event["delay"].is<double>() ) this->queueHook(event["name"].as<std::string>(), payload, event["delay"].as<float>());
else this->callHook(event["name"].as<std::string>(), payload );
}
return;
});
this->addHook( "window:Mouse.Moved", [&]( pod::payloads::windowMouseMoved& payload ){
if ( this->getUid() == 0 || !this->hasComponent<ext::Gui::mesh_t>() || metadata.world || (!metadata.box.min && !metadata.box.max) ) return;
bool clicked = false;
bool down = payload.state < 0;
pod::Vector2f click; {
click.x = (float) payload.position.x / (float) ext::gui::size.current.x;
click.y = (float) payload.position.y / (float) ext::gui::size.current.y;
click.x = (click.x * 2.0f) - 1.0f;
click.y = (click.y * 2.0f) - 1.0f;
float x = click.x;
float y = click.y;
clicked = ( metadata.box.min.x <= x && metadata.box.min.y <= y && metadata.box.max.x >= x && metadata.box.max.y >= y );
}
metadata.hovered = clicked;
metadataJson["hovered"] = clicked;
if ( clicked && hoverTimer.elapsed().asDouble() >= 1 ) {
hoverTimer.reset();
this->callHook("gui:Hovered.%UID%", payload);
}
this->callHook("gui:Mouse.Moved.%UID%", payload);
});
#else
this->addHook( "gui:Hovered.%UID%", [&](ext::json::Value& json){
if ( ext::json::isObject( metadataJson["events"]["hover"] ) ) {
uf::Serializer event = metadataJson["events"]["hover"];
@ -628,12 +571,9 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
if ( metadata.world ) return;
if ( !metadata.box.min && !metadata.box.max ) return;
bool down = json["mouse"]["state"].as<std::string>() == "Down";
bool clicked = false;
pod::Vector2ui position = uf::vector::decode( json["mouse"]["position"], pod::Vector2ui{} ); {
// position.x = json["mouse"]["position"]["x"].as<int>() > 0 ? json["mouse"]["position"]["x"].as<size_t>() : 0;
// position.y = json["mouse"]["position"]["y"].as<int>() > 0 ? json["mouse"]["position"]["y"].as<size_t>() : 0;
}
bool down = json["mouse"]["state"].as<std::string>() == "Down";
pod::Vector2ui position = uf::vector::decode( json["mouse"]["position"], pod::Vector2ui{} );
pod::Vector2f click; {
click.x = (float) position.x / (float) ext::gui::size.current.x;
click.y = (float) position.y / (float) ext::gui::size.current.y;
@ -654,7 +594,6 @@ void ext::GuiBehavior::initialize( uf::Object& self ) {
}
this->callHook("gui:Mouse.Moved.%UID%", json);
} );
#endif
}
#if UF_USE_FREETYPE
if ( metadataJson["text settings"]["string"].is<std::string>() ) {