Last active
November 16, 2020 03:08
-
-
Save upgradeQ/c553ee6a561d82397058d319055dcb25 to your computer and use it in GitHub Desktop.
Lua coroutines in obslua https://obsproject.com/forum/threads/tips-and-tricks-for-lua-scripts.132256/#post-491713
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local obs = obslua | |
local coroutine = require 'coroutine' | |
local math = require 'math' | |
local Timer = {} | |
function Timer:init(o) | |
o = o or {} | |
setmetatable(o,self) | |
self.__index = self | |
return o | |
end | |
function Timer:update(dt) | |
self.current_time = self.current_time + dt | |
if self.current_time >= self.delay then | |
self.finished = true | |
end | |
end | |
function Timer:enter() | |
self.finished = false | |
self.current_time = 0 | |
end | |
function Timer:exit() | |
--print('on exit') | |
end | |
function Timer:launch() | |
self:enter() | |
while not self.finished do | |
local dt = coroutine.yield() | |
self:update(dt) | |
end | |
self:exit() | |
end | |
function time_sleep(s) | |
local action = Timer:init{delay=s} | |
action:launch() | |
end | |
---[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[] | |
function current_scene() | |
print('start current scene') | |
time_sleep(1) | |
print('end waiting one second / starting to wait again') | |
time_sleep(4) | |
print('end waiting [current] for four seconds') | |
end | |
function infinity_scene() | |
while true do | |
n = math.random(1,3) | |
print('random sleep [' .. n .. '] seconds') | |
time_sleep(n) | |
end | |
end | |
local scene_item | |
local source_name = 'c2c2' | |
function find_scene_item() | |
local source = obs.obs_frontend_get_current_scene() | |
if not source then | |
print('there is no current scene') | |
return | |
end | |
scene_width = obs.obs_source_get_width(source) | |
scene_height = obs.obs_source_get_height(source) | |
local scene = obs.obs_scene_from_source(source) | |
obs.obs_source_release(source) | |
scene_item = obs.obs_scene_find_source(scene, source_name) | |
if scene_item then | |
original_pos = get_scene_item_pos(scene_item) | |
return true | |
end | |
print(source_name..' not found') | |
return false | |
end | |
function get_scene_item_pos(scene_item) | |
local pos = obs.vec2() | |
obs.obs_sceneitem_get_pos(scene_item, pos) | |
return pos | |
end | |
local x,y = 0,0 | |
function move_scene_item(scene_item,absolute_progress) | |
absolute_progress = absolute_progress or false | |
if not scene_item then return end | |
local next_pos = obs.vec2() | |
if not absolute_progress then | |
x = x + 30 | |
y = y + 30 | |
else | |
x = absolute_progress | |
y = absolute_progress | |
end | |
next_pos.x,next_pos.y = x,y | |
obs.obs_sceneitem_set_pos(scene_item, next_pos) | |
end | |
function second_scene() | |
local tries = 15 | |
--print('start second scene') | |
repeat | |
time_sleep(0.3) | |
move_scene_item(scene_item) | |
tries = tries - 1 | |
until tries == 0 | |
--print('end second') | |
end | |
local pow = math.pow | |
-- https://github.com/EmmanuelOga/easing/blob/master/lib/easing.lua | |
function inOutExpo(t, b, c, d) | |
if t == 0 then return b end | |
if t == d then return b + c end | |
t = t / d * 2 | |
if t < 1 then | |
return c / 2 * pow(2, 10 * (t - 1)) + b - c * 0.0005 | |
else | |
t = t - 1 | |
return c / 2 * 1.0005 * (-pow(2, -10 * t) + 2) + b | |
end | |
end | |
function inOutQuart(t, b, c, d) | |
t = t / d * 2 | |
if t < 1 then | |
return c / 2 * pow(t, 4) + b | |
else | |
t = t - 2 | |
return -c / 2 * (pow(t, 4) - 2) + b | |
end | |
end | |
function easing_scene_item_movement(begin,end_val,duration) | |
local begin = begin or 500 | |
local end_val = end_val or 0 | |
local duration = duration or 0.6 | |
local current = 0 | |
local interval = 0.02 | |
local change = end_val - begin | |
repeat | |
--local absolute_progress = inOutExpo(current,begin,change,duration) | |
local absolute_progress = inOutQuart(current,begin,change,duration) | |
move_scene_item(scene_item,absolute_progress) | |
time_sleep(interval) | |
current = current + interval | |
until current >= duration | |
end | |
function easing_scene_loop() | |
while true do | |
easing_scene_item_movement(900,0,0.16) | |
easing_scene_item_movement(0,300) | |
time_sleep(0.1) | |
easing_scene_item_movement(300,600,0.8) | |
time_sleep(0.3) | |
easing_scene_item_movement(600,900,0.23) | |
end | |
end | |
local c1 = coroutine.create(current_scene) | |
--local c2 = coroutine.create(second_scene) -- move some source on scene with name c2c2 | |
local c2 = coroutine.create(easing_scene_loop) | |
local c3 = coroutine.create(infinity_scene) | |
local c4 = coroutine.create(function() coroutine.yield() end) | |
function delayed_print_logic() | |
print('hello') | |
time_sleep(3) | |
print('world') | |
end | |
function delayed_print() | |
if coroutine.status(c4) == 'dead' then | |
c4 = coroutine.create(delayed_print_logic) | |
end | |
end | |
function cancel_delayed_print() | |
print('abort printing') | |
c4 = nil | |
c4 = coroutine.create(function() coroutine.yield() end) | |
end | |
---[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[] | |
function script_tick(dt) | |
-- set c2c2 as source name within current scene | |
if not scene_item then find_scene_item() end | |
coroutine.resume(c1,dt) | |
coroutine.resume(c2,dt) | |
coroutine.resume(c3,dt) | |
coroutine.resume(c4,dt) | |
end | |
---[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[]-[] | |
function htk_1_cb(pressed) | |
if pressed then | |
delayed_print() | |
end | |
end | |
function htk_2_cb(pressed) | |
if pressed then | |
cancel_delayed_print() | |
end | |
end | |
key_1 = '{"htk_1": [ { "key": "OBS_KEY_1" } ],' | |
key_2 = '"htk_2": [ { "key": "OBS_KEY_2" } ]}' | |
json_s = key_1 .. key_2 | |
default_hotkeys = { | |
{id='htk_1',des='print with delay',callback=htk_1_cb}, | |
{id='htk_2',des='cancel delayed print',callback=htk_2_cb}, | |
} | |
function script_load(settings) | |
s = obs.obs_data_create_from_json(json_s) | |
for _,v in pairs(default_hotkeys) do | |
local a = obs.obs_data_get_array(s,v.id) | |
h = obs.obs_hotkey_register_frontend(v.id,v.des,v.callback) | |
obs.obs_hotkey_load(h,a) | |
obs.obs_data_array_release(a) | |
end | |
obs.obs_data_release(s) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment