]> git.sesse.net Git - nageru/commitdiff
Make it possible to set channel names imperatively instead of using a callback.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 21 Jun 2019 17:31:28 +0000 (19:31 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Fri, 21 Jun 2019 17:44:11 +0000 (19:44 +0200)
channel_name() will still be used if it exists, for compatibility with older
themes.

nageru/simple.lua
nageru/theme.cpp
nageru/theme.h
nageru/theme.lua

index 3960505175e9637d1a2f627e1586c83691c59d41..8d5b3e673c1266a788d8eea043a337411a99b9bb 100644 (file)
@@ -32,17 +32,9 @@ function num_channels()
        return 2
 end
 
--- API ENTRY POINT
--- Returns the name for each additional channel (starting from 2).
--- Called at the start of the program, and then each frame for live
--- channels in case they change resolution.
-function channel_name(channel)
-       if channel == 2 then
-               return "First input"
-       elseif channel == 3 then
-               return "Second input"
-       end
-end
+-- Set some global state.
+Nageru.set_channel_name(2, "First input")
+Nageru.set_channel_name(3, "Second input")
 
 -- API ENTRY POINT
 -- Returns, given a channel number, which signal it corresponds to (starting from 0).
index 8050003b2025459651d20a99dea5f4d120347da3..6a4de4baa248ece934994332de8d559b29736010 100644 (file)
@@ -1223,6 +1223,17 @@ int call_num_channels(lua_State *L)
 
 }  // namespace
 
+int Nageru_set_channel_name(lua_State *L)
+{
+       // NOTE: m is already locked.
+       Theme *theme = get_theme_updata(L);
+       unsigned channel = luaL_checknumber(L, 1);
+       const string text = checkstdstring(L, 2);
+       theme->channel_names[channel] = text;
+       lua_pop(L, 2);
+       return 0;
+}
+
 Theme::Theme(const string &filename, const vector<string> &search_dirs, ResourcePool *resource_pool, unsigned num_cards)
        : resource_pool(resource_pool), num_cards(num_cards), signal_to_card_mapping(global_flags.default_stream_mapping)
 {
@@ -1293,7 +1304,7 @@ Theme::Theme(const string &filename, const vector<string> &search_dirs, Resource
        }
 
        // Set up the API we provide.
-       register_constants();
+       register_globals();
        register_class("Scene", Scene_funcs);
        register_class("Block", Block_funcs);
        register_class("EffectBlueprint", EffectBlueprint_funcs);
@@ -1334,7 +1345,7 @@ Theme::~Theme()
        lua_close(L);
 }
 
-void Theme::register_constants()
+void Theme::register_globals()
 {
        // Set Nageru.VIDEO_FORMAT_BGRA = bmusb::PixelFormat_8BitBGRA, etc.
        const vector<pair<string, int>> num_constants = {
@@ -1358,6 +1369,13 @@ void Theme::register_constants()
                lua_settable(L, 1);  // t[key] = value
        }
 
+       const luaL_Reg Nageru_funcs[] = {
+               { "set_channel_name", Nageru_set_channel_name },
+               { NULL, NULL }
+       };
+       lua_pushlightuserdata(L, this);
+       luaL_setfuncs(L, Nageru_funcs, 1);        // for (name,f in funcs) { mt[name] = f, with upvalue {theme} }
+
        lua_setglobal(L, "Nageru");  // Nageru = t
        assert(lua_gettop(L) == 0);
 }
@@ -1484,7 +1502,17 @@ Theme::Chain Theme::get_chain(unsigned num, float t, unsigned width, unsigned he
 string Theme::get_channel_name(unsigned channel)
 {
        lock_guard<mutex> lock(m);
+
        lua_getglobal(L, "channel_name");
+       if (lua_isnil(L, -1)) {
+               lua_pop(L, 1);
+               if (channel_names.count(channel)) {
+                       return channel_names[channel];
+               } else {
+                       return "(no title)";
+               }
+       }
+
        lua_pushnumber(L, channel);
        if (lua_pcall(L, 1, 1, 0) != 0) {
                fprintf(stderr, "error running function `channel_name': %s\n", lua_tostring(L, -1));
index 2fac7963346a2f3034041bd9ed089c8e24650d59..794542525e9e84f60f65679b63cab8d6ae85b469 100644 (file)
@@ -180,7 +180,7 @@ public:
        }
 
 private:
-       void register_constants();
+       void register_globals();
        void register_class(const char *class_name, const luaL_Reg *funcs, EffectType effect_type = NO_EFFECT_TYPE);
        int set_theme_menu(lua_State *L);
        Chain get_chain_from_effect_chain(movit::EffectChain *effect_chain, unsigned num, const InputState &input_state);
@@ -217,9 +217,12 @@ private:
        std::unique_ptr<MenuEntry> theme_menu;
        std::function<void()> theme_menu_callback;
 
+       std::map<unsigned, std::string> channel_names;  // Set using Nageru.set_theme(). Protected by <m>.
+
        friend class LiveInputWrapper;
        friend class Scene;
        friend int ThemeMenu_set(lua_State *L);
+       friend int Nageru_set_channel_name(lua_State *L);
 };
 
 // LiveInputWrapper is a facade on top of an YCbCrInput, exposed to
index de8d25222e9492e1118d94897bc7c0fc9743750f..c762a3f6d82ce1fafe1995d3f1de7ca988a2ab40 100644 (file)
@@ -36,11 +36,6 @@ local NO_TRANSITION = 0
 local ZOOM_TRANSITION = 1  -- Also for slides.
 local FADE_TRANSITION = 2
 
--- Last width/height/frame rate for each channel, if we have it.
--- Note that unlike the values we get from Nageru, the resolution is per
--- frame and not per field, since we deinterlace.
-local last_resolution = {}
-
 function make_sbs_input(scene)
        return {
                input = scene:add_input(),
@@ -115,6 +110,10 @@ local static_scene = Scene.new(16, 9)
 static_scene:add_input(static_image)  -- Note: Locks this input to images only.
 static_scene:finalize()
 
+-- Set some global state.
+Nageru.set_channel_name(SBS_SIGNAL_NUM + 2, "Side-by-side")
+Nageru.set_channel_name(STATIC_SIGNAL_NUM + 2, "Static picture")
+
 -- API ENTRY POINT
 -- Returns the number of outputs in addition to the live (0) and preview (1).
 -- Called only once, at the start of the program.
@@ -126,25 +125,6 @@ function is_plain_signal(num)
        return num == INPUT0_SIGNAL_NUM or num == INPUT1_SIGNAL_NUM
 end
 
--- API ENTRY POINT
--- Returns the name for each additional channel (starting from 2).
--- Called at the start of the program, and then each frame for live
--- channels in case they change resolution.
-function channel_name(channel)
-       local signal_num = channel - 2
-       if is_plain_signal(signal_num) then
-               if last_resolution[signal_num] then
-                       return "Input " .. (signal_num + 1) .. " (" .. last_resolution[signal_num].human_readable_resolution .. ")"
-               else
-                       return "Input " .. (signal_num + 1)
-               end
-       elseif signal_num == SBS_SIGNAL_NUM then
-               return "Side-by-side"
-       elseif signal_num == STATIC_SIGNAL_NUM then
-               return "Static picture"
-       end
-end
-
 -- API ENTRY POINT
 -- Returns, given a channel number, which signal it corresponds to (starting from 0).
 -- Should return -1 if the channel does not correspond to a simple signal
@@ -397,8 +377,7 @@ function get_scene(num, t, width, height, signals)
                        is_connected = signals:get_is_connected(signal_num),
                        has_signal = signals:get_has_signal(signal_num),
                        frame_rate_nom = signals:get_frame_rate_nom(signal_num),
-                       frame_rate_den = signals:get_frame_rate_den(signal_num),
-                       human_readable_resolution = signals:get_human_readable_resolution(signal_num)
+                       frame_rate_den = signals:get_frame_rate_den(signal_num)
                }
 
                if res.interlaced then
@@ -413,8 +392,10 @@ function get_scene(num, t, width, height, signals)
                end
 
                input_resolution[signal_num] = res
+
+               local text_res = signals:get_human_readable_resolution(signal_num)
+               Nageru.set_channel_name(signal_num + 2, "Input " .. (signal_num + 1) .. " (" .. text_res .. ")")
        end
-       last_resolution = input_resolution
 
        if num == 0 then  -- Live.
                finish_transitions(t)