فهرست منبع

GUI: add connection

Willi Zschiebsch 4 سال پیش
والد
کامیت
a60a716d29

+ 2 - 2
lib/include/Connector.h

@@ -17,9 +17,9 @@ namespace mdd {
 		Registration regi = Registration();
 		IProcessor::Ptr _root;
 		const std::map<const std::string, std::function<json(const json&)>> _ops = {//const std::map<const std::string, const json& (Connector::*)(const json&)> _ops = {
-			{"add", std::bind(&Connector::add,this,std::placeholders::_1) },/*
+			{"add", std::bind(&Connector::add,this,std::placeholders::_1) },
 			{"remove", std::bind(&Connector::remove,this,std::placeholders::_1)},
-			{"change", std::bind(&Connector::change,this,std::placeholders::_1)},*/
+			{"change", std::bind(&Connector::change,this,std::placeholders::_1)},
 			{"state", std::bind(&Connector::state,this,std::placeholders::_1)}
         };
 

+ 2 - 0
lib/include/IInput.h

@@ -25,6 +25,8 @@ namespace mdd{
         virtual limits& setLimits() = 0;
         virtual std::shared_ptr<IOutput> getConnection() = 0;
         virtual ~IInput() = default;
+
+        int removeConnection(std::shared_ptr<IOutput> output = nullptr) = 0;
     };
 }
 #endif

+ 1 - 1
lib/include/IManager.h

@@ -5,8 +5,8 @@ namespace mdd {
 	public:
 		virtual bool configure(const std::string& config) = 0;
 		virtual std::string getConfiguration() = 0;
-		//virtual std::string getGeneratorID() = 0;
 		virtual void load(const json& j) = 0;
 		virtual json dump() = 0;
+		virtual json getIdentifier() = 0;
 	};
 }

+ 2 - 1
lib/include/Input.h

@@ -54,7 +54,7 @@ namespace mdd {
         
         //bool verify(const json & data) override;
         int addConnection(std::shared_ptr<IOutput> output) override;
-        int removeConnection(std::shared_ptr<IOutput> output) override;
+        int removeConnection(std::shared_ptr<IOutput> output = nullptr) override;
         bool connect(std::shared_ptr<IOutput> output) override;
         void disconnect() override;
 
@@ -62,6 +62,7 @@ namespace mdd {
         std::string getConfiguration() override;
         void load(const json& j) override;
         json dump() override;
+        json getIdentifier() override;
     };
 }
 

+ 3 - 1
lib/include/ModuleBase.h

@@ -22,7 +22,7 @@ namespace mdd {
         std::vector<std::shared_ptr<Output>> outputs;
 
     public:
-        bool configure(const std::string& config) { return true; };
+        bool configure(const std::string& config);
         std::string getConfiguration() override;
 
         size_t getNumInputs() override;
@@ -47,6 +47,8 @@ namespace mdd {
         void load(const json& j) override;
         json dump() override;
 
+        json getIdentifier() override;
+
         void disconnect() override;
     };
 }

+ 1 - 0
lib/include/OptimizerBase.h

@@ -36,6 +36,7 @@ namespace mdd {
 		//virtual std::string getGeneratorID() = 0;
 		void load(const json& j);
 		json dump();
+		json getIdentifier() override;
 		//state update() override;
 	};
 }

+ 1 - 0
lib/include/Output.h

@@ -45,6 +45,7 @@ namespace mdd {
         std::string getConfiguration() override;
         void load(const json& j) override;
         json dump() override;
+        json getIdentifier() override;
     };
 }
 #endif

+ 1 - 0
lib/include/ProcessorBase.h

@@ -62,6 +62,7 @@ namespace mdd {
         void disconnect() override;
         void load(const json& j) override;
         json dump() override;
+        json getIdentifier() override;
     };
 }
 //*/

+ 99 - 2
lib/src/Connector.cpp

@@ -25,7 +25,7 @@ namespace mdd {
 		json jargs;
 		if (sub["type"] == "processor")
 		{
-			jargs["subject"] = _root->dump();
+			jargs["subject"] = _root->getIdentifier();
 		}
 		else if(sub["type"] == "module")
 		{
@@ -69,7 +69,42 @@ namespace mdd {
 		}
 		else if (obj["type"] == "connection")
 		{
+			IModule::Ptr module_in_ptr = _root->getModule(obj["input"]["prefix"].back().get<std::string>());
+			IModule::Ptr module_out_ptr = _root->getModule(obj["output"]["prefix"].back().get<std::string>());
+			if (module_in_ptr != nullptr && module_out_ptr != nullptr) {
+				IInput::Ptr in_ptr = nullptr;
+				for (size_t i = 0; i < module_in_ptr->getNumInputs(); i++)
+				{
+					auto in = module_in_ptr->getInput(i);
+					auto id = obj["input"]["name"].get<std::string>() + std::to_string(obj["input"]["id"].get<int>());
+					if (in->getID() == id)
+					{
+						in_ptr = in;
+						break;
+					}
+				}
 
+				IOutput::Ptr out_ptr = nullptr;
+				for (size_t i = 0; i < module_in_ptr->getNumOutputs(); i++)
+				{
+					auto out = module_out_ptr->getOutput(i);
+					auto id = obj["output"]["name"].get<std::string>() + std::to_string(obj["output"]["id"].get<int>());
+					if (out->getID() == id)
+					{
+						out_ptr = out;
+						break;
+					}
+				}
+
+				if (in_ptr != nullptr && out_ptr != nullptr)
+				{
+					in_ptr->connect(out_ptr);
+					jargs["object"] = obj;
+				}
+				
+			}
+			
+			
 		}
 		else if (obj["type"] == "input")
 		{
@@ -96,8 +131,70 @@ namespace mdd {
 	}
 
 	json Connector::change(const json& args) {
+		json ret;
+		if (!contains_subj_obj_structure(args))
+		{
+			return ret;
+		}
+		json sub = args["subject"];
+		if (!sub.contains("type"))
+		{
+			return ret;
+		}
+		json obj = args["object"];
+		ret["operation"] = "change";
+		json jargs;
+		if (sub["type"] == "processor")
+		{
+			if (jargs["subject"] == _root->getIdentifier())
+			{
+				jargs["subject"] = _root->getIdentifier();
+				if (_root->configure(obj.dump()))
+				{
+					jargs["object"] = obj;
+				}
+			}
+			else
+			{
+				IModule::Ptr module_ptr = _root->getModule(sub["name"].get<std::string>() + std::to_string(sub["id"].get<int>()));
+				if (module_ptr == nullptr) {
+					std::cout << "[Connector]: change: Was not able to find module." << std::endl;
+					return ret;
+				}
+				jargs["subject"] = module_ptr->getIdentifier();
+				if (module_ptr->configure(obj.dump()))
+				{
+					jargs["object"] = obj;
+				}
+			}
+		}
+		else if (sub["type"] == "module")
+		{
+			IModule::Ptr module_ptr = _root->getModule(sub["name"].get<std::string>() + std::to_string(sub["id"].get<int>()));
+			if (module_ptr == nullptr) {
+				std::cout << "[Connector]: change: Was not able to find module." << std::endl;
+				return ret;
+			}
+			jargs["subject"] = module_ptr->getIdentifier();
+			if (module_ptr->configure(obj.dump()))
+			{
+				jargs["object"] = obj;
+			}
+		}
+		else if (sub["type"] == "input")
+		{
 
-		return args;
+		}
+		else if (sub["type"] == "output")
+		{
+
+		}
+		else {
+			json j;
+			return j;
+		}
+		ret["args"] = jargs;
+		return ret;
 	}
 
 	json Connector::state(const json& args) {

+ 22 - 2
lib/src/Input.cpp

@@ -95,8 +95,18 @@ namespace mdd{
     }
 
     bool Input::connect(std::shared_ptr<IOutput> output){
-        _output = output;
-        _output->addConnection(std::make_shared<Input>((*this)));
+        if (_output != nullptr) {
+            if (_output->getIdentifier() != output->getIdentifier())
+            {
+                _output->removeConnection(std::make_shared<Input>((*this)));
+                removeConnection();
+            }
+        }
+        if (_output == nullptr)
+        {
+            addConnection(output);
+            _output->addConnection(std::make_shared<Input>((*this)));
+        }
         return true;
     }
 
@@ -167,4 +177,14 @@ namespace mdd{
         json jdump = json::parse(getConfiguration());
         return jdump;
     }
+
+    json Input::getIdentifier() {
+        json jID;
+        jID["name"] = _name;
+        jID["appendix"] = _appendix;
+        jID["value"] = _value;
+        jID["key"] = "Input";
+        jID["prefix"].push_back(_parent->getID());
+        return jID;
+    }
 }

+ 42 - 10
lib/src/ModuleBase.cpp

@@ -73,10 +73,30 @@ namespace mdd {
     }
 
     ModuleBase::ModuleBase(const std::string& base_config)
-        : _base_config(base_config)
     {
-
+        json jparse = json::parse(base_config);
+        if (jparse.contains("configure"))
+        {
+            _base_config = base_config;
+        }
+        else {
+            json jconfig;
+            jconfig["configure"] = jparse;
+            _base_config = jconfig.dump();
+        }
+        
+    }
+    bool ModuleBase::configure(const std::string& config) {
+        json j = json::parse(config);
+        json jbase = json::parse(_base_config);
+        if (j.contains("GUI"))
+        {
+            jbase["GUI"] = j["GUI"];
+        }
+        _base_config = jbase.dump();
+        return true;
     }
+   
 
     std::string ModuleBase::getConfiguration()
     {
@@ -122,14 +142,16 @@ namespace mdd {
     }
     json ModuleBase::dump()
     {
-        json ret;
-        ret["name"] = _name;
-        ret["id"] = getAppendix();
-        ret["type"] = type;
-        ret["key"] = key;
-        ret["prefix"] = std::vector<std::string>();
-        json configure = json::parse(_base_config);
-        ret["configure"] = configure;
+        json ret = getIdentifier();
+        json jconfig = json::parse(_base_config);
+        if (jconfig.contains("configure"))
+        {
+            ret["configure"] = jconfig["configure"];
+        }
+        if (jconfig.contains("GUI"))
+        {
+            ret["GUI"] = jconfig["GUI"];
+        }
 
         for (auto& in : inputs)
         {
@@ -154,4 +176,14 @@ namespace mdd {
             outputs[i]->disconnect();
         }
     }
+
+    json ModuleBase::getIdentifier() {
+        json jID;
+        jID["name"] = _name;
+        jID["id"] = getAppendix();
+        jID["type"] = type;
+        jID["key"] = key;
+        jID["prefix"] = std::vector<std::string>(); 
+        return jID;
+    }
 }

+ 6 - 1
lib/src/ModuleHTTP.cpp

@@ -153,8 +153,13 @@ namespace mdd{
     }
 
     bool ModuleHTTP::configure(const std::string& config) {
-        json config_parsed = json::parse(config);
         bool found = false;
+        found = ModuleBase::configure(config);
+        json config_parsed = json::parse(config);
+        if (!config_parsed.is_array())
+        {
+            return found;
+        }
         for (size_t i = 0; i < config_parsed.size(); i++)
         {
             if (config_parsed[i].contains("name"))

+ 6 - 0
lib/src/ModuleMath.cpp

@@ -62,7 +62,13 @@ namespace mdd {
 
     bool ModuleMath::configure(const std::string& config)
     {
+        bool success = false;
+        success = ModuleBase::configure(config);
         json config_parsed = json::parse(config);
+        if (!config_parsed.is_array())
+        {
+            return success;
+        }
         for (size_t i = 0; i < config_parsed.size(); i++)
         {
             if (config_parsed[i].contains("name"))

+ 15 - 7
lib/src/ModuleMerge.cpp

@@ -18,7 +18,7 @@ namespace mdd {
 		:ModuleBase(R"JSON(
         [{
             "name":"inputs",
-            "value":[{"type": "Value", "value": [1]}, {"type": "Value", "value": [1]}]
+            "value":[2]
         }])JSON")
 	{
 		std::vector<double> default_val = { 1 };
@@ -51,22 +51,30 @@ namespace mdd {
 	}
 
 	bool ModuleMerge::configure(const std::string& config) {
+		bool success = false;
+		success = ModuleBase::configure(config);
 		json config_parsed = json::parse(config);
+		if (!config_parsed.is_array())
+		{
+			return success;
+		}
 		for (size_t i = 0; i < config_parsed.size(); i++)
 		{
 			if (config_parsed[i].contains("name"))
 			{
 				if (config_parsed[i]["name"].get<std::string>() == "inputs")
 				{
+					size_t new_length = config_parsed[i]["value"][0].get<int>();
 					size_t length = inputs.size();
-					for (size_t j = length; j < config_parsed[i]["value"].size(); j++)
+					if (length - new_length > 0)
 					{
-						inputs.push_back(std::make_shared<Input>(this, config_parsed[i]["value"][j]["type"].get<std::string>(), j, config_parsed[i]["value"][j]["value"].get<std::vector<double>>()));
+						inputs.erase(inputs.end() - (length - new_length), inputs.end());
 					}
-					for (size_t j = 0; j < length; j++)
-					{
-						inputs[j]->setName(config_parsed[i]["value"][j]["type"].get<std::string>());
-						inputs[j]->setValue(config_parsed[i]["value"][j]["value"].get<std::vector<double>>());
+					else {
+						for (size_t j = length; j < new_length; j++)
+						{
+							inputs.push_back(std::make_shared<Input>(this, "Value", j, std::vector<double> {1}));
+						}
 					}
 				}
 			}

+ 6 - 0
lib/src/ModuleSQL.cpp

@@ -92,7 +92,13 @@ namespace mdd {
 	}
 
 	bool ModuleSQL::configure(const std::string& config) {
+		bool success = false;
+		success = ModuleBase::configure(config);
 		json config_parsed = json::parse(config);
+		if (!config_parsed.is_array())
+		{
+			return success;
+		}
 		
 		for (size_t i = 0; i < config_parsed.size(); i++)
 		{

+ 6 - 0
lib/src/ModuleSwitch.cpp

@@ -24,7 +24,13 @@ namespace mdd{
         setName("Switch");
     }
     bool ModuleSwitch::configure(const std::string& config) {
+        bool success = false;
+        success = ModuleBase::configure(config);
         json config_parsed = json::parse(config);
+        if (!config_parsed.is_array())
+        {
+            return success;
+        }
         for (size_t i = 0; i < config_parsed.size(); i++)
         {
             if (config_parsed[i].contains("name"))

+ 11 - 0
lib/src/OptimizerBase.cpp

@@ -96,4 +96,15 @@ namespace mdd{
 
 		return ret;
 	}
+
+	json OptimizerBase::getIdentifier() {
+		json jID;
+		/*
+		jID["name"] = _name;
+		jID["id"] = getAppendix();
+		jID["type"] = type;
+		jID["key"] = key;*/
+		jID["prefix"] = std::vector<std::string>();
+		return jID;
+	}
 }

+ 25 - 8
lib/src/Output.cpp

@@ -8,9 +8,10 @@ namespace mdd {
     int Output::removeConnection(std::shared_ptr<IInput> input)
     {
         for (auto it = _connections.begin(); it != _connections.end(); ++it) {
-            if ((*it) == input)
+            if ((*it)->getIdentifier() == input->getIdentifier())
             {
                 _connections.erase(it);
+                return _connections.size();
             }
         }
         return _connections.size();
@@ -97,8 +98,18 @@ namespace mdd {
 
     bool Output::connect(std::shared_ptr<IInput> input)
     {
-        addConnection(input);
-        input->addConnection(std::make_shared<Output>((*this)));
+        if (input->getConnection() != nullptr) {
+            if (input->getConnection()->getIdentifier() != getIdentifier())
+            {
+                removeConnection(input);
+                input->removeConnection();
+            }
+        }
+        if (input->getConnection() == nullptr)
+        {
+            addConnection(input);
+            input->addConnection(std::make_shared<Output>((*this)));
+        }
         return true;
     }
     std::vector<std::shared_ptr<IInput>> Output::getConnections()
@@ -140,11 +151,7 @@ namespace mdd {
 
     std::string Output::getConfiguration()
     {
-        json jconfig;
-        jconfig["name"] = _name;
-        jconfig["appendix"] = _appendix;
-        jconfig["value"] = _value;
-        jconfig["prefix"].push_back(_parent->getID());
+        json jconfig = getIdentifier();
         jconfig["optimizable"] = _optimizable;
         return jconfig.dump();
     }
@@ -160,4 +167,14 @@ namespace mdd {
         json jdump = json::parse(getConfiguration());
         return jdump;
     }
+
+    json Output::getIdentifier() {
+        json jID;
+        jID["name"] = _name;
+        jID["appendix"] = _appendix;
+        jID["value"] = _value;
+        jID["key"] = "Output";
+        jID["prefix"].push_back(_parent->getID());
+        return jID;
+    }
 }

+ 63 - 35
lib/src/ProcessorBase.cpp

@@ -2,13 +2,27 @@
 
 namespace mdd{
     ProcessorBase::ProcessorBase(const std::string& base_config)
-    : _base_config(base_config)
     {
-
+        json jparse = json::parse(base_config);
+        if (jparse.contains("configure"))
+        {
+            _base_config = base_config;
+        }
+        else {
+            json jconfig;
+            jconfig["configure"] = jparse;
+            _base_config = jconfig.dump();
+        }
     }
 
     bool ProcessorBase::configure(const std::string& config) {
         json j = json::parse(config);
+        json jbase = json::parse(_base_config);
+        if (j.contains("GUI"))
+        {
+            jbase["GUI"] = j["GUI"];
+        }
+        _base_config = jbase.dump();
         for (size_t i = 0; i < j.size(); i++)
         {
             if (j.contains("params"))
@@ -77,31 +91,7 @@ namespace mdd{
             sub_ret["params"]["outputs"].push_back(sub);
         }
 
-        sub_ret["modules"];
-        sub_ret["connections"];
-        for (size_t i = 0; i < modules.size(); i++)
-        {
-            json sub;
-            sub["id"] = typeid((*modules[i])).name();
-            sub["type"] = modules[i]->getType();
-            sub["appendix"] = modules[i]->getAppendix();
-            sub["configure"] = modules[i]->dump();
-            sub_ret["modules"].push_back(sub);
-            for (size_t j = 0; j < modules[i]->getNumOutputs(); j++)
-            {
-                auto connections = modules[i]->getOutput(j)->getConnections();
-                if (!connections.empty())
-                {
-                    json connect;
-                    connect["output"] = modules[i]->getOutput(j)->getParentID() + "/" + modules[i]->getOutput(j)->getID();
-                    for (size_t k = 0; k < connections.size(); k++)
-                    {
-                        connect["inputs"].push_back(connections[k]->getParentID() + "/" + connections[k]->getID());
-                    }
-                    sub_ret["connections"].push_back(connect);
-                }
-            }
-        }
+        
         ret.push_back(sub_ret);
         return ret.dump();
     }
@@ -256,13 +246,18 @@ namespace mdd{
     }
 
     json ProcessorBase::dump() {
-        json ret;
-        ret["name"] = _name;
-        ret["id"] = getAppendix();
-        ret["type"] = type;
-        ret["key"] = key;
-        ret["prefix"] = std::vector<std::string>();
-        ret["configure"] = json::parse(_base_config);
+        json ret = getIdentifier();
+        json jconfig = json::parse(_base_config);
+        if (jconfig.contains("configure"))
+        {
+            ret["configure"] = jconfig["configure"];
+        }
+        if (jconfig.contains("GUI"))
+        {
+            ret["GUI"] = jconfig["GUI"];
+        }
+         
+        //ret["configure"] = json::parse(_base_config);
         
 
         for (auto& in : processor_inputs)
@@ -284,11 +279,44 @@ namespace mdd{
         }
         for (auto& mod : modules)
         {
-            ret["modules"].push_back(mod->dump());
+            if (mod->getType()=="module")
+            {
+                ret["modules"].push_back(mod->dump());
+            }
+            else
+            {
+                ret["modules"].push_back(mod->dump());
+            }
+           
+
+            for (size_t j = 0; j < mod->getNumOutputs(); j++)
+            {
+                auto input_connections = mod->getOutput(j)->getConnections();
+                if (!input_connections.empty())
+                {
+                    json connect;
+                    connect["output"] = mod->getOutput(j)->getIdentifier();
+                    for (size_t k = 0; k < input_connections.size(); k++)
+                    {
+                        connect["inputs"].push_back(input_connections[k]->getIdentifier());
+                    }
+                    ret["connections"].push_back(connect);
+                }
+            }
         }
         return ret;
     }
 
+    json ProcessorBase::getIdentifier() {
+        json jID;
+        jID["name"] = _name;
+        jID["id"] = getAppendix();
+        jID["type"] = type;
+        jID["key"] = key;
+        jID["prefix"] = std::vector<std::string>();
+        return jID;
+    }
+
     std::shared_ptr<IOutput> ProcessorBase::getOutput(size_t index) {
         if (index < processor_outputs.size())
         {

+ 6 - 1
lib/src/ProcessorStandard.cpp

@@ -27,8 +27,13 @@ namespace mdd {
     }
 
     bool ProcessorStandard::configure(const std::string& config) {
-        json config_parsed = json::parse(config);
         bool found = false;
+        found = ProcessorBase::configure(config);
+        json config_parsed = json::parse(config);
+        if (!config_parsed.is_array())
+        {
+            return found;
+        }
         for (size_t i = 0; i < config_parsed.size(); i++)
         {
             if (config_parsed[i].contains("name"))