From fb487caec38c0da7a43bab850af6aa79b07befde Mon Sep 17 00:00:00 2001
From: Romain Forlot <romain.forlot@iot.bzh>
Date: Tue, 5 Dec 2017 16:51:25 +0100
Subject: Hold all contexts (plugin & source) in signalCtx_

Keeping persistence between call data are kept in that member
also subscription Action now use getSignals_ context and no more
the signal one, this is more accurate and simples

Change-Id: Idd7c56ba30f1daa9eaf9b99a7261d58189ef0bb2
Signed-off-by: Romain Forlot <romain.forlot@iot.bzh>
---
 signal-composer-binding/signal-composer.cpp |  1 +
 signal-composer-binding/signal.cpp          | 41 ++++++++++++++++++++++++-----
 signal-composer-binding/signal.hpp          |  2 ++
 signal-composer-binding/source.cpp          |  6 +++--
 4 files changed, 41 insertions(+), 9 deletions(-)

(limited to 'signal-composer-binding')

diff --git a/signal-composer-binding/signal-composer.cpp b/signal-composer-binding/signal-composer.cpp
index dedd4b3..3ad2d4e 100644
--- a/signal-composer-binding/signal-composer.cpp
+++ b/signal-composer-binding/signal-composer.cpp
@@ -58,6 +58,7 @@ static struct signalCBT pluginHandle = {
 	.searchNsetSignalValue = searchNsetSignalValueHandle,
 	.setSignalValue = setSignalValueHandle,
 	.aSignal = nullptr,
+	.pluginCtx = nullptr,
 };
 
 CtlSectionT Composer::ctlSections_[] = {
diff --git a/signal-composer-binding/signal.cpp b/signal-composer-binding/signal.cpp
index e7156dc..c09e059 100644
--- a/signal-composer-binding/signal.cpp
+++ b/signal-composer-binding/signal.cpp
@@ -34,6 +34,7 @@ Signal::Signal()
  unit_(""),
  onReceived_(nullptr),
  getSignalsArgs_(nullptr),
+ signalCtx_(new struct signalCBT),
  subscribed_(false)
 {}
 
@@ -48,6 +49,7 @@ Signal::Signal(const std::string& id, const std::string& event, std::vector<std:
  unit_(unit),
  onReceived_(onReceived),
  getSignalsArgs_(getSignalsArgs),
+ signalCtx_(new struct signalCBT),
  subscribed_(false)
 {}
 
@@ -67,11 +69,13 @@ Signal::Signal(const std::string& id,
  unit_(unit),
  onReceived_(onReceived),
  getSignalsArgs_(),
+ signalCtx_(new struct signalCBT),
  subscribed_(false)
 {}
 
 Signal::~Signal()
 {
+	delete(signalCtx_);
 	delete(onReceived_);
 }
 
@@ -126,9 +130,16 @@ json_object* Signal::toJSON() const
 			"uid", id_.c_str(),
 			"getSignalsArgs", getSignalsArgs_);
 
-	if (!event_.empty()) {json_object_object_add(queryJ, "event", json_object_new_string(event_.c_str()));}
-	if (json_object_array_length(nameArrayJ)) {json_object_object_add(queryJ, "depends", nameArrayJ);}
+	if (!event_.empty())
+		{json_object_object_add(queryJ, "event", json_object_new_string(event_.c_str()));}
+
+	if (json_object_array_length(nameArrayJ))
+		{json_object_object_add(queryJ, "depends", nameArrayJ);}
+	else
+		{json_object_put(nameArrayJ);}
+
 	if (!unit_.empty()) {json_object_object_add(queryJ, "unit", json_object_new_string(unit_.c_str()));}
+
 	if (frequency_) {json_object_object_add(queryJ, "frequency", json_object_new_double(frequency_));}
 
 	if(timestamp_) {json_object_object_add(queryJ, "timestamp", json_object_new_int64(timestamp_));}
@@ -140,15 +151,31 @@ json_object* Signal::toJSON() const
 	return queryJ;
 }
 
+/// @brief Initialize signal context if not already done and return it.
+///  Signal context is a handle to be use by plugins then they can call
+///  some signal object method setting signal values.
+///  Also if plugin set a context it retrieve it and initiaze the pluginCtx
+///  member then plugin can find a persistent memory area where to hold its
+///  value.
+///
+/// @return a pointer to the signalCtx_ member initialized.
 struct signalCBT* Signal::get_context()
 {
-	struct signalCBT* ctx =	new struct signalCBT;
+	if(!signalCtx_->aSignal ||
+		!signalCtx_->searchNsetSignalValue ||
+		!signalCtx_->setSignalValue)
+	{
+		signalCtx_->searchNsetSignalValue = searchNsetSignalValueHandle;
+		signalCtx_->setSignalValue = setSignalValueHandle;
+
+		signalCtx_->aSignal = (void*)this;
 
-	ctx->searchNsetSignalValue = searchNsetSignalValueHandle;
-	ctx->setSignalValue = setSignalValueHandle;
+		signalCtx_->pluginCtx = onReceived_ && onReceived_->type == CTL_TYPE_CB ?
+			onReceived_->exec.cb.plugin->context:
+			nullptr;
+	}
 
-	ctx->aSignal = (void*)this;
-	return ctx;
+	return signalCtx_;
 }
 
 /// @brief Set Signal timestamp and value property when an incoming
diff --git a/signal-composer-binding/signal.hpp b/signal-composer-binding/signal.hpp
index 97ab4c7..0fbb0a6 100644
--- a/signal-composer-binding/signal.hpp
+++ b/signal-composer-binding/signal.hpp
@@ -73,6 +73,7 @@ private:
 	std::string unit_;
 	CtlActionT* onReceived_;
 	json_object* getSignalsArgs_;
+	struct signalCBT* signalCtx_;
 
 public:
 	bool subscribed_; ///< subscribed_ - boolean value telling if yes or no the signal has been subcribed to the low level binding.
@@ -114,4 +115,5 @@ struct signalCBT
 	void (*searchNsetSignalValue)(const char* aName, uint64_t timestamp, struct signalValue value);
 	void (*setSignalValue)(void* aSignal, uint64_t timestamp, struct signalValue value);
 	void* aSignal;
+	void* pluginCtx;
 };
diff --git a/signal-composer-binding/source.cpp b/signal-composer-binding/source.cpp
index 6ad9511..3180513 100644
--- a/signal-composer-binding/source.cpp
+++ b/signal-composer-binding/source.cpp
@@ -113,11 +113,13 @@ void SourceAPI::makeSubscription()
 				break;
 			}
 			source.uid = sig.first.c_str();
-			source.context = (void*)sig.second->get_context();
+			source.context = getSignals_->type == CTL_TYPE_CB ?
+				getSignals_->exec.cb.plugin->context:
+				nullptr;
 			ActionExecOne(&source, getSignals_, signalJ);
 			// Considerate signal subscribed no matter what
 			sig.second->subscribed_ = true;
-			delete((struct signalCBT*)source.context);
+			json_object_put(signalJ);
 		}
 		source.uid = "";
 		ActionExecOne(&source, getSignals_, nullptr);
-- 
cgit