THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 13/12/2010 at 07:48, xxxxxxxx wrote:
Here is the complete code of the Math node:
gv_math_operator.h
class GvMathOperator : public GvOperatorData
{
INSTANCEOF(GvMathOperator,GvOperatorData)
private:
GvValuesInfo ports;
GvDynamicData data;
GvValueFlags func;
public:
GvMathOperator(void);
virtual ~GvMathOperator(void);
public:
virtual Bool iCreateOperator(GvNode *bn);
virtual const String GetDetailedText(GvNode *bn);
virtual const String GetText(GvNode *bn);
virtual const String GetTitle(GvNode *bn);
virtual Bool InitCalculation(GvNode *bn, GvCalc *c, GvRun *r);
virtual void FreeCalculation(GvNode *bn, GvCalc *c);
virtual Bool Calculate(GvNode *bn, GvPort *port, GvRun *r, GvCalc *c);
virtual Bool iGetPortDescription(GvNode *bn, GvPortIO port, LONG id, GvPortDescription *pd);
virtual Bool GetDDescription(GeListNode *node,Description *description, LONG &flags);
virtual Bool SetDParameter(GeListNode *node, const DescID &id,const GeData &t_data,LONG &flags);
static NodeData* Alloc(void) { return gNew GvMathOperator; }
};
////////////////////////////////
gv_math_operator.cpp
#include "operators.h"
#include "gv_math_operator.h"
#include "lib_description.h"
#include "gvmath.h"
////////////////////////////////
#define NR_OF_FUNCTIONS 5
static LONG title_ids[NR_OF_FUNCTIONS] =
{
GV_ADD_NODE_TITLE_STRING,
GV_SUB_NODE_TITLE_STRING,
GV_MUL_NODE_TITLE_STRING,
GV_DIV_NODE_TITLE_STRING,
GV_MOD_NODE_TITLE_STRING,
};
////////////////////////////////
GvMathOperator::GvMathOperator(void)
{
}
GvMathOperator::~GvMathOperator(void)
{
}
////////////////////////////////
Bool GvMathOperator::iCreateOperator(GvNode *bn)
{
BaseContainer *bc = bn->GetOpContainerInstance(); if (!bc) return FALSE;
bc->SetLong(GV_DYNAMIC_DATATYPE,ID_GV_DATA_TYPE_REAL);
bc->SetLong(GV_MATH_FUNCTION_ID,GV_ADD_NODE_FUNCTION);
return SUPER::iCreateOperator(bn);
}
const String GvMathOperator::GetDetailedText(GvNode *bn)
{
return GvGetOperatorDetailedText(this,bn);
}
const String GvMathOperator::GetText(GvNode *bn)
{
BaseContainer *bc = bn->GetOpContainerInstance();
String text = GeLoadString(title_ids[bc->GetLong(GV_MATH_FUNCTION_ID)]);
GvDataInfo *info = GvGetDataInfo(bn,GV_DYNAMIC_DATATYPE);
return info ? text + String(":") + *info->data_handler->GetName(info->data_handler->userdata) : text;
}
const String GvMathOperator::GetTitle(GvNode *bn)
{
BaseContainer *bc = bn->GetOpContainerInstance();
LONG func = bc->GetLong(GV_MATH_FUNCTION_ID);
return GeLoadString(GV_MATH_NODE_TITLE_STRING) + String(":") + GeLoadString(title_ids[func]);
}
Bool GvMathOperator::iGetPortDescription(GvNode *bn, GvPortIO port, LONG id, GvPortDescription *pd)
{
if (!SUPER::iGetPortDescription(bn,port,id,pd)) return FALSE;
GvDataInfo *info = GvGetDataInfo(bn,GV_DYNAMIC_DATATYPE);
if (!info) return FALSE;
switch (id)
{
case GV_MATH_INPUT:
case GV_MATH_OUTPUT:
pd->data_id = info->data_handler->data_id;
break;
}
return TRUE;
}
////////////////////////////////
Bool GvMathOperator::SetDParameter(GeListNode *node, const DescID &id,const GeData &t_data,LONG &flags)
{
if (!SUPER::SetDParameter(node,id,t_data,flags)) return FALSE;
switch (id[0].id)
{
case GV_DYNAMIC_DATATYPE:
{
flags |= DESCFLAGS_PARAM_SET;
GvNode *bn = (GvNode* )node;
if (!GvCheckDataInfo(bn,GV_DYNAMIC_DATATYPE)) return FALSE;
if (!bn->ResetPortType(GV_MATH_INPUT)) return FALSE;
if (!bn->ResetPortType(GV_MATH_OUTPUT)) return FALSE;
}
break;
}
return TRUE;
}
Bool GvMathOperator::GetDDescription(GeListNode *node,Description *description, LONG &flags)
{
if (!SUPER::GetDDescription(node,description,flags)) return FALSE;
if (flags & DESCFLAGS_DESC_LOADED)
{
BaseContainer *bc = description->GetParameterI(DescLevel(GV_DYNAMIC_DATATYPE),NULL);
if (bc)
{
BaseContainer types;
BaseContainer *b = ((GvNode* )node)->GetOpContainerInstance();
GvValueFlags func = GV_CALC_NOP;
switch (b->GetLong(GV_MATH_FUNCTION_ID))
{
case GV_ADD_NODE_FUNCTION: func = GV_CALC_ADD; break;
case GV_SUB_NODE_FUNCTION: func = GV_CALC_SUB; break;
case GV_MUL_NODE_FUNCTION: func = GV_CALC_MUL; break;
case GV_DIV_NODE_FUNCTION: func = GV_CALC_DIV; break;
case GV_MOD_NODE_FUNCTION: func = GV_CALC_MOD; break;
default: return FALSE; break;
}
if (func != GV_CALC_NOP)
{
GvGetWorld()->GetDataTypes(types,GV_DATA_OPTIONS_NONE,func);
bc->SetData(DESC_CYCLE,types);
}
}
}
return TRUE;
}
////////////////////////////////
static LONG input_ids[] = { GV_MATH_INPUT, 0 };
enum { GV_MATH_INPUT_INDEX };
Bool GvMathOperator::InitCalculation(GvNode *bn, GvCalc *c, GvRun *r)
{
if (!GvBuildValuesTable(bn,ports,c,r,input_ids)) return FALSE;
if (!GvAllocDynamicData(bn,data,c,GV_DYNAMIC_DATATYPE)) return FALSE;
BaseContainer *bc = bn->GetOpContainerInstance();
switch (bc->GetLong(GV_MATH_FUNCTION_ID))
{
case GV_ADD_NODE_FUNCTION: func = GV_CALC_ADD; break;
case GV_SUB_NODE_FUNCTION: func = GV_CALC_SUB; break;
case GV_MUL_NODE_FUNCTION: func = GV_CALC_MUL; break;
case GV_DIV_NODE_FUNCTION: func = GV_CALC_DIV; break;
case GV_MOD_NODE_FUNCTION: func = GV_CALC_MOD; break;
default: func = GV_CALC_NOP; break;
}
return TRUE;
}
void GvMathOperator::FreeCalculation(GvNode *bn, GvCalc *c)
{
GvFreeValuesTable(bn,ports);
GvFreeDynamicData(data);
}
Bool GvMathOperator::Calculate(GvNode *bn, GvPort *port, GvRun *r, GvCalc *c)
{
LONG i, j, n = 0; GvValue *v;
v = ports.in_values[GV_MATH_INPUT_INDEX];
if (v)
{
v->Calculate(bn,GV_PORT_INPUT,r,c,GV_MULTIPLE_PORTS);
j = v->NrOfPorts();
for (i = 0; i < j; ++i)
{
if (n == 0)
{
if (!v->GetPort(i)->CalculateRawData(data.data,data.data,r,GV_CALC_SET)) return FALSE;
}
else
{
if (!v->GetPort(i)->CalculateRawDataRev(data.data,data.data,r,func)) return FALSE;
}
++n;
}
}
if (n == 0) GvClearDynamicData(data,r);
return ports.out_ports[0]->CopyRawData(data.data,r);
}
////////////////////////////////
Please check also the gvmath.* resource files.
cheers,
Matthias