]> git.sesse.net Git - nageru/blobdiff - nageru/scene.h
Unbreak showing the first two channels in the tally JSON.
[nageru] / nageru / scene.h
index bdd5d7c78c924aa561567ff55a74a42492406cc0..4e1181bbf4cf9f504625d5eae9708db79a057ba1 100644 (file)
@@ -13,6 +13,7 @@
 // (directly to screen, RGBA) or live (Y'CbCr output).
 
 #include <stddef.h>
+#include <bitset>
 #include <functional>
 #include <map>
 #include <memory>
@@ -77,13 +78,36 @@ struct Block {
        size_t cardinality_base = 0;
 
        // Find the chosen alternative for this block in a given instance.
-       size_t chosen_alternative(size_t chain_idx) const {
-               return (chain_idx / cardinality_base) % alternatives.size();
+       int chosen_alternative(size_t chain_idx) const {
+               if (chain_idx == size_t(-1)) {
+                       return currently_chosen_alternative;
+               } else {
+                       return (chain_idx / cardinality_base) % alternatives.size();
+               }
        }
 
        std::vector<EffectBlueprint *> alternatives;  // Must all have the same amount of inputs. Pointers to make things easier for Lua.
        std::vector<Index> inputs;  // One for each input of alternatives[0] (ie., typically 0 or 1, occasionally 2).
+
+       // If any of these effects are disabled (IdentityEffect chosen)
+       // or enabled (not chosen) as determined by <condition>, so should this one.
+       struct Disabler {
+               Index block_idx;
+               enum {
+                       DISABLE_IF_OTHER_DISABLED,
+
+                       // This a promise from the user; ie., we don't disable automatically
+                       // (see comments in find_disabled_blocks()).
+                       DISABLE_IF_OTHER_ENABLED
+               } condition;
+               std::string declaration_point;  // For error messages.
+       };
+       std::vector<Disabler> disablers;
        int currently_chosen_alternative = 0;
+       // What alternative to use if the block is disabled.
+       // Points to an alternative with IDENTITY_EFFECT if it exists
+       // (to disable as much as possible), otherwise 0.
+       int canonical_alternative = 0;
        bool is_input = false;
 
        // For LIVE_INPUT* only. We can't just always populate signal_to_connect,
@@ -105,6 +129,12 @@ struct Block {
        std::map<std::string, float> float_parameters;
        std::map<std::string, std::array<float, 3>> vec3_parameters;
        std::map<std::string, std::array<float, 4>> vec4_parameters;
+
+       std::string declaration_point;  // For error messages.
+
+       // Only for AUTO_WHITE_BALANCE_EFFECT. Points to the parent block with is_input = true,
+       // so that we know which signal to get the white balance from.
+       const Block *white_balance_controller_block = nullptr;
 };
 
 int Block_display(lua_State* L);
@@ -112,6 +142,8 @@ int Block_choose(lua_State* L);
 int Block_enable(lua_State *L);
 int Block_enable_if(lua_State *L);
 int Block_disable(lua_State *L);
+int Block_always_disable_if_disabled(lua_State *L);
+int Block_promise_to_disable_if_enabled(lua_State *L);
 int Block_set_int(lua_State *L);
 int Block_set_float(lua_State *L);
 int Block_set_vec3(lua_State *L);
@@ -133,8 +165,32 @@ private:
        movit::ResourcePool *resource_pool;
 
        movit::Effect *instantiate_effects(const Block *block, size_t chain_idx, Instantiation *instantiation);
-       size_t compute_chain_number_for_block(size_t block_idx) const;
-       static void find_inputs_for_block(lua_State *L, Scene *scene, Block *block);
+       size_t compute_chain_number_for_block(size_t block_idx, const std::bitset<256> &disabled) const;
+       static void find_inputs_for_block(lua_State *L, Scene *scene, Block *block, int first_input_idx = 3);
+       static Block *find_block_from_arg(lua_State *L, Scene *scene, int idx);
+
+       // Find out which blocks (indexed by position in the “blocks” array),
+       // if any, are disabled in a given instantiation. A disabled block is
+       // one that will not be instantiated at all, because it is a secondary
+       // (ie., not the first) input of some multi-input effect that was replaced
+       // with IdentityEffect in the given instantiation.
+       //
+       // Set chain_idx to size_t(-1) to use whatever is in each block's
+       // currently_chosen_alternative.
+       std::bitset<256> find_disabled_blocks(size_t chain_idx) const;
+       void find_disabled_blocks(size_t chain_idx, size_t block_idx, bool currently_disabled, std::bitset<256> *disabled) const;
+
+       // If a block is disabled, it should always have canonical_alternative chosen,
+       // so that we don't instantiate a bunch of irrelevant duplicates that
+       // differ only in disabled blocks. You can check this property with
+       // is_noncanonical_chain() and then avoid instantiating the ones where
+       // it returns true.
+       bool is_noncanonical_chain(size_t chain_idx) const;
+
+       // For a given block, find any parents it may have that are inputs.
+       // If there is more than one, throws an error. If there are zero,
+       // returns nullptr (should probably also be an error).
+       const Block *find_root_input_block(lua_State *L, const Block *block);
 
 public:
        Scene(Theme *theme, float aspect_nom, float aspect_denom);
@@ -146,6 +202,7 @@ public:
        static int add_input(lua_State *L);
        static int add_effect(lua_State *L);
        static int add_optional_effect(lua_State *L);
+       static int add_auto_white_balance(lua_State *L);
        static int finalize(lua_State *L);
 };