666 lines
19 KiB
C++
666 lines
19 KiB
C++
//TODO big update
|
|
/*
|
|
add setting bool freeze => stop remapping parameters, and check that target is compatible
|
|
add setting bool execute in real time => does not execute in 1 frame as now (return CKBR_ACTIVATENEXTFRAME)
|
|
|
|
put all these settings in a flag - register flag param hidden
|
|
|
|
put target in input parameter so that user can then change it on the fly
|
|
|
|
reset,wait for completion,stop at exit,no parameter restore,freeze io mapping,real time execute,
|
|
*/
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////
|
|
//
|
|
// CallBehavior
|
|
//
|
|
/////////////////////////////////////////////////////
|
|
/////////////////////////////////////////////////////
|
|
#include "CKALL.h"
|
|
#include "CallBehaviorCallback.h"
|
|
|
|
#define CALLBEHAVIOR_NAME "Call Behavior"
|
|
#define CALLBEHAVIOR_GUID CKGUID(0x360a720d,0x7fa42f94)
|
|
|
|
CKObjectDeclaration *FillBehaviorCallBehaviorDecl();
|
|
CKERROR CreateCallBehaviorProto(CKBehaviorPrototype **);
|
|
int CallBehavior(const CKBehaviorContext& context);
|
|
CKERROR CallBehaviorCallback(const CKBehaviorContext& context);
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// enums & defines
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
enum INS
|
|
{
|
|
eINS,
|
|
};
|
|
|
|
enum OUTS
|
|
{
|
|
eOUTS,
|
|
};
|
|
|
|
enum PINS
|
|
{
|
|
eRESET,
|
|
eWAITFORCOMPLETION,
|
|
eSTOP_AT_EXIT,
|
|
eINPUTS
|
|
};
|
|
|
|
enum POUTS
|
|
{
|
|
eOUTPUTS,
|
|
};
|
|
|
|
enum PLOCALS
|
|
{
|
|
eTARGET_BEHAVIOR, //setting
|
|
eMAX_RECURSION_DEPTH, //setting
|
|
eDO_NOT_RESTORE_PARAMETERS, //setting, optimisation
|
|
eRECURSION_DEPTH, //local
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// save parameter links
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
struct BehaviorsParameters
|
|
{
|
|
int sourcesCount;
|
|
CK_ID* sources;
|
|
int destinationsCount;
|
|
CK_ID** destinations;
|
|
|
|
BehaviorsParameters() {
|
|
memset(this,0,sizeof(BehaviorsParameters));
|
|
destinations = 0;
|
|
}
|
|
~BehaviorsParameters(){Clear();}
|
|
|
|
void Clear()
|
|
{
|
|
if (sources)
|
|
delete [] sources;
|
|
if (destinations)
|
|
{
|
|
for (int i=0;i<destinationsCount;i++)
|
|
{
|
|
delete [] destinations[i];
|
|
}
|
|
delete [] destinations;
|
|
}
|
|
memset(this,0,sizeof(this));
|
|
}
|
|
|
|
|
|
void SaveBehaviorParameters(CKBehavior* beh)
|
|
{
|
|
if (!beh)
|
|
return;
|
|
Clear();
|
|
//save pins
|
|
sourcesCount = beh->GetInputParameterCount();
|
|
sources = new CK_ID[sourcesCount*2];
|
|
for (int i=0;i<sourcesCount;++i)
|
|
{
|
|
CKParameterIn* pin = beh->GetInputParameter(i);
|
|
if (pin)
|
|
{
|
|
if (CKParameterIn* shared = pin->GetSharedSource())
|
|
{
|
|
sources[i*2] = 1;
|
|
sources[i*2+1] = shared->GetID();
|
|
}
|
|
else if (CKParameter* p = pin->GetDirectSource())
|
|
{
|
|
sources[i*2] = 0;
|
|
sources[i*2+1] = p->GetID();
|
|
}
|
|
else
|
|
{
|
|
sources[i*2] = 0;
|
|
sources[i*2+1] = 0;
|
|
}
|
|
}
|
|
}
|
|
//save pouts
|
|
destinationsCount = beh->GetOutputParameterCount();
|
|
destinations = new CK_ID*[destinationsCount];
|
|
for (int i=0;i<destinationsCount;++i)
|
|
{
|
|
CKParameterOut* pout = beh->GetOutputParameter(i);
|
|
if (pout)
|
|
{
|
|
if (int destCount = pout->GetDestinationCount())
|
|
{
|
|
destinations[i] = new CK_ID[destCount+1];
|
|
destinations[i][0] = destCount;
|
|
for (int j=0;j<destCount;++j)
|
|
{
|
|
CKParameter* dest = pout->GetDestination(j);
|
|
destinations[i][j+1] = dest?dest->GetID():0;
|
|
}
|
|
}
|
|
else
|
|
destinations[i] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
void LoadBehaviorParameters(CKBehavior* beh)
|
|
{
|
|
if (!beh)
|
|
return;
|
|
//restore pins
|
|
for (int i=0;i<sourcesCount;++i)
|
|
{
|
|
CKParameterIn* pin = beh->GetInputParameter(i);
|
|
if (pin)
|
|
{
|
|
CK_ID id = sources[2*i+1];
|
|
if (id==0)
|
|
{
|
|
pin->ShareSourceWith(0);
|
|
pin->SetDirectSource(0);
|
|
}
|
|
else
|
|
{
|
|
CKObject* obj = beh->GetCKContext()->GetObject(id);
|
|
if (sources[2*i]==0)
|
|
{
|
|
pin->ShareSourceWith(0);
|
|
pin->SetDirectSource((CKParameter*)obj);
|
|
}
|
|
else
|
|
{
|
|
pin->SetDirectSource(0);
|
|
pin->ShareSourceWith((CKParameterIn*)obj);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//restore pouts
|
|
for (int i=0;i<destinationsCount;++i)
|
|
{
|
|
CKParameterOut* pout = beh->GetOutputParameter(i);
|
|
if (pout)
|
|
{
|
|
pout->RemoveAllDestinations();
|
|
if (destinations[i])
|
|
{
|
|
int count = destinations[i][0];
|
|
for (int j=0;j<count;++j)
|
|
{
|
|
CKParameter* p = (CKParameter*)beh->GetCKContext()->GetObject(destinations[i][j+1]);
|
|
if (CKIsChildClassOf(p,CKCID_PARAMETER))
|
|
pout->AddDestination(p);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void SetBehaviorParameters(CKBehavior* callBB,CKBehavior* calledBeh)
|
|
{
|
|
if (!callBB || !calledBeh)
|
|
return;
|
|
|
|
int inCountTarget = calledBeh->GetInputParameterCount();
|
|
int outCountTarget = calledBeh->GetOutputParameterCount();
|
|
//set sources & dest
|
|
for (int i=0;i<inCountTarget;++i)
|
|
{
|
|
CKParameterIn* pin1 = calledBeh->GetInputParameter(i);
|
|
CKParameterIn* pin2 = callBB->GetInputParameter(i+eINPUTS);
|
|
if (pin1 && pin2)
|
|
pin1->SetDirectSource(pin2->GetDirectSource());
|
|
}
|
|
for (int i=0;i<outCountTarget;++i)
|
|
{
|
|
CKParameterOut* pout1 = calledBeh->GetOutputParameter(i);
|
|
CKParameterOut* pout2 = callBB->GetOutputParameter(i+eOUTPUTS);
|
|
if (pout1 && pout2)
|
|
{
|
|
pout1->RemoveAllDestinations();
|
|
pout1->AddDestination(pout2);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void NameBehaviorParameters(CKBehavior* callBB,CKBehavior* calledBeh)
|
|
{
|
|
if (!calledBeh)
|
|
return;
|
|
|
|
int count = calledBeh->GetInputParameterCount();
|
|
for (int i=0;i<count;++i)
|
|
{
|
|
CKParameterIn* p1 = calledBeh->GetInputParameter(i);
|
|
CKParameterIn* p2 = callBB->GetInputParameter(i+eINPUTS);
|
|
if (p1 && p2)
|
|
{
|
|
p2->SetName(p1->GetName());
|
|
if (p1->GetType()!=p2->GetType())
|
|
{
|
|
p2->SetType(p1->GetType());
|
|
//CKParameter* psource = p2->GetRealSource();
|
|
//if (psource)
|
|
// psource->SetType(p1->GetType());
|
|
}
|
|
}
|
|
}
|
|
|
|
count = calledBeh->GetOutputParameterCount();
|
|
for (int i=0;i<count;++i)
|
|
{
|
|
CKParameter* p1 = calledBeh->GetOutputParameter(i);
|
|
CKParameter* p2 = callBB->GetOutputParameter(i+eOUTPUTS);
|
|
if (p1 && p2)
|
|
{
|
|
p2->SetName(p1->GetName());
|
|
if (p1->GetType()!=p2->GetType())
|
|
{
|
|
p2->SetType(p1->GetType());
|
|
}
|
|
}
|
|
}
|
|
|
|
count = calledBeh->GetInputCount();
|
|
for (int i=0;i<count;++i)
|
|
{
|
|
CKBehaviorIO* p1 = calledBeh->GetInput(i);
|
|
CKBehaviorIO* p2 = callBB->GetInput(i+eINS);
|
|
if (p1 && p2)
|
|
p2->SetName(p1->GetName());
|
|
}
|
|
|
|
count = calledBeh->GetOutputCount();
|
|
for (int i=0;i<count;++i)
|
|
{
|
|
CKBehaviorIO* p1 = calledBeh->GetOutput(i);
|
|
CKBehaviorIO* p2 = callBB->GetOutput(i+eOUTS);
|
|
if (p1 && p2)
|
|
p2->SetName(p1->GetName());
|
|
}
|
|
}
|
|
|
|
static void ResetBehaviorParameters(CKBehavior* behavior)
|
|
{
|
|
if (!behavior)
|
|
return;
|
|
|
|
int inCountTarget = behavior->GetInputParameterCount();
|
|
int outCountTarget = behavior->GetOutputParameterCount();
|
|
//set sources & dest
|
|
for (int i=0;i<inCountTarget;++i)
|
|
{
|
|
CKParameterIn* pin1 = behavior->GetInputParameter(i);
|
|
if (pin1)
|
|
{
|
|
pin1->SetDirectSource(0);
|
|
pin1->ShareSourceWith(0);
|
|
}
|
|
}
|
|
for (int i=0;i<outCountTarget;++i)
|
|
{
|
|
CKParameterOut* pout1 = behavior->GetOutputParameter(i);
|
|
if (pout1)
|
|
pout1->RemoveAllDestinations();
|
|
}
|
|
}
|
|
|
|
};
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// the behavior
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
CKObjectDeclaration *FillBehaviorCallBehaviorDecl()
|
|
{
|
|
CKObjectDeclaration *od = CreateCKObjectDeclaration(CALLBEHAVIOR_NAME);
|
|
od->SetDescription("Calls immediatly a behavior.");
|
|
/* rem:
|
|
<SPAN CLASS=in>In: </SPAN>triggers the process.<BR>
|
|
<SPAN CLASS=out>Out: </SPAN>is activated when the activated script's process is completed.<BR>
|
|
<BR>
|
|
<SPAN CLASS=pin>Reset?: </SPAN>if TRUE, the script will be reset; if FALSE the script will be resumed from its previous state.<BR>
|
|
<SPAN CLASS=pin>Script: </SPAN>script to be performed.<BR>
|
|
<SPAN CLASS=pin>Wait For Completion?: </SPAN>if TRUE, the script will be executed until completion; if FALSE the script will be executed for one frame.<BR>
|
|
<BR>
|
|
The script called is executed immediatly, stopping the execution of the current script.
|
|
*/
|
|
/* warning:
|
|
The script must not contain a infinite loop if you set Wait For Completion.<BR>
|
|
*/
|
|
od->SetType(CKDLL_BEHAVIORPROTOTYPE);
|
|
od->SetGuid(CALLBEHAVIOR_GUID);
|
|
od->SetAuthorGuid(VIRTOOLS_GUID);
|
|
od->SetAuthorName("Virtools");
|
|
od->SetVersion(0x00010000);
|
|
od->SetCreationFunction(CreateCallBehaviorProto);
|
|
od->SetCompatibleClassId(CKCID_BEOBJECT);
|
|
od->SetCategory("Narratives/Script Management");
|
|
return od;
|
|
}
|
|
|
|
CKERROR CreateCallBehaviorProto(CKBehaviorPrototype **pproto)
|
|
{
|
|
CKBehaviorPrototype *proto = CreateCKBehaviorPrototype(CALLBEHAVIOR_NAME);
|
|
if(!proto) return CKERR_OUTOFMEMORY;
|
|
|
|
proto->DeclareInParameter("Reset", CKPGUID_BOOL, "FALSE");
|
|
proto->DeclareInParameter("Wait For Completion", CKPGUID_BOOL, "FALSE");
|
|
proto->DeclareInParameter("Stop At Exit", CKPGUID_BOOL, "FALSE");
|
|
|
|
proto->DeclareSetting("Behavior",CKPGUID_BEHAVIOR);
|
|
proto->DeclareSetting("Max Recursion",CKPGUID_INT,"100");//0 means no protection
|
|
proto->DeclareSetting("Do not restore parameters",CKPGUID_BOOL);//eDO_NOT_RESTORE_PARAMETERS
|
|
proto->DeclareLocalParameter("",CKPGUID_INT);//eRECURSION_DEPTH
|
|
|
|
proto->SetFlags(CK_BEHAVIORPROTOTYPE_NORMAL);
|
|
proto->SetFunction(CallBehavior);
|
|
proto->SetBehaviorCallbackFct(CallBehaviorCallback);
|
|
proto->SetBehaviorFlags((CK_BEHAVIOR_FLAGS)(
|
|
CKBEHAVIOR_INTERNALLYCREATEDINPUTS|
|
|
CKBEHAVIOR_INTERNALLYCREATEDOUTPUTS|
|
|
CKBEHAVIOR_INTERNALLYCREATEDINPUTPARAMS|
|
|
CKBEHAVIOR_INTERNALLYCREATEDOUTPUTPARAMS
|
|
));
|
|
|
|
*pproto = proto;
|
|
return CK_OK;
|
|
|
|
}
|
|
|
|
|
|
int CallBehavior(const CKBehaviorContext& behcontext)
|
|
{
|
|
CKBehavior* beh = behcontext.Behavior;
|
|
|
|
//Get target behavior
|
|
CKBehavior* target = (CKBehavior*) beh->GetLocalParameterObject(eTARGET_BEHAVIOR);
|
|
if (!target)
|
|
return CKBR_OK;
|
|
|
|
//reset
|
|
BOOL reset=FALSE;
|
|
beh->GetInputParameterValue(eRESET, &reset);
|
|
if (reset)
|
|
target->Activate(FALSE,TRUE);
|
|
|
|
//Activate Inputs
|
|
//target->ActivateInput(0);
|
|
int ioCount = target->GetInputCount();
|
|
for (int i=eINS;i<eINS+ioCount;++i)
|
|
{
|
|
if (beh->IsInputActive(i))
|
|
target->ActivateInput(i-eINS);
|
|
}
|
|
|
|
// Get waitcomp
|
|
BOOL wc=TRUE;
|
|
beh->GetInputParameterValue(eWAITFORCOMPLETION, &wc);
|
|
|
|
//stop at exit
|
|
BOOL stopAtExit = FALSE;
|
|
beh->GetInputParameterValue(eSTOP_AT_EXIT, &stopAtExit);
|
|
|
|
//max depth
|
|
int maxDepth = 100;
|
|
beh->GetLocalParameterValue(eMAX_RECURSION_DEPTH,&maxDepth);
|
|
|
|
//current depth
|
|
int currentDepth = 0;
|
|
beh->GetLocalParameterValue(eRECURSION_DEPTH,¤tDepth);
|
|
|
|
currentDepth++;
|
|
if (maxDepth>=0 && currentDepth>maxDepth)
|
|
{
|
|
behcontext.Context->OutputToConsole("CallBehavior, recursion>max recursion depth, BB break");
|
|
return CKBR_OK;
|
|
}
|
|
beh->SetLocalParameterValue(eRECURSION_DEPTH,¤tDepth);
|
|
|
|
//optim
|
|
int noRestoreParam = FALSE;
|
|
beh->GetLocalParameterValue(eDO_NOT_RESTORE_PARAMETERS,&noRestoreParam);
|
|
|
|
|
|
if (wc) {
|
|
int loop = 0;
|
|
int maxloop = behcontext.Context->GetBehaviorManager()->GetBehaviorMaxIteration();
|
|
for(;;++loop)
|
|
{
|
|
if (loop > maxloop) {
|
|
behcontext.Context->OutputToConsoleExBeep("Execute Behavior : Behavior %s Executed too much times",target?target->GetName():"NA");
|
|
target->Activate(FALSE,FALSE);
|
|
break;
|
|
}
|
|
|
|
BehaviorsParameters behParams;
|
|
if (noRestoreParam==FALSE)
|
|
behParams.SaveBehaviorParameters(target);
|
|
BehaviorsParameters::SetBehaviorParameters(beh,target);
|
|
CKERROR result = target->Execute(behcontext.DeltaTime);
|
|
if (noRestoreParam==FALSE)
|
|
behParams.LoadBehaviorParameters(target);
|
|
// The target loop on itself too much times
|
|
if (result == CKBR_INFINITELOOP) {
|
|
target->Activate(FALSE,FALSE);
|
|
break;
|
|
}
|
|
if(!target->IsActive())
|
|
break;
|
|
}
|
|
} else { // we execute only one frame of the target
|
|
BehaviorsParameters behParams;
|
|
if (noRestoreParam==FALSE)
|
|
behParams.SaveBehaviorParameters(target);
|
|
BehaviorsParameters::SetBehaviorParameters(beh,target);
|
|
target->Execute(behcontext.DeltaTime);
|
|
if (noRestoreParam==FALSE)
|
|
behParams.LoadBehaviorParameters(target);
|
|
target->Activate(FALSE,FALSE);
|
|
}
|
|
|
|
//recursive depth update
|
|
currentDepth--;
|
|
beh->SetLocalParameterValue(eRECURSION_DEPTH,¤tDepth);
|
|
|
|
// IO Activation
|
|
//beh->ActivateInput(0,FALSE);
|
|
//beh->ActivateOutput(0);
|
|
for (int i=eINS;i<eINS+ioCount;++i)
|
|
beh->ActivateInput(i,FALSE);
|
|
ioCount = target->GetOutputCount();
|
|
for (int i=eOUTS;i<eOUTS+ioCount;++i)
|
|
beh->ActivateOutput(i,target->IsOutputActive(i-eOUTS));
|
|
|
|
if (stopAtExit)
|
|
{
|
|
for (int i=0;i<ioCount;++i)
|
|
target->ActivateOutput(i,FALSE);
|
|
}
|
|
|
|
return CKBR_OK;
|
|
}
|
|
|
|
void RemoveIOxParams(CKBehavior* beh)
|
|
{
|
|
CKContext* ctx = beh->GetCKContext();
|
|
int count = beh->GetInputParameterCount()-eINPUTS;
|
|
for (int i=0;i<count;++i)
|
|
ctx->DestroyObject(beh->RemoveInputParameter(eINPUTS),CK_DESTROY_NONOTIFY,0);
|
|
|
|
count = beh->GetOutputParameterCount()-eOUTPUTS;
|
|
for (int i=0;i<count;++i)
|
|
ctx->DestroyObject(beh->RemoveOutputParameter(eOUTPUTS),CK_DESTROY_NONOTIFY,0);
|
|
|
|
count = beh->GetInputCount()-eINS;
|
|
for (int i=0;i<count;++i)
|
|
beh->DeleteInput(eINS);
|
|
|
|
count = beh->GetOutputCount()-eOUTS;
|
|
for (int i=0;i<count;++i)
|
|
beh->DeleteOutput(eOUTS);
|
|
}
|
|
|
|
CKERROR CallBehaviorCallback(const CKBehaviorContext& behcontext)
|
|
{
|
|
CKBehavior* beh = behcontext.Behavior;
|
|
switch( behcontext.CallbackMessage )
|
|
{
|
|
//create same ios as in target behavior
|
|
case CKM_BEHAVIOREDITED:
|
|
{
|
|
CKBehavior* target = (CKBehavior*) beh->GetLocalParameterObject(eTARGET_BEHAVIOR);
|
|
//update behavior ios & types just in case
|
|
BehaviorsParameters::NameBehaviorParameters(beh,target);
|
|
}
|
|
break;
|
|
case CKM_BEHAVIORSETTINGSEDITED:
|
|
{
|
|
CKBehavior* target = (CKBehavior*) beh->GetLocalParameterObject(eTARGET_BEHAVIOR);
|
|
BOOL bb = FALSE;
|
|
if (target)
|
|
bb = (target->GetFlags() & CKBEHAVIOR_BUILDINGBLOCK)?TRUE:FALSE;
|
|
|
|
if (target==beh)// || bb) allow bb finally
|
|
{
|
|
//if (bb)
|
|
// behcontext.Context->OutputToConsole("CallBehavior BB cannot target another BB");
|
|
//else
|
|
behcontext.Context->OutputToConsole("CallBehavior BB cannot target itself");
|
|
beh->SetLocalParameterObject(eTARGET_BEHAVIOR,0);
|
|
beh->SetName(CALLBEHAVIOR_NAME);
|
|
RemoveIOxParams(beh);
|
|
|
|
behcontext.Context->SendInterfaceMessage(CKUIM_CALLBEHAVIORBB_CHANGE,(CKDWORD)beh,eCallBehavior_Edit,0);//warn interface
|
|
|
|
return CKBR_PARAMETERERROR;
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//Fit IOs & Params
|
|
if (CKIsChildClassOf(target,CKCID_BEHAVIOR) && target->GetOwner())
|
|
{
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//Params
|
|
int inCountTarget = target->GetInputParameterCount();
|
|
int outCountTarget = target->GetOutputParameterCount();
|
|
|
|
int inCountCaller = beh->GetInputParameterCount();
|
|
int outCountCaller = beh->GetOutputParameterCount();
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//remove params if too much
|
|
for (int i=inCountCaller-1;i>=eINPUTS+inCountTarget;i--)
|
|
behcontext.Context->DestroyObject(beh->RemoveInputParameter(i),CK_DESTROY_NONOTIFY,0);
|
|
for (int i=outCountCaller-1;i>=eOUTPUTS+outCountTarget;i--)
|
|
behcontext.Context->DestroyObject(beh->RemoveOutputParameter(i),CK_DESTROY_NONOTIFY,0);
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//create params if not enough
|
|
inCountCaller = beh->GetInputParameterCount();
|
|
outCountCaller = beh->GetOutputParameterCount();
|
|
|
|
for (int i=inCountCaller-eINPUTS;i<inCountTarget;i++)
|
|
{
|
|
CKParameterIn* pin = target->GetInputParameter(i);
|
|
beh->CreateInputParameter(pin->GetName(),pin->GetGUID());
|
|
}
|
|
for (int i=outCountCaller-eOUTPUTS;i<outCountTarget;i++)
|
|
{
|
|
CKParameterOut* pout = target->GetOutputParameter(i);
|
|
beh->CreateOutputParameter(pout->GetName(),pout->GetGUID());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//IOs
|
|
inCountTarget = target->GetInputCount();
|
|
outCountTarget = target->GetOutputCount();
|
|
|
|
inCountCaller = beh->GetInputCount();
|
|
outCountCaller = beh->GetOutputCount();
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//remove IOS if too much
|
|
for (int i=inCountCaller-1;i>=eINS+inCountTarget;i--)
|
|
beh->DeleteInput(i);
|
|
for (int i=outCountCaller-1;i>=eOUTS+outCountTarget;i--)
|
|
beh->DeleteOutput(i);
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//create IOS if not enough
|
|
inCountCaller = beh->GetInputCount();
|
|
outCountCaller = beh->GetOutputCount();
|
|
|
|
for (int i=inCountCaller-eINS;i<inCountTarget;i++)
|
|
{
|
|
CKBehaviorIO* io = target->GetInput(i);
|
|
beh->CreateInput(io->GetName());
|
|
}
|
|
for (int i=outCountCaller-eOUTS;i<outCountTarget;i++)
|
|
{
|
|
CKBehaviorIO* io = target->GetOutput(i);
|
|
beh->CreateOutput(io->GetName());
|
|
}
|
|
|
|
//rename
|
|
BehaviorsParameters::NameBehaviorParameters(beh,target);
|
|
if (target && target->GetName())
|
|
{
|
|
XString finalName;
|
|
finalName.Format("%s:%s",CALLBEHAVIOR_NAME,target->GetName());
|
|
beh->SetName(finalName.Str());
|
|
}
|
|
}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
else //remove all supplementary pins & pouts from BB
|
|
{
|
|
RemoveIOxParams(beh);
|
|
beh->SetName(CALLBEHAVIOR_NAME);
|
|
}
|
|
|
|
{
|
|
CKBehavior* target = (CKBehavior*) beh->GetLocalParameterObject(eTARGET_BEHAVIOR);
|
|
behcontext.Context->SendInterfaceMessage(CKUIM_CALLBEHAVIORBB_CHANGE,(CKDWORD)beh,eCallBehavior_Edit,(CKDWORD)target);//warn interface
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case CKM_BEHAVIORDELETE:
|
|
case CKM_BEHAVIORDETACH:
|
|
{
|
|
CKBehavior* target = (CKBehavior*) beh->GetLocalParameterObject(eTARGET_BEHAVIOR);
|
|
behcontext.Context->SendInterfaceMessage(CKUIM_CALLBEHAVIORBB_CHANGE,(CKDWORD)beh,eCallBehavior_Detach,(CKDWORD)target);//warn interface
|
|
}
|
|
break;
|
|
case CKM_BEHAVIORLOAD:
|
|
case CKM_BEHAVIORATTACH:
|
|
{
|
|
CKBehavior* target = (CKBehavior*) beh->GetLocalParameterObject(eTARGET_BEHAVIOR);
|
|
behcontext.Context->SendInterfaceMessage(CKUIM_CALLBEHAVIORBB_CHANGE,(CKDWORD)beh,eCallBehavior_Attach,(CKDWORD)target);//warn interface
|
|
if (behcontext.Context->IsInInterfaceMode())
|
|
{
|
|
if (target && target->GetName())
|
|
{
|
|
XString finalName;
|
|
finalName.Format("%s:%s",CALLBEHAVIOR_NAME,target->GetName());
|
|
beh->SetName(finalName.Str());
|
|
}
|
|
}
|
|
|
|
}
|
|
break;
|
|
}
|
|
return CK_OK;
|
|
}
|