/* ******************************************************************* * Function: int BehaviourFunction( const CKBehaviorContext& behaviorContext ) * * Description : The execution function is the function that will be called * during the process loop of the behavior engine, if the behavior * is defined as using an execution function. This function is not * called if the behavior is defined as a graph. This function is the * heart of the behavior: it should compute the essence of the behavior, * in an incremental way. The minimum amount of computing should be * done at each call, to leave time for the other behaviors to run. * The function receives the delay in milliseconds that has elapsed * since the last behavioral process, and should rely on this value to * manage the amount of effect it has on its computation, if the effect * of this computation relies on time. * * Parameters : * behaviourContext r Behavior context reference, which gives access to * frequently used global objects ( context, level, manager, etc... ) * * Returns : int, If it is done, it should return CKBR_OK. If it returns * CKBR_ACTIVATENEXTFRAME, the behavior will again be called * during the next process loop. * ******************************************************************* */ int GBLLDGetSetup::BehaviourFunction( const CKBehaviorContext& behaviorContext ) { CKBehavior *beh; CKContext *context; GBLLDManager *GBLLDMan; XString DBName; CKBOOL logging; XString ODBCName; XString proxyLogin; XString proxyPassword; XString serverAddress; XString serverLogin; XString serverPassword; CKBOOL serverMode; XString userName; int virtoolsUserID; CKBOOL webPlayerMode; int ConnectionID; if ( (beh = behaviorContext.Behavior) == NULL ) return CKBR_BEHAVIORERROR; if ( (context = behaviorContext.Context) == NULL ) return CKBR_BEHAVIORERROR; if ( (GBLLDMan = (GBLLDManager*)context->GetManagerByGuid(GBLLDManagerGUID)) == NULL ) return CKBR_BEHAVIORERROR; beh->ActivateInput( POS_I_IN, FALSE ); // Force the reading of the attributes GBLLDMan->ReadSetup(); ConnectionID = GBLLDMan->GetConnectionID(); DBName = GBLLDMan->GetDBName(); logging = GBLLDMan->IsLogging(); ODBCName = GBLLDMan->GetODBCName(); proxyLogin = GBLLDMan->GetProxyLogin(); proxyPassword = GBLLDMan->GetProxyPassword(); serverAddress = GBLLDMan->GetServerAddress(); serverLogin = GBLLDMan->GetServerLogin(); serverPassword = GBLLDMan->GetServerPassword(); serverMode = GBLLDMan->GetServerMode(); userName = GBLLDMan->GetUserName(); webPlayerMode = GBLLDMan->IsWebplayerMode(); virtoolsUserID = GBLLDMan->GetVirtoolsUserID(); beh->SetOutputParameterValue( POS_OP_CONNECTIONID, &ConnectionID ); beh->SetOutputParameterValue( POS_OP_DBNAME, DBName.CStr(), DBName.Length() ); beh->SetOutputParameterValue( POS_OP_LOGGING, &logging ); beh->SetOutputParameterValue( POS_OP_ODBCNAME, ODBCName.CStr(), ODBCName.Length() ); beh->SetOutputParameterValue( POS_OP_PROXYLOGIN, proxyLogin.CStr(), proxyLogin.Length() ); beh->SetOutputParameterValue( POS_OP_PROXYPASSWORD, proxyPassword.CStr(), proxyPassword.Length() ); beh->SetOutputParameterValue( POS_OP_SERVERADDRESS, serverAddress.CStr(), serverAddress.Length() ); beh->SetOutputParameterValue( POS_OP_SERVERLOGIN, serverLogin.CStr(), serverLogin.Length() ); beh->SetOutputParameterValue( POS_OP_SERVERMODE, &serverMode ); beh->SetOutputParameterValue( POS_OP_SERVERPASSWORD, serverPassword.CStr(), serverPassword.Length() ); beh->SetOutputParameterValue( POS_OP_USERNAME, userName.CStr(), userName.Length() ); beh->SetOutputParameterValue( POS_OP_WEBPLAYERMODE, &webPlayerMode ); beh->SetOutputParameterValue( POS_OP_VIRTOOLSUSERID, &virtoolsUserID ); beh->ActivateOutput( POS_O_OUT, TRUE ); return CKBR_OK; }
void PhysicManager::_checkObjectsByAttribute(CKScene *newScene) { CKAttributeManager* attman = m_Context->GetAttributeManager(); int sizeJFuncMap = ATT_FUNC_TABLE_SIZE;//(sizeof(*getRegistrationTable()) / sizeof((getRegistrationTable())[0])); for (int fIndex = 0 ; fIndex < sizeJFuncMap ; fIndex ++) { std::vector<int>attributeIdList; pFactory::Instance()->findAttributeIdentifiersByGuid(getRegistrationTable()[fIndex].guid,attributeIdList); int attCount = attributeIdList.size(); for (int i = 0 ; i < attCount ; i++ ) { int currentAttType = attributeIdList.at(i); const XObjectPointerArray& Array = attman->GetAttributeListPtr( attributeIdList.at(i) ); for (CKObject** it = Array.Begin(); it != Array.End(); ++it) { CK3dEntity *target = static_cast<CK3dEntity*>(*it); if (target) { XString error; error.Format("Registering :%s with %s",target->GetName(),attman->GetAttributeNameByType(currentAttType)); //if(!strcmp( target->GetName(),"smutan3-3" ) ) { // xLogger::xLog(XL_START,ELOGTRACE,E_LI_MANAGER,"problem case" ); } // CKScene *levelScene = GetContext()->GetCurrentLevel()->GetCurrentScene(); // we check as no scene is current in use if ( ( GetContext()->GetCurrentLevel()->GetLevelScene() == newScene && !isSceneObject2(target) ) || ( newScene && newScene->IsObjectHere(target) && newScene !=GetContext()->GetCurrentLevel()->GetLevelScene() ) || ( newScene && GetContext()->GetCurrentLevel()->GetCurrentScene() && GetContext()->GetCurrentLevel()->GetCurrentScene() == newScene && newScene !=GetContext()->GetCurrentLevel()->GetLevelScene() && newScene->IsObjectHere(target) ) || ( (physicFlags & PMF_DONT_DELETE_SCENES) ) ) { xLogger::xLog(XL_START,ELOGTRACE,E_LI_MANAGER,error.CStr() ); (*getRegistrationTable()[fIndex].rFunc)(target,currentAttType,true,false); GetPMan()->getCheckList().PushBack(target->GetID()); } } } } } }
pTireFunction pFactory::createTireFuncFromParameter(CKParameter *par) { pTireFunction result; result.setToDefault(); if (!par) { return result; } result.extremumSlip = vtTools::ParameterTools::GetValueFromParameterStruct<float>(par,1); result.extremumValue = vtTools::ParameterTools::GetValueFromParameterStruct<float>(par,2); result.asymptoteSlip = vtTools::ParameterTools::GetValueFromParameterStruct<float>(par,3); result.asymptoteValue= vtTools::ParameterTools::GetValueFromParameterStruct<float>(par,4); result.stiffnessFactor = vtTools::ParameterTools::GetValueFromParameterStruct<float>(par,5); /************************************************************************/ /* Lat Tire Func from XML ? */ /************************************************************************/ int xmlLinkId = vtTools::ParameterTools::GetValueFromParameterStruct<int>(par,0); if (xmlLinkId!=0) { XString nodeName = vtAgeia::getEnumDescription(GetPMan()->GetContext()->GetParameterManager(),VTE_XML_TIRE_SETTINGS,xmlLinkId ); loadFrom(result,nodeName.CStr(),getDefaultDocument()); if (!result.isValid()) { xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,"Latitude Tire Function was incorrect, setting to default"); result.setToDefault(); }else{ copyTo((CKParameterOut*)par,result); } } if (!result.isValid()) { result.setToDefault(); } return result; }
int CCustomPlayer::_InitRenderEngines(CKPluginManager& iPluginManager) { // here we look for the render engine (ck2_3d) int count = iPluginManager.GetPluginCount(CKPLUGIN_RENDERENGINE_DLL); for (int i=0;i<count;i++) { CKPluginEntry* desc = iPluginManager.GetPluginInfo(CKPLUGIN_RENDERENGINE_DLL,i); CKPluginDll* dll = iPluginManager.GetPluginDllInfo(desc->m_PluginDllIndex); #if !defined(CUSTOM_PLAYER_STATIC) XWORD pos = dll->m_DllFileName.RFind(DIRECTORY_SEP_CHAR); if (pos==XString::NOTFOUND) continue; XString str = dll->m_DllFileName.Substring(pos+1); if (strnicmp(str.CStr(),"ck2_3d",strlen("ck2_3d"))==0) return i; #else if (dll->m_DllFileName.ICompare("ck2_3d")==0) return i; #endif } return -1; }
/* ******************************************************************* * Function: int BehaviourFunction() * * Description : Returns the number of plugins in this DLL * * Paramters : * CKBehaviorContext& r The virtools behaviour context * * Returns : One of the many virtools return values * ******************************************************************* */ int CGBLFileSystem::BehaviourFunction(const CKBehaviorContext& behContext) { BOOL error = FALSE; // Quick bit of error checking CKBehavior* beh = behContext.Behavior; CKBeObject* beObject = beh->GetTarget(); int fileSystemBrowseMode = 0; if (!beObject) { error = TRUE; } if (!error) { // Reset On input, if active if (beh->IsInputActive(eBehInputOn)) { beh->ActivateInput(eBehInputOn, FALSE); // Clear error message output beh->SetOutputParameterValue(eParamOutputErrorMsg, EMPTY_STRING); } // see which mode we are in beh->GetInputParameterValue(eParamInputMode, &fileSystemBrowseMode); } if (!error) { // See if we have the special case char *currentFolder = NULL; currentFolder = (char*)(beh->GetInputParameterReadDataPtr(eParamInputCurrentFolder)); XString scannedFolder = currentFolder; if (currentFolder) { // special case takes priority over FILES / FOLDER mode if (strcmp(currentFolder,SPECIAL_CASE)==0) { beh->SetOutputParameterValue(eParamOutputScannedFolder, scannedFolder.CStr(),scannedFolder.Length()+1 ); if (fileSystemBrowseMode == eFolder) { if (GetLogicalDrives(beh)) { // Everythings gone ok we have a list of the logical drives beh->ActivateOutput(eBehOutputDone, TRUE); } else { // Something went wrong beh->SetOutputParameterValue(eParamOutputErrorMsg, "Failed To Scan The Logical Drives"); beh->ActivateOutput(eBehOutputError, TRUE); } } else { // Cant scan for files in the SPECIAL_CASE // Get the destination data array and clear it out CKDataArray* dataArray = static_cast<CKDataArray*>(beh->GetInputParameterObject(eParamInputDataArray)); if (!dataArray) { CGBLWidget::OutputBBErrorMsg(beh, "Please attatch an array to the BB"); } else { dataArray->Clear(); dataArray->AddRow(); int currentRow = dataArray->GetRowCount()-1; // 0 index dataArray->SetElementStringValue(currentRow,NAME_COLUMN,NOT_FOUND); beh->ActivateOutput(eBehOutputDone, TRUE); } } } else { // add a "\" to the end, it makes the ouput consistent. int len = strlen (scannedFolder.CStr()); if ((scannedFolder[len-1])!=SINGLE_SEPERATOR) { scannedFolder << SINGLE_SEPERATOR; } // Try to scan the passed folder if (GetData(beh,fileSystemBrowseMode)==FALSE) { // Error Handling we can handle errors here // We most likely got here because the user doesnt have access to the folder. if (fileSystemBrowseMode == eFile) { beh->SetOutputParameterValue(eParamOutputErrorMsg, "Failed To Scan Files"); } else { beh->SetOutputParameterValue(eParamOutputErrorMsg, "Failed To Scan Folders"); } beh->ActivateOutput(eBehOutputDone, TRUE); // Handleable, recoverable errors, so dont set the error flag //beh->ActivateOutput(eBehOutputError, TRUE); } else { // No errors beh->SetOutputParameterValue(eParamOutputScannedFolder, scannedFolder.CStr(), scannedFolder.Length() + 1); beh->ActivateOutput(eBehOutputDone, TRUE); } } } else { // Dont think we can ever get here becuase "" is a valid folder. // Just in case though. beh->SetOutputParameterValue(eParamOutputErrorMsg, "Please Supply a Folder To Scan"); beh->ActivateOutput(eBehOutputError, TRUE); } } return CKBR_OK; }
NxMaterialDesc* pFactory::createMaterialFromEntity(CKBeObject*object) { ////////////////////////////////////////////////////////////////////////// //sanity checks : if (!object ) { return NULL; } if (!object->HasAttribute(GetPMan()->att_surface_props)) { return NULL; } ////////////////////////////////////////////////////////////////////////// CKParameterManager *pm = object->GetCKContext()->GetParameterManager(); int parameterType = pm->ParameterGuidToType(VTE_XML_MATERIAL_TYPE); NxMaterialDesc *result = new NxMaterialDesc(); using namespace vtTools::AttributeTools; XString nodeName; int enumID = GetValueFromAttribute<int>(object,GetPMan()->att_surface_props,0); if (enumID==0) { goto takeFromAttribute; } CKEnumStruct *enumStruct = pm->GetEnumDescByType(parameterType); if ( enumStruct ) { for (int i = 0 ; i < enumStruct->GetNumEnums() ; i ++ ) { if(i == enumID) { nodeName = enumStruct->GetEnumDescription(i); if (nodeName.Length()) { result = createMaterialFromXML(nodeName.CStr(),getDefaultDocument()); if (result) { return result; } } } } } takeFromAttribute : { float dynamicFriction = GetValueFromAttribute<float>(object,GetPMan()->att_surface_props,1); if (dynamicFriction >=0.0f) { result->dynamicFriction =dynamicFriction; } float statFriction = GetValueFromAttribute<float>(object,GetPMan()->att_surface_props,2); if (statFriction>=0.0f) { result->staticFriction=statFriction; } float rest = GetValueFromAttribute<float>(object,GetPMan()->att_surface_props,3); if (rest>=0.0f) { result->restitution=rest; } float dynamicFrictionV = GetValueFromAttribute<float>(object,GetPMan()->att_surface_props,4); if (dynamicFrictionV >=0.0f) { result->dynamicFrictionV =dynamicFrictionV; } float staticFrictionV = GetValueFromAttribute<float>(object,GetPMan()->att_surface_props,5); if (staticFrictionV>=0.0f) { result->staticFriction=staticFrictionV; } VxVector anis = GetValueFromAttribute<VxVector>(object,GetPMan()->att_surface_props,6); if (anis.Magnitude()>=0.01f) { result->dirOfAnisotropy=pMath::getFrom(anis); } int fMode = GetValueFromAttribute<int>(object,GetPMan()->att_surface_props,7); if (fMode !=-1) { result->frictionCombineMode=(NxCombineMode)fMode; } int rMode = GetValueFromAttribute<int>(object,GetPMan()->att_surface_props,8); if (rMode !=-1) { result->restitutionCombineMode=(NxCombineMode)rMode; } return result; } return result; }
int GBLCOCreateError::BehaviourFunction( const CKBehaviorContext& behContext ) { CKBehavior *behaviour = behContext.Behavior; CKContext *context = behContext.Context; if ( behaviour == NULL || context == NULL ) return CKBR_GENERICERROR; behaviour->ActivateInput(ECGBLCOCreateErrorBehInputs::In, FALSE); CGBLCOErrorManager *errorManager = (CGBLCOErrorManager *)context->GetManagerByGuid(CGBLCOErrorManagerGUID); if ( errorManager == NULL ) return CKBR_GENERICERROR; // Get Parameters Inputs Source. CKParameterOut *poutError = behaviour->GetOutputParameter(ECGBLCOCreateErrorParamOutputs::GetError); if ( poutError == NULL ) return CKBR_GENERICERROR; CKParameterIn*pinCode = behaviour->GetInputParameter(ECGBLCOCreateErrorParamInputs::SetErrorCode); CKParameterIn*pinDesc = behaviour->GetInputParameter(ECGBLCOCreateErrorParamInputs::SetErrorDescription); CKParameterIn*pinType = behaviour->GetInputParameter(ECGBLCOCreateErrorParamInputs::SetErrorType); if ( pinCode == NULL || pinDesc == NULL || pinType == NULL ) return CKBR_GENERICERROR; CKParameter*paraCode = pinCode->GetRealSource(); CKParameter*paraDesc = pinDesc->GetRealSource(); CKParameter*paraType = pinType->GetRealSource(); if ( paraCode == NULL || paraDesc == NULL || paraType == NULL ) return CKBR_GENERICERROR; // Get Parameters Inputs Values (code,desc,type). int code = 0; paraCode->GetValue(&code); XString desc; int paramsize = paraDesc->GetStringValue(NULL); if (paramsize) { XAP<char> paramstring(new char[paramsize]); paraDesc->GetStringValue(paramstring,TRUE); desc << (char*)paramstring; } CGBLCOError::EGBLCOErrorType type; paraType->GetValue(&type); // Create the TGBLError parameter output. TGBLError::SetTGBLError(poutError,type,code,(CKSTRING)desc.CStr()); CK_CLASSID cid = poutError->GetClassID(); // if ( type != CGBLCOError::EGBLCOErrorType::GBLCO_FATAL ) { behaviour->ActivateOutput(ECGBLCOCreateErrorBehOutputs::OutHandled, FALSE); behaviour->ActivateOutput(ECGBLCOCreateErrorBehOutputs::OutUnhandled, TRUE); return CKBR_OK; } errorManager->NotifyError(type,code,(CKSTRING)desc.CStr()); behaviour->ActivateOutput(ECGBLCOCreateErrorBehOutputs::OutHandled, TRUE); behaviour->ActivateOutput(ECGBLCOCreateErrorBehOutputs::OutUnhandled, FALSE); return CKBR_OK; }
int pFactory::copyTo(pWheelDescr *dst,CKParameter *src) { int result = 1; if (!src || !dst) { return NULL; } using namespace vtTools::ParameterTools; dst->setToDefault(); dst->wheelSuspension = GetValueFromParameterStruct<float>(src,E_WD_SUSPENSION); dst->springRestitution= GetValueFromParameterStruct<float>(src,E_WD_SPRING_RES); dst->springBias = GetValueFromParameterStruct<float>(src,E_WD_SPRING_BIAS); dst->springDamping= GetValueFromParameterStruct<float>(src,E_WD_DAMP); dst->maxBrakeForce= GetValueFromParameterStruct<float>(src,E_WD_MAX_BFORCE); dst->frictionToSide= GetValueFromParameterStruct<float>(src,E_WD_FSIDE); dst->frictionToFront= GetValueFromParameterStruct<float>(src,E_WD_FFRONT); CKParameterOut *pOld = GetParameterFromStruct(src,E_WD_INVERSE_WHEEL_MASS); if (pOld) { if (pOld->GetGUID() == CKPGUID_FLOAT) { dst->inverseWheelMass= GetValueFromParameterStruct<float>(src,E_WD_INVERSE_WHEEL_MASS); } if (pOld->GetGUID() == CKPGUID_INT) { dst->wheelApproximation= GetValueFromParameterStruct<int>(src,E_WD_INVERSE_WHEEL_MASS); } } //dst->wheelApproximation= GetValueFromParameterStruct<int>(float,E_WD_INVERSE_WHEEL_MASS); dst->wheelFlags= (WheelFlags)GetValueFromParameterStruct<int>(src,E_WD_FLAGS); dst->wheelShapeFlags=(WheelShapeFlags) GetValueFromParameterStruct<int>(src,E_WD_SFLAGS); CKParameterOut *parLatFunc = GetParameterFromStruct(src,E_WD_LAT_FUNC); CKParameterOut *parLongFunc = GetParameterFromStruct(src,E_WD_LONG_FUNC); /************************************************************************/ /* XML Setup ? */ /************************************************************************/ int xmlLinkId= GetValueFromParameterStruct<int>(src,E_WD_XML); bool wIsXML=false; bool latIsXML= false; bool longIsXML=false; XString nodeName; if ( xmlLinkId !=0 ) { nodeName = vtAgeia::getEnumDescription(GetPMan()->GetContext()->GetParameterManager(),VTE_XML_WHEEL_SETTINGS,xmlLinkId); loadWheelDescrFromXML(*dst,nodeName.CStr(),getDefaultDocument()); wIsXML =true; if (!dst->isValid()) { xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,"Wheel Description was invalid"); } if (dst->latFunc.xmlLink!=0) { latIsXML=true; } if (dst->longFunc.xmlLink!=0) { longIsXML=true; } } if (!latIsXML) { dst->latFunc = createTireFuncFromParameter(parLatFunc); } if (!longIsXML) { dst->longFunc= createTireFuncFromParameter(parLongFunc); } if (wIsXML) { copyTo((CKParameterOut*)src,dst); } if (longIsXML) { copyTo(GetParameterFromStruct(src,E_WD_LONG_FUNC),dst->longFunc); } if (latIsXML) { copyTo(GetParameterFromStruct(src,E_WD_LAT_FUNC),dst->latFunc); } return result; }
pWheel *pFactory::createWheelSubShape(pRigidBody *body,CK3dEntity* subEntity,CKMesh *mesh,pObjectDescr *descr,VxVector localPos, VxQuaternion localRotation,NxShape*dstShape) { //################################################################ // // Sanity checks // #ifdef _DEBUG assert(body && subEntity && descr ); // Should never occur ! #endif // _DEBUG XString errorStr; //################################################################ // // Retrieve the wheel setting from attribute // int attTypeWheelSettings = GetPMan()->att_wheelDescr; int attTypeConvexCylinderSettings = GetPMan()->getAttributeTypeByGuid(VTS_PHYSIC_CONVEX_CYLDINDER_WHEEL_DESCR); if (!subEntity->HasAttribute(attTypeWheelSettings)) { errorStr.Format("Object %s has been set as wheel but there is no wheel attribute attached",subEntity->GetName()); xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,errorStr.CStr()); return NULL; } pWheelDescr *wDescr = new pWheelDescr(); CKParameterOut *par = subEntity->GetAttributeParameter(attTypeWheelSettings); if (par) { int err = copyTo(wDescr,par); if (!wDescr->isValid() ) { xLogger::xLog(XL_START,ELOGERROR,E_LI_MANAGER,"Wheel Description is invalid"); SAFE_DELETE(wDescr); return NULL; } } //################################################################ // // Construct the final wheel object basing on the type of the wheel // pWheel *result = NULL; //if(wDescr->wheelFlags & WF_UseWheelShape) { result = new pWheel2(body,wDescr,subEntity); /*else { //################################################################ // Wheel type 1 specified, check there is also a override for the convex cylinder if (!subEntity->HasAttribute(attTypeConvexCylinderSettings)) { errorStr.Format("Object %s has been created with default settings for convex cylinder shape",subEntity->GetName()); xLogger::xLog(XL_START,ELOGWARNING,E_LI_MANAGER,errorStr.CStr()); } result = new pWheel1(body,wDescr); }*/ //################################################################ // // Create the wheel shape // //if(wDescr->wheelFlags & WF_UseWheelShape){ dstShape=_createWheelShape2(body->getActor(),descr,wDescr,subEntity,mesh,localPos,localRotation); ((pWheel2*)result)->setWheelShape((NxWheelShape*)dstShape); // } /*else { dstShape=_createWheelShape1(body->getActor(),(pWheel1*)result,descr,wDescr,subEntity,mesh,localPos,localRotation); }*/ if (!dstShape) { errorStr.Format("Couldn't create wheel shape for object %s",subEntity->GetName()); xLogger::xLog(XL_START,ELOGWARNING,E_LI_MANAGER,errorStr.CStr()); SAFE_DELETE(wDescr); SAFE_DELETE(result); return NULL; } //################################################################ // // Finalize wheel setup // result->setEntID(subEntity->GetID()); return result; }
/* ******************************************************************* * Function: int BehaviourFunction() * * Description : * * Paramters : * CKBehaviorContext& r The virtools behaviour context * * Returns : One of the many virtools return values * ******************************************************************* */ int CGBLLOStringBuilder::BehaviourFunction(const CKBehaviorContext& behContext) { CKBehavior* beh = behContext.Behavior; CKBeObject* beObject = beh->GetTarget(); CKBOOL error = FALSE; XString outString = NULL; // error check to ensure virtools is working ok if (!beObject) { error = TRUE; CKParameterOut *parameterOutError = beh->GetOutputParameter(EGBLStringBuilderParamOutputs::eParamGetError); TGBLError::SetTGBLError(parameterOutError,CGBLCOError::EGBLCOErrorType::GBLCO_FATAL,LOI_ERROR_NO_BEHAVIOUR_STATE,LOI_ERROR_NO_BEHAVIOUR_DESC); beh->SetOutputParameterValue(eParamGetError, parameterOutError); beh->ActivateOutput(eBehOutputError, TRUE); } int lengthOfSource = 0; int lengthOfInsert = 0; int insertPosition = 0; if (!error) { // Reset On input, if active if (beh->IsInputActive(eBehInputOn)) { beh->ActivateInput(eBehInputOn, FALSE); } // get the BB params into variables to work with XString sourceString = NULL; sourceString = (CKSTRING)(beh->GetInputParameterReadDataPtr(eParamSetSourceString)); XString insertString = NULL; insertString = (CKSTRING)(beh->GetInputParameterReadDataPtr(eParamSetInsertString)); beh->GetInputParameterValue(eParamSetInsertPosition,&insertPosition); lengthOfSource = strlen(sourceString.Str()); lengthOfInsert = strlen(insertString.Str()); // Simple bounds checking and error recovery if (insertPosition<0) { insertPosition=0; } if (insertPosition>lengthOfSource) { outString = sourceString; outString += insertString; } else { // a little more error checking and simple recovery // deal with the special cases first if (lengthOfSource<=0) { // an empty source outString = insertString; } else if (insertPosition == 0) { outString = insertString; outString += sourceString; } else { // build up the new string XString start = NULL; XString end = NULL; start = sourceString.Substring(0,insertPosition); end = sourceString.Substring(insertPosition,lengthOfSource); outString = start ; outString += insertString; outString += end; } } } if (!error) { int newCartPos = insertPosition+lengthOfInsert; beh->SetOutputParameterValue(eParamGetCarretPosition,&newCartPos); beh->SetOutputParameterValue(eParamGetNewText, outString.CStr(), outString.Length() + 1); beh->ActivateOutput(eBehOutputDone, TRUE); } return CKBR_OK; }