// Copyright (C) 2001 Jean-Marc Valin
extern "C" {
}
#include "UINode.h"
#include "UINetwork.h"
#include "UITerminal.h"
#include "UINodeParameters.h"
#include <libxml/tree.h>
#include "Node.h"
#include "UIDocument.h"
#include "UILink.h"
#include "ParameterSet.h"
#include "Network.h"
#include <algorithm>
//@implements UIClasses
using namespace std;
namespace FD {
UINode::UINode(UINetwork* _net, string _name, string _type, double _x, double _y, bool doInit)
: destroyed(false)
, name(_name)
, net(_net)
, type(_type)
, x(_x)
, y(_y)
, xtmp(_x)
, ytmp(_y)
{
if (doInit)
{
parameters = newNodeParameters(this,type);
vector<ItemInfo *> inputname;
vector<ItemInfo *> outputname;
inputname = net->getDocument()->getNetInputs(type);
outputname = net->getDocument()->getNetOutputs(type);
for (unsigned int i=0;i<inputname.size();i++)
{
inputs.insert(inputs.end(), newTerminal(inputname[i],
this, true, 0.0, 0.0));
}
for (unsigned int i=0;i<outputname.size();i++)
{
outputs.insert(outputs.end(), newTerminal(outputname[i],
this, false, 0.0, 0.0));
}
description = net->getDocument()->getDescription(type);
}
}
UINode::UINode(UINetwork* _net, xmlNodePtr def, bool doInit)
: destroyed(false)
, net(_net)
{
if (doInit)
{
loadXML(def);
}
}
void UINode::loadXML(xmlNodePtr def)
{
char *str_name = (char *)xmlGetProp(def, (xmlChar *)"name");
char *str_type = (char *)xmlGetProp(def, (xmlChar *)"type");
char *str_x = (char *)xmlGetProp(def, (xmlChar *)"x");
char *str_y = (char *)xmlGetProp(def, (xmlChar *)"y");
if (!str_name || !str_type || !str_x || !str_y)
{
throw new GeneralException("Missing node parameter(s) in XML definition", __FILE__, __LINE__);
}
name = string(str_name);
type = string(str_type);
x = atof(str_x);
y = atof(str_y);
free (str_name); free (str_type); free(str_x); free(str_y);
xtmp = x;
ytmp = y;
parameters = newNodeParameters(this, type);
parameters->load(def);
vector<ItemInfo *> inputname;
vector<ItemInfo *> outputname;
inputname = net->getDocument()->getNetInputs(type);
outputname = net->getDocument()->getNetOutputs(type);
for (unsigned int i=0;i<inputname.size();i++)
{
inputs.insert(inputs.end(), newTerminal (inputname[i],
this, true, 0.0, 0.0));
}
for (unsigned int i=0;i<outputname.size();i++)
{
outputs.insert(outputs.end(), newTerminal (outputname[i],
this, false, 0.0, 0.0));
}
description = net->getDocument()->getDescription(type);
}
UINode::~UINode()
{
if (!destroyed)
{
for (unsigned int i=0;i<inputs.size();i++)
delete inputs[i];
for (unsigned int i=0;i<outputs.size();i++)
delete outputs[i];
delete parameters;
net->removeNode(this);
}
}
void UINode::saveXML(xmlNode *root)
{
xmlNodePtr tree = xmlNewChild(root, NULL, (xmlChar *)"Node", NULL);
xmlSetProp(tree, (xmlChar *)"name", (xmlChar *)name.c_str());
xmlSetProp(tree, (xmlChar *)"type", (xmlChar *)type.c_str());
char tmp[15];
sprintf (tmp, "%f", float(x));
xmlSetProp(tree, (xmlChar *)"x", (xmlChar *)tmp);
sprintf (tmp, "%f", float(y));
xmlSetProp(tree, (xmlChar *)"y", (xmlChar *)tmp);
parameters->saveXML(tree);
}
UITerminal *UINode::getInputNamed(string n)
{
for (unsigned int i=0;i<inputs.size();i++)
if (inputs[i]->getName() == n)
return inputs[i];
return NULL;
}
UITerminal *UINode::getOutputNamed(string n)
{
for (unsigned int i=0;i<outputs.size();i++)
if (outputs[i]->getName() == n)
return outputs[i];
return NULL;
}
void UINode::setNodeParameters(UINodeParameters *params)
{
parameters = params;
}
void UINode::insertNetParams(vector<ItemInfo *> ¶ms)
{
parameters->insertNetParams(params);
}
void UINode::updateNetParams(vector<ItemInfo *> ¶ms) {
parameters->updateNetParams(params);
}
UILink *UINode::newLink (UITerminal *_from, UITerminal *_to)
{
//cerr<<"UINode::newLink\n";
return new UILink (_from, _to);
}
UINetTerminal *UINode::newNetTerminal (UITerminal *_terminal, UINetTerminal::NetTermType _type, const string &_name,
const string &_objType, const string &_description) {
//cerr<<"UINode::newNetTerminal\n";
return new UINetTerminal (_terminal, _type, _name, _objType, _description);
}
UINodeParameters *UINode::newNodeParameters (UINode *_node, string type)
{
//cerr << "UINode::newNodeParameters\n";
return new UINodeParameters (_node, type);
}
Node *UINode::build(const ParameterSet ¶ms)
{
//for all params, it will perform substitution in parameters (process subnet_params)
Node *node=NULL;
_NodeFactory *factory = NULL;
ParameterSet *par=NULL;
factory = Node::getFactoryNamed(type);
try {
par = parameters->build(params);
//This is only true if type is in the dictionary
if (factory)
{
node = factory->Create(name, *par);
} else {
UINetwork *buildNet = net->getDocument()->getNetworkNamed(type);
if (buildNet)
node = buildNet->build(name, *par);
else
{
node = UIDocument::buildExternal(type, name, *par);
if (!node)
{
throw new GeneralException(string("Node not found: ")+type, __FILE__, __LINE__);
}
}
}
} catch (BaseException *e)
{
if (par)
delete par;
if (node)
delete node;
throw e->add (new GeneralException(string("Exception caught while creating ")+name
+ " (type " + type + ")", __FILE__, __LINE__));
}
node->setUINode(this);
delete par;
return node;
}
void UINode::addTerminal(const string &_name, UINetTerminal::NetTermType _type, const string &_objType, const string &_description)
{
double x1=0,y1=0,x2=0,y2=0;
ItemInfo info;
info.name = _name;
info.type = _objType;
info.description = _description;
switch (_type) {
case UINetTerminal::INPUT:
inputs.insert(inputs.end(), newTerminal (&info, this, true, x1, y1));
break;
case UINetTerminal::OUTPUT:
outputs.insert(outputs.end(), newTerminal (&info, this, false, x2,y2 ));
break;
default:
break;
}
redraw();
}
void UINode::removeTerminal(const string &_name, UINetTerminal::NetTermType _type)
{
vector<UITerminal*>::iterator term;
switch (_type) {
case UINetTerminal::INPUT:
term = find(inputs.begin(), inputs.end(), getInputNamed(_name));
if (term!=inputs.end())
{
delete *term;
inputs.erase(term);
}
break;
case UINetTerminal::OUTPUT:
term = find(outputs.begin(), outputs.end(), getOutputNamed(_name));
if (term!=outputs.end())
{
delete *term;
outputs.erase(term);
}
break;
default:
break;
}
redraw();
}
void UINode::genCode(ostream &out, int &id, set<string> &nodeList)
{
int bakID=id;
id++;
int bakID2=id;
bool builtin=false;
_NodeFactory *factory = NULL;
factory = Node::getFactoryNamed(type);
if (factory)
{
builtin=true;
nodeList.insert(nodeList.end(), type);
}
else
{
builtin=false;
UINetwork *buildNet = net->getDocument()->getNetworkNamed(type);
if (buildNet)
buildNet->genCode(out, id, nodeList);
else {
UIDocument::genCodeExternal(type, out, id, nodeList);
}
}
out << "static Node *genNode" << bakID << "(const ParameterSet ¶ms)\n";
out << "{\n";
parameters->genCode(out);
if (builtin)
{
out << " _NodeFactory *factory = Node::getFactoryNamed(\"" << type << "\");\n";
out << " if (!factory)\n";
out << " throw new GeneralException(\"Node could not be found: " << type << "\", __FILE__, __LINE__);\n";
out << " Node *node = factory->Create(\""<<name << "\", parameters);\n";
} else {
out << " Node *node = genNet" << bakID2 << "(\""<<name << "\", parameters);\n";
}
out << " return node;\n";
out << "}\n\n";
}
string UINode::getComments() const
{
return parameters->getComments();
}
void UINode::rename (const string &newName) {
//FIXME : should do something about the node name?
type = newName;
}
UITerminal* UINode::newTerminal(ItemInfo *_info, UINode *_node, bool _isInput, double _x, double _y)
{
return new UITerminal(_info,_node,_isInput,_x,_y);
}
}//namespace FD
syntax highlighted by Code2HTML, v. 0.9.1