]> git.sesse.net Git - casparcg/commitdiff
More binding functionality
authorHelge Norberg <helge.norberg@svt.se>
Thu, 4 Jul 2013 18:03:21 +0000 (20:03 +0200)
committerHelge Norberg <helge.norberg@svt.se>
Thu, 4 Jul 2013 18:03:21 +0000 (20:03 +0200)
core/producer/binding.h
core/producer/scene/scene_producer.cpp
core/producer/scene/scene_producer.h

index d2b4be4858d2ebf64510d5c9c3d27ad628914b0e..e3ae993c75b63b36b328a67c0adeb52a79d30f46 100644 (file)
 
 namespace caspar { namespace core {
 
-template <typename T>
-class binding
+namespace detail {
+
+struct impl_base : std::enable_shared_from_this<impl_base>
 {
-private:
-       struct impl_base : std::enable_shared_from_this<impl_base>
+       std::vector<std::shared_ptr<impl_base>> dependencies_;
+       mutable std::vector<std::pair<
+                       std::weak_ptr<void>,
+                       std::function<void ()>>> on_change_;
+
+       virtual ~impl_base()
        {
-               std::vector<std::shared_ptr<impl_base>> dependencies_;
-               mutable std::vector<std::pair<
-                               std::weak_ptr<void>,
-                               std::function<void ()>>> on_change_;
+       }
 
-               virtual ~impl_base()
-               {
-               }
+       virtual void evaluate() = 0;
 
-               virtual void evaluate() = 0;
+       void depend_on(const std::shared_ptr<impl_base>& dependency)
+       {
+               dependency->on_change(shared_from_this(), [=] { evaluate(); });
+               dependencies_.push_back(dependency);
+       }
 
-               void depend_on(const std::shared_ptr<impl_base>& dependency)
-               {
-                       dependency->on_change(shared_from_this(), [=] { evaluate(); });
-                       dependencies_.push_back(dependency);
-               }
+       void on_change(
+                       const std::weak_ptr<void>& dependant,
+                       const std::function<void ()>& listener) const
+       {
+               on_change_.push_back(std::make_pair(dependant, listener));
+       }
+};
 
-               void on_change(
-                               const std::weak_ptr<void>& dependant,
-                               const std::function<void ()>& listener) const
-               {
-                       on_change_.push_back(std::make_pair(dependant, listener));
-               }
-       };
+}
 
-       struct impl : public impl_base
+template <typename T>
+class binding
+{
+private:
+
+       struct impl : public detail::impl_base
        {
                T value_;
                std::function<T ()> expression_;
@@ -153,6 +158,8 @@ private:
                }
        };
 
+       template<typename> friend class binding;
+
        std::shared_ptr<impl> impl_;
 public:
        binding()
@@ -205,18 +212,15 @@ public:
                return impl_->bound();
        }
 
-       void depend_on(const binding<T>& other)
+       template<typename T2>
+       void depend_on(const binding<T2>& other)
        {
                impl_->depend_on(other.impl_);
        }
 
        binding<T> operator+(T other) const
        {
-               auto self = impl_;
-
-               return binding<T>(
-                               [other, self] { return other + self->get(); },
-                               *this);
+               return transformed([other](T self) { return self + other; });
        }
 
        binding<T> operator+(const binding<T>& other) const
@@ -232,11 +236,7 @@ public:
 
        binding<T> operator-() const
        {
-               auto self = impl_;
-
-               return binding<T>(
-                               [self] { return -self->get(); },
-                               *this);
+               return transformed([](T self) { return -self; });
        }
 
        binding<T> operator-(const binding<T>& other) const
@@ -251,11 +251,7 @@ public:
 
        binding<T> operator*(T other) const
        {
-               auto self = impl_;
-
-               return binding<T>(
-                               [other, self] { return other * self->get(); },
-                               *this);
+               return transformed([other](T self) { return self * other; });
        }
 
        binding<T> operator*(const binding<T>& other) const
@@ -271,11 +267,7 @@ public:
 
        binding<T> operator/(T other) const
        {
-               auto self = impl_;
-
-               return binding<T>(
-                               [other, self] { return self->get() / other; },
-                               *this);
+               return transformed([other](T self) { return self / other; });
        }
 
        binding<T> operator/(const binding<T>& other) const
@@ -291,11 +283,7 @@ public:
 
        binding<bool> operator==(T other) const
        {
-               auto self = impl_;
-
-               return binding<bool>(
-                               [other, self] { return self->get() == other; },
-                               *this);
+               return transformed([other](T self) { return self == other; });
        }
 
        binding<bool> operator==(const binding<T>& other) const
@@ -311,11 +299,7 @@ public:
 
        binding<bool> operator!=(T other) const
        {
-               auto self = impl_;
-
-               return binding<bool>(
-                               [other, self] { return self->get() != other; },
-                               *this);
+               return transformed([other](T self) { return self != other; });
        }
 
        binding<bool> operator!=(const binding<T>& other) const
@@ -329,6 +313,23 @@ public:
                                other);
        }
 
+       template<typename T2>
+       binding<T2> as() const
+       {
+               return transformed([](T val) { return static_cast<T2>(val); });
+       }
+
+       template<typename Func>
+       auto transformed(const Func& func) const -> binding<decltype(func(impl_->value_))>
+       {
+               typedef decltype(func(impl_->value_)) R;
+               auto self = impl_;
+
+               return binding<R>(
+                               [self, func] { return func(self->get()); },
+                               *this);
+       }
+
        void unbind()
        {
                impl_->unbind();
index d85cebb5bc65165c6aaf6b72bfbb86f900598a28..c663bc0405829c6040380a66ecb240ca63ab45c6 100644 (file)
@@ -41,8 +41,9 @@ adjustments::adjustments()
 struct scene_producer::impl
 {
        constraints pixel_constraints_;
-       std::vector<layer> layers_;
+       std::list<layer> layers_;
        interaction_aggregator aggregator_;
+       binding<int64_t> frame_number_;
 
        impl(int width, int height)
                : pixel_constraints_(width, height)
@@ -53,16 +54,28 @@ struct scene_producer::impl
        layer& create_layer(
                        const spl::shared_ptr<frame_producer>& producer, int x, int y)
        {
-               layer layer(producer);
+               layer& layer = create_layer(producer);
 
                layer.position.x.set(x);
                layer.position.y.set(y);
 
+               return layer;
+       }
+
+       layer& create_layer(const spl::shared_ptr<frame_producer>& producer)
+       {
+               layer layer(producer);
+
                layers_.push_back(layer);
 
                return layers_.back();
        }
 
+       binding<int64_t> frame()
+       {
+               return frame_number_;
+       }
+
        frame_transform get_transform(const layer& layer) const
        {
                frame_transform transform;
@@ -94,6 +107,8 @@ struct scene_producer::impl
                        frames.push_back(frame);
                }
 
+               frame_number_.set(frame_number_.get() + 1);
+
                return draw_frame(frames);
        }
 
@@ -168,6 +183,17 @@ layer& scene_producer::create_layer(
        return impl_->create_layer(producer, x, y);
 }
 
+layer& scene_producer::create_layer(
+               const spl::shared_ptr<frame_producer>& producer)
+{
+       return impl_->create_layer(producer);
+}
+
+binding<int64_t> scene_producer::frame()
+{
+       return impl_->frame();
+}
+
 draw_frame scene_producer::receive_impl()
 {
        return impl_->render_frame();
@@ -215,13 +241,13 @@ spl::shared_ptr<frame_producer> create_dummy_scene_producer(const spl::shared_pt
        if (params.size() < 1 || params.at(0) != L"[SCENE]")
                return core::frame_producer::empty();
 
-       auto scene = spl::make_shared<scene_producer>(160, 90);
+       auto scene = spl::make_shared<scene_producer>(1280, 720);
 
-       std::vector<std::wstring> sub_params;
 
-       binding<int> text_width(10);
-       binding<int> padding(1);
-       binding<int> panel_width = padding + text_width + padding;
+       binding<double> text_width(10);
+       binding<double> padding(1);
+       binding<double> panel_width = padding + text_width + padding;
+       binding<double> panel_height(50);
 
        auto subscription = panel_width.on_change([&]
        {
@@ -233,19 +259,47 @@ spl::shared_ptr<frame_producer> create_dummy_scene_producer(const spl::shared_pt
        padding.set(2);
        text_width.set(20);
 
+       auto create_param = [](std::wstring elem) -> std::vector<std::wstring>
+       {
+               std::vector<std::wstring> result;
+               result.push_back(elem);
+               return result;
+       };
+
+       scene->create_layer(create_producer(frame_factory, format_desc, create_param(L"car")));
+       std::vector<std::wstring> sub_params;
        sub_params.push_back(L"[FREEHAND]");
-       sub_params.push_back(L"100");
-       sub_params.push_back(L"50");
+       sub_params.push_back(L"640");
+       sub_params.push_back(L"360");
        scene->create_layer(create_producer(frame_factory, format_desc, sub_params), 10, 10);
        sub_params.clear();
 
-       sub_params.push_back(L"BLUE");
-       scene->create_layer(create_producer(frame_factory, format_desc, sub_params), 110, 10);
-       sub_params.clear();
-
-       sub_params.push_back(L"SP");
-       scene->create_layer(create_producer(frame_factory, format_desc, sub_params), 50, 50);
-       sub_params.clear();
+       scene->create_layer(create_producer(frame_factory, format_desc, create_param(L"BLUE")), 110, 10);
+
+       //scene->create_layer(create_producer(frame_factory, format_desc, create_param(L"SP")), 50, 50);
+
+       auto& upper_left = scene->create_layer(create_producer(frame_factory, format_desc, create_param(L"scene/upper_left")));
+       auto& upper_right = scene->create_layer(create_producer(frame_factory, format_desc, create_param(L"scene/upper_right")));
+       auto& lower_left = scene->create_layer(create_producer(frame_factory, format_desc, create_param(L"scene/lower_left")));
+       auto& lower_right = scene->create_layer(create_producer(frame_factory, format_desc, create_param(L"scene/lower_right")));
+
+       binding<double> panel_x = scene->frame()
+                       .as<double>()
+                       .transformed([](double v) { return std::sin(v / 20.0); })
+                       * 20.0
+                       + 40.0;
+       binding<double> panel_y(500);
+       upper_left.position.x = panel_x;
+       upper_left.position.y = panel_y;
+       upper_right.position.x = upper_left.position.x + upper_left.producer.get()->pixel_constraints().width + panel_width;
+       upper_right.position.y = upper_left.position.y;
+       lower_left.position.x = upper_left.position.x;
+       lower_left.position.y = upper_left.position.y + upper_left.producer.get()->pixel_constraints().height + panel_height;
+       lower_right.position.x = upper_right.position.x;
+       lower_right.position.y = lower_left.position.y;
+
+       text_width.set(500);
+       panel_height.set(50);
 
        return scene;
 }
index 1e4d3472211a10361dd5963a9db3fa2f9464df30..e444f031d66b1e4aaa5cf95d778056a1cb40d0b5 100644 (file)
@@ -69,6 +69,8 @@ public:
        void unsubscribe(const monitor::observable::observer_ptr& o) override;
        layer& create_layer(
                        const spl::shared_ptr<frame_producer>& producer, int x, int y);
+       layer& create_layer(const spl::shared_ptr<frame_producer>& producer);
+       binding<int64_t> frame();
 private:
        struct impl;
        std::unique_ptr<impl> impl_;