Skip to content

Commit

Permalink
collect user input
Browse files Browse the repository at this point in the history
  • Loading branch information
summeroff committed Sep 23, 2024
1 parent c212906 commit a01eae3
Show file tree
Hide file tree
Showing 15 changed files with 264 additions and 121 deletions.
93 changes: 93 additions & 0 deletions examples/example_input_collecting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
const streamlabs_overlays = require('../build/RelWithDebInfo/game_overlay.node'); // Ensure this line is at the top

// Constants
const LOG_FILE_PATH = "c:\\work\\over_log.log";
const INITIAL_DELAY = 2000;
const STEP_DELAY = 5000;
const SCRIPT_TIMEOUT = 25000;

class OverlayController {
constructor(logFilePath) {
this.logFilePath = logFilePath;
}

log(message) {
const timestamp = new Date().toISOString();
console.log(`[${timestamp}] ${message}`);
}

start() {
this.log('Starting overlay...');
streamlabs_overlays.start(this.logFilePath);
this.log(`Overlay status: ${streamlabs_overlays.getStatus()}`);
}

stop() {
this.log('Stopping overlay...');
streamlabs_overlays.stop();
this.log('Overlay stopped. Exiting...');
process.exit();
}

scriptFinished() {
this.log('Script finished.');
this.stop();
}

stepFinish() {
this.log('Step finished.');
setTimeout(() => this.scriptFinished(), INITIAL_DELAY);
}

step4() {
this.log('Executing step 4: Disabling input collection again.');
streamlabs_overlays.switchInputCollection(false);
setTimeout(() => this.stepFinish(), STEP_DELAY);
}

step3() {
this.log('Executing step 3: Re-enabling input collection.');
streamlabs_overlays.switchInputCollection(true);
setTimeout(() => this.step4(), STEP_DELAY);
}

step2() {
this.log('Executing step 2: Enabling input collection.');
streamlabs_overlays.switchInputCollection(true);
setTimeout(() => this.step3(), STEP_DELAY);
}

step1() {
this.log('Executing step 1: Setting up input callbacks.');

streamlabs_overlays.setMouseCallback((eventType, x, y, modifier) => {
this.log(`MouseCallback: eventType=${eventType}, x=${x}, y=${y}, modifier=${modifier}`);
return 3;
});

streamlabs_overlays.setKeyboardCallback((eventType, keyCode) => {
this.log(`KeyboardCallback: eventType=${eventType}, keyCode=${keyCode}`);
if (keyCode === 38) {
streamlabs_overlays.switchInputCollection(false);
}
return 1;
});

setTimeout(() => this.step2(), STEP_DELAY);
}

run() {
try {
setTimeout(() => this.step1(), INITIAL_DELAY);
setTimeout(() => this.scriptFinished(), SCRIPT_TIMEOUT);
} catch (error) {
this.log(`An error occurred: ${error}`);
this.scriptFinished();
}
}
}

// Instantiate and run the overlay controller
const overlayController = new OverlayController(LOG_FILE_PATH);
overlayController.start();
overlayController.run();
65 changes: 0 additions & 65 deletions examples/example_interactivity_console.js

This file was deleted.

2 changes: 1 addition & 1 deletion examples/example_interactivity_window.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@

const { app, BrowserWindow } = require("electron")
const streamlabs_overlays = require('../build/Debug/game_overlay.node')
const streamlabs_overlays = require('../build/Release/game_overlay.node')
const fs = require("fs")

let win;
Expand Down
2 changes: 1 addition & 1 deletion examples/example_with_resize.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { app, BrowserWindow } = require("electron")
const electron = require('electron')
const streamlabs_overlays = require('../build/Debug/game_overlay.node')
const streamlabs_overlays = require('../build/Release/game_overlay.node')
const fs = require("fs")

//
Expand Down
5 changes: 3 additions & 2 deletions include/sl_overlay_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ int WINAPI set_overlay_autohide(int id, int autohide_timeout, int autohide_trans

int WINAPI set_callback_for_keyboard_input(int (*ptr)(WPARAM, LPARAM));
int WINAPI set_callback_for_mouse_input(int (*ptr)(WPARAM, LPARAM));
int WINAPI set_callback_for_switching_input(int (*ptr)());
int WINAPI set_callback_for_switching_input(BOOL (*ptr)());

int WINAPI use_callback_for_keyboard_input(WPARAM wParam, LPARAM lParam);
int WINAPI use_callback_for_mouse_input(WPARAM wParam, LPARAM lParam);
int WINAPI use_callback_for_switching_input();

int WINAPI switch_overlays_user_input(bool mode_active);
BOOL WINAPI switch_overlays_interactive_mode(bool mode_active);
BOOL WINAPI switch_overlays_collect_user_input(bool mode_active);
5 changes: 3 additions & 2 deletions include/sl_overlays.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ class smg_overlays
void quit();

//redirect user input
bool is_intercepting = false;
void hook_user_input();
bool is_input_hooked = false;
bool is_input_intercepting = false;
void hook_user_input(bool need_to_intercept);
void unhook_user_input();

//commands
Expand Down
1 change: 1 addition & 0 deletions include/stdafx.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const int COMMAND_HIDE_OVERLAYS = 2;
const int COMMAND_QUIT = 4;
const int COMMAND_TAKE_INPUT = 7;
const int COMMAND_RELEASE_INPUT = 8;
const int COMMAND_COLLECT_INPUT = 9;

//command for web view thread to close web view
//wParam id
Expand Down
5 changes: 4 additions & 1 deletion include/user_input_callback.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ struct callback_method_t
static bool set_intercept_active(bool) noexcept;

static bool get_intercept_active() noexcept;
static bool get_input_collection_active() noexcept;
static bool set_input_collection_active(bool) noexcept;

static void static_async_callback(uv_async_t* handle);
void async_callback();
Expand Down Expand Up @@ -109,4 +111,5 @@ struct callback_mouse_method_t : callback_method_t
extern callback_keyboard_method_t* user_keyboard_callback_info;
extern callback_mouse_method_t* user_mouse_callback_info;

int switch_input();
BOOL switch_interactive_mode();
BOOL switch_input_collecting();
9 changes: 8 additions & 1 deletion npm/typings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,11 @@ export function setKeyboardCallback(callback: Function): void;
* In this mode overlay module intercept user keyboard and mouse events and use callbacks to send them to frontend
*
*/
export function switchInteractiveMode( active: Boolean ): void;
export function switchInteractiveMode(active: Boolean): void;

/**
* Switch on/off collecting user input for overlays
* In this mode overlay module take user keyboard and mouse events without intercepting them and use callbacks to send them to frontend
*
*/
export function SwitchInputCollection(active: Boolean): void;
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ To configure a build
```
mkdir build
cd build
cmake -G "Visual Studio 16 2019" -A x64 ../
cmake -G "Visual Studio 17 2022" -A x64 -DCMAKE_INSTALL_PREFIX="desktop\node_modules\game-overlay" ../
```

And to make a build
Expand All @@ -34,7 +34,7 @@ cmake --build . --config Release
### Module use examples
Examples to show api usage for simple usecases.
```
yarn electron examples\example_with_offscreen.js
yarn electron examples\example_with_offscreen.js
yarn electron examples\example_interactivity_console.js
yarn electron examples\example_interactivity_window.js
```
Expand Down
44 changes: 42 additions & 2 deletions src/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,9 @@ napi_value SwitchToInteractive(napi_env env, napi_callback_info args)

if (callback_method_t::get_intercept_active() != switch_to && check_visibility_for_switch)
{
set_callback_for_switching_input(&switch_input); // so module can switch itself off by some command
set_callback_for_switching_input(&switch_interactive_mode); // so module can switch itself off by some command

switch_input();
switch_interactive_mode();

log_info << "APP: SwitchToInteractive " << callback_method_t::get_intercept_active() << std::endl;

Expand All @@ -227,6 +227,41 @@ napi_value SwitchToInteractive(napi_env env, napi_callback_info args)
return ret;
}

napi_value SwitchInputCollection(napi_env env, napi_callback_info args)
{
if (!user_keyboard_callback_info->ready || !user_mouse_callback_info->ready)
{
log_info << "APP: SwitchInputCollection rejected as callbacks not set" << std::endl;
return failed_ret;
}

napi_value ret = nullptr;
size_t argc = 1;
napi_value argv[1];
bool switch_to;
int switched = -1;

if (napi_get_cb_info(env, args, &argc, argv, NULL, NULL) != napi_ok)
return failed_ret;

if (napi_get_value_bool(env, argv[0], &switch_to) != napi_ok)
return failed_ret;

if (callback_method_t::get_input_collection_active() != switch_to)
{
switch_input_collecting();

log_info << "APP: SwitchInputCollection " << callback_method_t::get_input_collection_active() << std::endl;

switched = 1;
}

if (napi_create_int32(env, switched, &ret) != napi_ok)
return failed_ret;

return ret;
}

napi_value SetKeyboardCallback(napi_env env, napi_callback_info args)
{
log_info << "APP: SetKeyboardCallback " << std::endl;
Expand Down Expand Up @@ -634,6 +669,11 @@ napi_value init(napi_env env, napi_value exports)
if (napi_set_named_property(env, exports, "switchInteractiveMode", fn) != napi_ok)
return failed_ret;

if (napi_create_function(env, nullptr, 0, SwitchInputCollection, nullptr, &fn) != napi_ok)
return failed_ret;
if (napi_set_named_property(env, exports, "switchInputCollection", fn) != napi_ok)
return failed_ret;

if (napi_create_function(env, nullptr, 0, SetKeyboardCallback, nullptr, &fn) != napi_ok)
return failed_ret;
if (napi_set_named_property(env, exports, "setKeyboardCallback", fn) != napi_ok)
Expand Down
21 changes: 17 additions & 4 deletions src/sl_overlay_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ int WINAPI remove_overlay(int id)

static int (*callback_keyboard_ptr)(WPARAM, LPARAM) = nullptr;
static int (*callback_mouse_ptr)(WPARAM, LPARAM) = nullptr;
static int (*callback_switch_ptr)() = nullptr;
static BOOL (*callback_switch_ptr)() = nullptr;

int WINAPI set_callback_for_keyboard_input(int (*ptr)(WPARAM, LPARAM))
{
Expand All @@ -185,7 +185,7 @@ int WINAPI set_callback_for_mouse_input(int (*ptr)(WPARAM, LPARAM))
return 0;
}

int WINAPI set_callback_for_switching_input(int (*ptr)())
int WINAPI set_callback_for_switching_input(BOOL (*ptr)())
{
callback_switch_ptr = ptr;

Expand Down Expand Up @@ -219,7 +219,7 @@ int WINAPI use_callback_for_switching_input()
return 0;
}

int WINAPI switch_overlays_user_input(bool mode_active)
BOOL WINAPI switch_overlays_interactive_mode(bool mode_active)
{
BOOL ret = false;

Expand All @@ -231,7 +231,20 @@ int WINAPI switch_overlays_user_input(bool mode_active)
ret = PostThreadMessage((DWORD)overlays_thread_id, WM_SLO_OVERLAY_COMMAND, COMMAND_RELEASE_INPUT, 0);
}

return 0;
return ret;
}

BOOL WINAPI switch_overlays_collect_user_input(bool mode_active)
{
BOOL ret = false;
if(mode_active)
{
ret = PostThreadMessage((DWORD)overlays_thread_id, WM_SLO_OVERLAY_COMMAND, COMMAND_COLLECT_INPUT, 0);
} else {
ret = PostThreadMessage((DWORD)overlays_thread_id, WM_SLO_OVERLAY_COMMAND, COMMAND_RELEASE_INPUT, 0);
}

return ret;
}

int WINAPI add_overlay_by_hwnd(const void* hwnd_array, size_t array_size)
Expand Down
Loading

0 comments on commit a01eae3

Please sign in to comment.