From 42cbf4bab1077a131e8e6af1cbb05f7c57f4eff6 Mon Sep 17 00:00:00 2001
From: Nicolas Pope <nicolas.pope@utu.fi>
Date: Mon, 20 Jan 2020 10:48:27 +0200
Subject: [PATCH] Allow constructor parameters to operators

---
 .../include/ftl/operators/operator.hpp        | 25 +++++++++++++++++++
 .../include/ftl/operators/opticalflow.hpp     |  5 ++--
 components/operators/src/nvopticalflow.cpp    |  7 +++++-
 .../src/sources/stereovideo/stereovideo.cpp   |  2 +-
 4 files changed, 35 insertions(+), 4 deletions(-)

diff --git a/components/operators/include/ftl/operators/operator.hpp b/components/operators/include/ftl/operators/operator.hpp
index 71d2e939a..79cd008fd 100644
--- a/components/operators/include/ftl/operators/operator.hpp
+++ b/components/operators/include/ftl/operators/operator.hpp
@@ -72,6 +72,20 @@ struct ConstructionHelper : public ConstructionHelperBase {
 	}
 };
 
+template <typename T, typename... ARGS>
+struct ConstructionHelper2 : public ConstructionHelperBase {
+	explicit ConstructionHelper2(ftl::Configurable *cfg, ARGS... args) : ConstructionHelperBase(cfg) {
+		arguments_ = std::make_tuple(args...);
+	}
+	~ConstructionHelper2() {}
+	ftl::operators::Operator *make() override {
+		return new T(config, arguments_);
+	}
+
+	private:
+	std::tuple<ARGS...> arguments_;
+};
+
 struct OperatorNode {
 	ConstructionHelperBase *maker;
 	std::vector<ftl::operators::Operator*> instances;
@@ -92,6 +106,9 @@ class Graph : public ftl::Configurable {
 	template <typename T>
 	ftl::Configurable *append(const std::string &name);
 
+	template <typename T, typename... ARGS>
+	ftl::Configurable *append(const std::string &name, ARGS...);
+
 	bool apply(ftl::rgbd::Frame &in, ftl::rgbd::Frame &out, cudaStream_t stream=0);
 	bool apply(ftl::rgbd::FrameSet &in, ftl::rgbd::FrameSet &out, cudaStream_t stream=0);
 	bool apply(ftl::rgbd::FrameSet &in, ftl::rgbd::Frame &out, cudaStream_t stream=0);
@@ -115,4 +132,12 @@ ftl::Configurable *ftl::operators::Graph::append(const std::string &name) {
 	return _append(new ftl::operators::detail::ConstructionHelper<T>(configs_[name]));
 }
 
+template <typename T, typename... ARGS>
+ftl::Configurable *ftl::operators::Graph::append(const std::string &name, ARGS... args) {
+	if (configs_.find(name) == configs_.end()) {
+		configs_[name] = ftl::create<ftl::Configurable>(this, name);
+	}
+	return _append(new ftl::operators::detail::ConstructionHelper2<T, ARGS...>(configs_[name], args...));
+}
+
 #endif  // _FTL_OPERATORS_OPERATOR_HPP_
diff --git a/components/operators/include/ftl/operators/opticalflow.hpp b/components/operators/include/ftl/operators/opticalflow.hpp
index e80160631..43edf6b84 100644
--- a/components/operators/include/ftl/operators/opticalflow.hpp
+++ b/components/operators/include/ftl/operators/opticalflow.hpp
@@ -13,6 +13,7 @@ namespace operators {
 class NVOpticalFlow : public ftl::operators::Operator {
 	public:
 	explicit NVOpticalFlow(ftl::Configurable*);
+	NVOpticalFlow(ftl::Configurable*, const std::tuple<ftl::codecs::Channel,ftl::codecs::Channel> &channels);
 	~NVOpticalFlow();
 
 	inline Operator::Type type() const override { return Operator::Type::OneToOne; }
@@ -26,8 +27,8 @@ class NVOpticalFlow : public ftl::operators::Operator {
 	cv::Size size_;
 	
 	// TODO: Colour to Flow always assumed, could also calculate something else?
-	const ftl::codecs::Channel channel_in_ = ftl::codecs::Channel::Colour;
-	const ftl::codecs::Channel channel_out_ = ftl::codecs::Channel::Flow;
+	ftl::codecs::Channel channel_in_;
+	ftl::codecs::Channel channel_out_;
 
 	cv::Ptr<cv::cuda::NvidiaOpticalFlow_1_0> nvof_;
 	cv::cuda::GpuMat left_gray_;
diff --git a/components/operators/src/nvopticalflow.cpp b/components/operators/src/nvopticalflow.cpp
index 6ce98d757..08da949e0 100644
--- a/components/operators/src/nvopticalflow.cpp
+++ b/components/operators/src/nvopticalflow.cpp
@@ -10,10 +10,15 @@ using cv::Size;
 using cv::cuda::GpuMat;
 
 NVOpticalFlow::NVOpticalFlow(ftl::Configurable* cfg) :
-		ftl::operators::Operator(cfg) {
+		ftl::operators::Operator(cfg), channel_in_(ftl::codecs::Channel::Colour), channel_out_(ftl::codecs::Channel::Flow) {
 	size_ = Size(0, 0);
 }
 
+NVOpticalFlow::NVOpticalFlow(ftl::Configurable*cfg, const std::tuple<ftl::codecs::Channel,ftl::codecs::Channel> &channels) : ftl::operators::Operator(cfg) {
+	channel_in_ = std::get<0>(channels);
+	channel_out_ = std::get<1>(channels);
+}
+
 NVOpticalFlow::~NVOpticalFlow() {
 }
 
diff --git a/components/rgbd-sources/src/sources/stereovideo/stereovideo.cpp b/components/rgbd-sources/src/sources/stereovideo/stereovideo.cpp
index 3a0587ebb..584796770 100644
--- a/components/rgbd-sources/src/sources/stereovideo/stereovideo.cpp
+++ b/components/rgbd-sources/src/sources/stereovideo/stereovideo.cpp
@@ -76,7 +76,7 @@ void StereoVideoSource::init(const string &file) {
 
 	pipeline_input_ = ftl::config::create<ftl::operators::Graph>(host_, "input");
 	#ifdef HAVE_OPTFLOW
-	pipeline_input_->append<ftl::operators::NVOpticalFlow>("optflow");
+	pipeline_input_->append<ftl::operators::NVOpticalFlow>("optflow", Channel::Colour, Channel::Flow);
 	#endif
 
 	calib_ = ftl::create<Calibrate>(host_, "calibration", cv::Size(lsrc_->fullWidth(), lsrc_->fullHeight()), stream_);
-- 
GitLab