Input AIManager::getInput(unsigned int playerNum) { updateRecovery(playerNum); return followPath(playerNum); //return followRandomPath(playerNum); //Test function }
bool Actor::handleOrder(TrackOrder &order, EntityEvent event, const EntityEventParams ¶ms) { if(event == EntityEvent::init_order || event == EntityEvent::think) { order.m_time_for_update -= timeDelta(); const Entity *target = refEntity(order.m_target); if(!target) return false; if(order.m_time_for_update < 0.0f) { fixPosition(); int3 cur_pos = (int3)pos(); int3 target_pos; FBox target_box = target->boundingBox(); if(!world()->findClosestPos(target_pos, cur_pos, enclosingIBox(target_box), ref())) return failOrder(); order.m_path_pos = PathPos(); if(!world()->findPath(order.m_path, cur_pos, target_pos, ref())) return failOrder(); order.m_time_for_update = 0.25f; } if(distance(boundingBox(), target->boundingBox()) <= order.m_min_distance) return false; if(event == EntityEvent::init_order) { if(order.m_please_run && m_proto.simpleAnimId(Action::run, m_stance) == -1) order.m_please_run = 0; if(!animate(order.m_please_run? Action::run : Action::walk)) return failOrder(); } FollowPathResult result = order.needCancel()? FollowPathResult::finished : followPath(order.m_path, order.m_path_pos, order.m_please_run); if(result != FollowPathResult::moved) return false; } if(order.m_path.length(order.m_path_pos) > 1.0f) { if(event == EntityEvent::anim_finished && m_stance == Stance::crouch) { animate(m_action); } if(event == EntityEvent::step) { SurfaceId standing_surface = surfaceUnder(); playSound(m_proto.step_sounds[m_stance][standing_surface], pos()); } } return true; }
void printPath(FILE*out, Graph G, char D[]){ int j; for (j = 1; j <= G->numV; j++) if (strcmp(D, G->vertex[j].id) == 0)break; if (j > G->numV) fprintf(out, "\nNo such node %s\n", D); else{ fprintf(out, "\nPath to %s: ", D); followPath(out, G, j); fprintf(out, "\n"); } }
void TankAI::explore() { //choose some random position on the map and find a way from here to this position while (_path == NULL) { Point randomGoal = _scene.getTerrain().getRandomPointOnMap(); _path = _scene.getTerrain().findPath(_tank->getPosition(), randomGoal); } followPath(); //as long as we dont have a target, do some searching animation _tank->setAzimuth(_tank->getAzimuth() + 5); }
void printCostPath(FILE*out, Graph G, char c[]){ int j; for (j = 1; j <= G->numV; j++){ if (strcmp(G->vertex[j].id, c) != 0){ fprintf(out, " to %-16s: %4d, Path: ", G->vertex[j].id, G->vertex[j].cost); if (G->vertex[j].cost != INFINITY) followPath(out, G, j); else fprintf(out, "unreachable"); fprintf(out, "\n"); } } }
void TankAI::escape() { //choose some random position on the map and find a way from here to this position while (_path == NULL) { Point randomGoal; do { randomGoal = _scene.getTerrain().getRandomPointOnMap(); } while (Utils::distance(_currentTarget->getPosition(), randomGoal) > SMALLTANK_ESCAPE_DISTANCE); _path = _scene.getTerrain().findPath(_tank->getPosition(), randomGoal); } followPath(); }
bool CCPathFinderNetwork::findPath(CCCollideable *objectToPath, Path &pathResult, const PathNode *fromNode, const PathNode *toNode) { if( fromNode != NULL && toNode != NULL ) { NodesList<const PathNode, 50> previousNodes; previousNodes.add( fromNode ); pathTargetNode = toNode; path.distance = 0.0f; pathingFrom = fromNode; if( followPath( objectToPath, path, 0, 0.0f, previousNodes, fromNode, toNode ) ) { pathResult = path; return true; } } return false; }
void TankAI::hunt() { //choose some random position on the map and find a way from here to this position if (Utils::distance(_tank->getPosition(), _currentTarget->getPosition()) > SHOOTING_DISTANCE) { while (_path == NULL) { Point randomGoal; do { randomGoal = _scene.getTerrain().getRandomPointOnMap(); } while (Utils::distance(randomGoal, _currentTarget->getPosition()) < SHOOTING_DISTANCE); _path = _scene.getTerrain().findPath(_tank->getPosition(), randomGoal); } followPath(); } aim(); if (_tank->_reloadingTime == 0) { //shoot _tank->fireBullet(); _tank->_reloadingTime = SMALLTANK_RELOADING_TIME; } }
void Drone::update() { assert(ask_ != 0); /* rotateVelocity(); */ if (current_path_ == 0) { vel_ *= 0; } static bool once = true; float elpsd = clk_.GetElapsedTime(); if (elpsd >= Drone::kSeekTime && once) { ask_->resetWeights(); ask_->setAutoTarget(); if (ask_->seek()) { ask_->buildPath(); delete current_path_; current_path_ = 0; current_path_ = new Path; *current_path_ = ask_->path(); moveToPoint(ask_->startCell()->screen_position); } clk_.Reset(); once = false; } else { followPath(); } pos_ += vel_ * speed_; Entity::update(); }
bool AdActor::update() { _currentSprite = nullptr; if (_state == STATE_READY) { if (_animSprite) { delete _animSprite; _animSprite = nullptr; } if (_animSprite2) { _animSprite2 = nullptr; } } // finished playing animation? if (_state == STATE_PLAYING_ANIM && _animSprite != nullptr && _animSprite->isFinished()) { _state = _nextState; _nextState = STATE_READY; _currentSprite = _animSprite; } if (_state == STATE_PLAYING_ANIM_SET && _animSprite2 != nullptr && _animSprite2->isFinished()) { _state = _nextState; _nextState = STATE_READY; _currentSprite = _animSprite2; } if (_sentence && _state != STATE_TALKING) { _sentence->finish(); } // default: stand animation if (!_currentSprite) { if (_sprite) { _currentSprite = _sprite; } else { if (_standSprite) { _currentSprite = _standSprite->getSprite(_dir); } else { AdSpriteSet *anim = getAnimByName(_idleAnimName); if (anim) { _currentSprite = anim->getSprite(_dir); } } } } bool already_moved = false; switch (_state) { ////////////////////////////////////////////////////////////////////////// case STATE_PLAYING_ANIM: _currentSprite = _animSprite; break; ////////////////////////////////////////////////////////////////////////// case STATE_PLAYING_ANIM_SET: _currentSprite = _animSprite2; break; ////////////////////////////////////////////////////////////////////////// case STATE_TURNING_LEFT: if (_tempSprite2 == nullptr || _tempSprite2->isFinished()) { if (_dir > 0) { _dir = (TDirection)(_dir - 1); } else { _dir = (TDirection)(NUM_DIRECTIONS - 1); } if (_dir == _targetDir) { _tempSprite2 = nullptr; _state = _nextState; _nextState = STATE_READY; } else { if (_turnLeftSprite) { _tempSprite2 = _turnLeftSprite->getSprite(_dir); } else { AdSpriteSet *anim = getAnimByName(_turnLeftAnimName); if (anim) { _tempSprite2 = anim->getSprite(_dir); } } if (_tempSprite2) { _tempSprite2->reset(); if (_tempSprite2->_looping) { _tempSprite2->_looping = false; } } _currentSprite = _tempSprite2; } } else { _currentSprite = _tempSprite2; } break; ////////////////////////////////////////////////////////////////////////// case STATE_TURNING_RIGHT: if (_tempSprite2 == nullptr || _tempSprite2->isFinished()) { _dir = (TDirection)(_dir + 1); if ((int)_dir >= (int)NUM_DIRECTIONS) { _dir = (TDirection)(0); } if (_dir == _targetDir) { _tempSprite2 = nullptr; _state = _nextState; _nextState = STATE_READY; } else { if (_turnRightSprite) { _tempSprite2 = _turnRightSprite->getSprite(_dir); } else { AdSpriteSet *anim = getAnimByName(_turnRightAnimName); if (anim) { _tempSprite2 = anim->getSprite(_dir); } } if (_tempSprite2) { _tempSprite2->reset(); if (_tempSprite2->_looping) { _tempSprite2->_looping = false; } } _currentSprite = _tempSprite2; } } else { _currentSprite = _tempSprite2; } break; ////////////////////////////////////////////////////////////////////////// case STATE_SEARCHING_PATH: // keep asking scene for the path if (((AdGame *)_gameRef)->_scene->getPath(BasePoint(_posX, _posY), *_targetPoint, _path, this)) { _state = STATE_WAITING_PATH; } break; ////////////////////////////////////////////////////////////////////////// case STATE_WAITING_PATH: // wait until the scene finished the path if (_path->_ready) { followPath(); } break; ////////////////////////////////////////////////////////////////////////// case STATE_FOLLOWING_PATH: getNextStep(); already_moved = true; break; ////////////////////////////////////////////////////////////////////////// case STATE_TALKING: { _sentence->update(_dir); if (_sentence->_currentSprite) { _tempSprite2 = _sentence->_currentSprite; } bool timeIsUp = (_sentence->_sound && _sentence->_soundStarted && (!_sentence->_sound->isPlaying() && !_sentence->_sound->isPaused())) || (!_sentence->_sound && _sentence->_duration <= _gameRef->getTimer()->getTime() - _sentence->_startTime); if (_tempSprite2 == nullptr || _tempSprite2->isFinished() || (/*_tempSprite2->_looping &&*/ timeIsUp)) { if (timeIsUp) { _sentence->finish(); _tempSprite2 = nullptr; _state = _nextState; _nextState = STATE_READY; } else { _tempSprite2 = getTalkStance(_sentence->getNextStance()); if (_tempSprite2) { _tempSprite2->reset(); _currentSprite = _tempSprite2; ((AdGame *)_gameRef)->addSentence(_sentence); } } } else { _currentSprite = _tempSprite2; ((AdGame *)_gameRef)->addSentence(_sentence); } } break; ////////////////////////////////////////////////////////////////////////// case STATE_READY: if (!_animSprite && !_animSprite2) { if (_sprite) { _currentSprite = _sprite; } else { if (_standSprite) { _currentSprite = _standSprite->getSprite(_dir); } else { AdSpriteSet *anim = getAnimByName(_idleAnimName); if (anim) { _currentSprite = anim->getSprite(_dir); } } } } break; default: error("AdActor::Update - Unhandled enum"); } if (_currentSprite && !already_moved) { _currentSprite->getCurrentFrame(_zoomable ? ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) : 100, _zoomable ? ((AdGame *)_gameRef)->_scene->getZoomAt(_posX, _posY) : 100); if (_currentSprite->isChanged()) { _posX += _currentSprite->_moveX; _posY += _currentSprite->_moveY; afterMove(); } } //_gameRef->QuickMessageForm("%s", _currentSprite->_filename); updateBlockRegion(); _ready = (_state == STATE_READY); updatePartEmitter(); updateSpriteAttachments(); return STATUS_OK; }
bool CCPathFinderNetwork::followPath(CCCollideable *objectToPath, Path &path, const int currentDirection, const float currentDistance, NodesList<const PathNode, 50> &previousNodes, const PathNode *fromNode, const PathNode *toNode) { // Node found if( fromNode == toNode ) { path.endDirection = currentDirection; path.distance = currentDistance; return true; } const int nextDirection = currentDirection+1; if( nextDirection >= 50 ) { // Give up return false; } pathFromNode = fromNode; const CCList<PathNode::PathConnection> &connections = fromNode->connections; int *values = new int[connections.length]; for( int i=0; i<connections.length; ++i ) { values[i] = i; } qsort( values, connections.length, sizeof( int ), compare ); for( int i=0; i<connections.length; ++i ) { const PathNode::PathConnection *nextConnection = connections.list[values[i]]; const PathNode *targetNode = nextConnection->node; // Previously followed? if( previousNodes.find( targetNode ) != -1 ) { continue; } CCCollideable *collidedWith = CCOctreeMovementCollisionCheck( objectToPath, fromNode->point, targetNode->point ); if( collidedWith != NULL ) { continue; } const float pathDistance = currentDistance + nextConnection->distance; if( previousNodes.add( targetNode ) == false ) { delete[] values; return false; } if( followPath( objectToPath, path, nextDirection, pathDistance, previousNodes, targetNode, toNode ) ) { path.directions[currentDirection] = values[i]; delete[] values; return true; } } delete[] values; return false; }
void Follower::update(float _dt) { //do nothing if dead if (bIsDead) {//will add a more elaborate lose screen later gStateMachine->transitionState(STATE_LOSE); return; } Pawn::update(_dt); mLastPathFound += _dt; static float aiCheck = 0.0f; aiCheck += _dt; if (aiCheck >= RUN_AI)//only run the AI every so many frames //inside this conditional you should use aiCheck where you'd normally use _dt { float distanceToPlayerSq; bIsMoving = true; switch (mState) { case PSTATE_PURSUE: distanceToPlayerSq = D3DXVec3LengthSq(&(gPlayer->getPosition() - mPosition)); if (distanceToPlayerSq > FOLLOW_DISTANCE_SQ) { if (!followPath() || mLastPathFound > MIN_PATH_TIME) setPathPlayer(); } else if (distanceToPlayerSq > FOLLOW_DISTANCE_STOP_SQ) { mVelocity = gPlayer->getPosition() - mPosition; D3DXVec3Normalize(&mVelocity, &mVelocity);//normalize to 1 unit length vector mVelocity *= mSpeed;//multiply by speed } else { stop(); bIsMoving = false; } break; case PSTATE_AFRAID: //how long has it been afraid mAfraidTime += _dt; if (mAfraidTime >= mAfraidMax) {//don't let the follower be afraid indefinitely, else the task of getting them //to the goal might become impossible bAfraid = false; mAfraidTime = 0.0f; mState = PSTATE_PURSUE; break; } //if no longer afraid if (!bAfraid) { mState = PSTATE_PURSUE; break; } else//flee randomly in panic { if (mLastPathFound >= MIN_PATH_TIME || !followPath(1.0f)) { setPathFlee(); } //gSound->getSystem()->playSound(NULL, followerCry, false, 0); } break; } mPosition += (mVelocity * aiCheck);//set position based on speed detectCollision();//let the player push the follower, but not into walls pointForward(aiCheck);//set rotation based on direction mMesh->setPosRot(mPosition, mRotation);//set position and rotation of mesh aiCheck = 0.0f; } }
void Enemy::update(float _dt) { if (bIsDead) { gSound->getSystem()->playSound(FMOD_CHANNEL_FREE, enemyDeath, false, NULL); return; } Pawn::update(_dt); //if it has seen the player/follower, decrease its point value over time if (bSeenPlayer && mPoints > mMinPoints) { mPoints -= (mPointDrain * _dt); mPoints = max(mMinPoints, mPoints);//if it dropped below min value, push it back up } mLastPathFound += _dt;//when last path was found mAttackTime += _dt;//when last attack was made mLoseSightPlayer += _dt; mLoseSightFollower += _dt; D3DXVECTOR3 targetPosition; /* static float aiCheck = 0.0f; aiCheck += _dt; if (aiCheck >= RUN_AI)//only run the AI every so many frames*/ //inside this conditional you should use aiCheck where you'd normally use _dt { switch (mState) { case PSTATE_WANDER: //if they have recently seen player/follower or see them now if (mLoseSightPlayer < LOSE_SIGHT || mLoseSightFollower < LOSE_SIGHT || noticeFollower() || noticePlayer()) { if (bAfraid)//if afraid, run { mState = PSTATE_AFRAID; break; } else { chooseTarget(); mState = PSTATE_PURSUE; gSound->getSystem()->playSound(FMOD_CHANNEL_FREE, enemyAttack, false, 0); break; } } else //if they can't see the player, just wander //unless low on health, in which case seek a heal spot { if (mHealth == mHealthMax) { if (!followPath(0.75f) && mLastPathFound > MIN_PATH_TIME) { setPathRandom(); break; } } else { mState = PSTATE_INJURED; bHealing = false; gSound->getSystem()->playSound(FMOD_CHANNEL_FREE, enemyGetHit, false, 0); break; } } break; case PSTATE_PURSUE: //if they no longer see the target, go back to wandering state // if pursuing player and doesn't see player and hasn't seen them for a while if ((bPursuingPlayer && !noticePlayer() && mLoseSightPlayer >= LOSE_SIGHT) || //if pursuing follower and doesn't see them and hasn't seen them for a while (!bPursuingPlayer && !noticeFollower() && mLoseSightFollower >= LOSE_SIGHT)) { mState = PSTATE_WANDER; break; } //if can see their target, but is afraid if (bAfraid) { mState = PSTATE_AFRAID; break; } //otherwise they can see and aren't afraid //stop if they are too close to the target, otherwise try to get closer if (bPursuingPlayer) targetPosition = gPlayer->getPosition(); else targetPosition = gFollower->getPosition(); if ((D3DXVec3LengthSq(&(mPosition - targetPosition))) <= mClosestDistanceSq) { mVelocity = D3DXVECTOR3(0.0f, 0.0f, 0.0f); } else { if (mLastPathFound >= MIN_PATH_TIME || !followPath(1.0f)) { if (bPursuingPlayer) setPathPlayer(); else setPathFollower(); } } //attack if it can if (mAttackTime > mAttackDelay) { if (bPursuingPlayer) { if (bAttackPlayer) { attack(gPlayer->getPosition()); mAttackTime = 0.0f; gSound->getSystem()->playSound(FMOD_CHANNEL_FREE, enemyAttack, false, 0); } } else { if (bAttackFollower) { attack(gFollower->getPosition()); mAttackTime = 0.0f; gSound->getSystem()->playSound(FMOD_CHANNEL_FREE, enemyAttack, false, 0); } } } break; case PSTATE_AFRAID: //if they reached good health again, they are no longer afraid //the add health function will take away fear state when they reach proper hp if (!bAfraid) { mState = PSTATE_WANDER; break; } //if they no longer see the target, go back to wandering state // if pursuing player and doesn't see player and hasn't seen them for a while if ((bPursuingPlayer && !noticePlayer() && mLoseSightPlayer >= LOSE_SIGHT) || //if pursuing follower and doesn't see them and hasn't seen them for a while (!bPursuingPlayer && !noticeFollower() && mLoseSightFollower >= LOSE_SIGHT)) { mState = PSTATE_INJURED; break; } if (mLastPathFound >= MIN_PATH_TIME || !followPath(1.0f)) { setPathFlee(); } //still attack if they are close enough if (mAttackTime >= mAttackDelay) { if (bPursuingPlayer) { if (bAttackPlayer) { attack(gPlayer->getPosition()); mAttackTime = 0.0f; gSound->getSystem()->playSound(FMOD_CHANNEL_FREE, enemyAttack, false, 0); } } else { if (bAttackFollower) { attack(gFollower->getPosition()); mAttackTime = 0.0f; gSound->getSystem()->playSound(FMOD_CHANNEL_FREE, enemyAttack, false, 0); } } } break; case PSTATE_INJURED://enemy is injured and cannot presently see player/wanderer //if they have recently seen player/follower or see them now if (mLoseSightPlayer < LOSE_SIGHT || mLoseSightFollower < LOSE_SIGHT || noticeFollower() || noticePlayer()) { //if they are afraid, flee. If not, pursue if (bAfraid) { mState = PSTATE_AFRAID; break; } else { chooseTarget(); mState = PSTATE_PURSUE; gSound->getSystem()->playSound(FMOD_CHANNEL_FREE,enemyAttack, false, 0); break; } } else//if they don't see the player or follower, find a healing spot to recover { if (mHealth == mHealthMax) {//when fully healed, go back to wandering mState = PSTATE_WANDER; break; } if (bHealing) { stop(); if (mHealth == mHealthMax) { bHealing = false; mState = PSTATE_WANDER; break; } } else { if (mLastPathFound >= MIN_PATH_TIME || !followPath(1.0f)) { setPathHealing(); } } } break; } //rotate to the direction you're going pointForward(_dt); //update position mPosition += mVelocity * _dt; detectCollision(); mMesh->setPosRot(mPosition, mRotation); } }
void followPath(FILE*out, Graph G, int c){ if (c != 0){ followPath(out, G, G->vertex[c].parent); fprintf(out, "%s ", G->vertex[c].id); } }
/** * CAIStatePathFollow::update * @date Modified April 18, 2006 */ void CAIStatePathFollow::update(CAIEntity* poAIEntity, CCharacter* poCharacter) { followPath(poAIEntity, poCharacter, 10.0f); }
void myfunc() { int num_rows,k, l; double orient,delta_orient,rot_speed,t_rot,t_trans; double x0,y0,x,y,dx,dy; float distance,distance1,lala; double PI=3.14159265; x0=0; y0=0; double orient0; orient0=0; // starting conditions still have to be properly intialized double D = 0.094; /*distance between wheels, has to be measured*/ char ch; const float tol = 1.0e-7; // 7 significant figures float xold, xnew; // local variables int test; /*Read in coords, mat[d][0] contains x-coords, mat[d][1] contains y-coords*/ int i=0,j=0; double mat[100][2]; double z; // UInt32* pathx; // UInt32* pathy; // Here we should store the path-coordinates // // while((line=fgets(buffer,sizeof(buffer),fp))!=NULL) // { // // record = strtok(line,","); /*break up string, return first token */ // while(record != NULL) // { // printf("record : %s \n",record); //here you can put the record into the array as per your requirement. // mat[i][j++] = atof(record) ; /*Convert string to double, put in [i,j] then j+1*/ // record = strtok(NULL,","); // } // ++i ; // j=0; // } initRTC(); camera_reset(160); init_uart1(57600); while(1){ if(getsignal()){ ch = getch(); printf("Character on serial %c 1\r\n", ch ); if(ch == 75) {return;} else{ switch (ch) { case '1': /*Read in csv-file, mat[d][0] contains distance in m, mat[d][1] contains delta_orientation in degrees */ mat[0][0]=0.61; mat[0][1]=0; mat[1][0]=0.58; mat[1][1]=90; mat[2][0]=1.00; mat[2][1]=-45; mat[3][0]=0.33; mat[3][1]=-60; num_rows = 4; // to be determined depends on how weread in givens k=0; while(k<=num_rows-1) { distance=mat[k][0]; delta_orient=mat[k][1]; if(delta_orient>0){ t_rot=1000*(0.010*delta_orient+0.003); } else{ if(delta_orient<0){ t_rot=1000*(-0.010*delta_orient+0.003); } else t_rot=0; } t_trans=1000*(4.8*distance+0.05); printf("tekst 2 distance: %lf,delta_orient:%lf \n t_rot: %lf t_trans: %lf \n\n",distance*1000,delta_orient,t_rot,t_trans); if (delta_orient>0){ sendReceive(203,22,202,20);//turn counterclockwise delay(t_rot); sendReceive(201,0,202,0);//stop } if(delta_orient<0){ sendReceive(201, 22, 204, 20);//turn clockwise delay(t_rot); sendReceive(201,0,202,0);//stop } sendReceive(201, 23, 202, 20);//drive forward delay(t_trans); sendReceive(201, 0, 202, 0);//stop printf("k: %d",k); k++; } break; case '5': /* Drive forward */ sendReceive(201, 23, 202, 20); /* 201: Right motor moves forward 202: Left motor moves forward Forward= opposite the antenna */ break; case '6': /* Stop */ sendReceive(201, 0, 202, 0); break; case '7': sendReceive(203, 22, 204, 20); /* 203: Right motor moves backward 204: Left motor moves backward Backward= antenna - side */ break; case '8': /* Rotate left (counter clockwise) */ sendReceive(203, 22, 202, 20); /* Rotate: left motor rotates backward; right one forward */ break; case '9': /* Rotate right (clockwise) */ sendReceive(201,22,204,20); /* Rotate: left motor rotates forward; right one backward */ break; case 'a': printf("Reading path"); l = readNumber(); printf("l = ",l); followPath(l); break; } } } } //end while } //end myfunc
void Gist::addActions() { /// Expand current node auto expand_action = new QAction("Expand", this); expand_action->setShortcut(QKeySequence("Return")); addAction(expand_action); connect(expand_action, SIGNAL(triggered()), m_Canvas, SLOT(expandCurrentNode())); reset = new QAction("Reset", this); addAction(reset); connect(reset, SIGNAL(triggered()), m_Canvas, SLOT(reset())); // reset->setShortcut(QKeySequence("Ctrl+R")); showPixelTree = new QAction("Pixel Tree View", this); addAction(showPixelTree); connect(showPixelTree, SIGNAL(triggered()), m_Canvas, SLOT(showPixelTree())); showIcicleTree = new QAction("Icicle Tree View", this); addAction(showIcicleTree); connect(showIcicleTree, SIGNAL(triggered()), m_Canvas, SLOT(showIcicleTree())); showWebscript = new QAction("Webscript View", this); addAction(showWebscript); connect(showWebscript, SIGNAL(triggered()), m_Canvas, SLOT(showWebscript())); followPath = new QAction("Follow Path", this); addAction(followPath); connect(followPath, SIGNAL(triggered()), m_Canvas, SLOT(followPath())); /// Collect ML stats auto collectMLStats_action = new QAction("Collect ML stats", this); addAction(collectMLStats_action); connect(collectMLStats_action, SIGNAL(triggered()), m_Canvas, SLOT(collectMLStats())); deleteWhiteNodes = new QAction{"Delete Unexplored Nodes", this}; addAction(deleteWhiteNodes); connect(deleteWhiteNodes, &QAction::triggered, m_Canvas, &TreeCanvas::deleteWhiteNodes); navUp = new QAction("Up", this); addAction(navUp); navUp->setShortcut(QKeySequence("Up")); connect(navUp, SIGNAL(triggered()), m_Canvas, SLOT(navUp())); navDown = new QAction("Down", this); addAction(navDown); navDown->setShortcut(QKeySequence("Down")); connect(navDown, SIGNAL(triggered()), m_Canvas, SLOT(navDown())); navLeft = new QAction("Left", this); addAction(navLeft); navLeft->setShortcut(QKeySequence("Left")); connect(navLeft, SIGNAL(triggered()), m_Canvas, SLOT(navLeft())); navRight = new QAction("Right", this); addAction(navRight); navRight->setShortcut(QKeySequence("Right")); connect(navRight, SIGNAL(triggered()), m_Canvas, SLOT(navRight())); navRoot = new QAction("Root", this); addAction(navRoot); navRoot->setShortcut(QKeySequence("R")); connect(navRoot, SIGNAL(triggered()), m_Canvas, SLOT(navRoot())); navNextSol = new QAction("To next solution", this); addAction(navNextSol); navNextSol->setShortcut(QKeySequence("Shift+Right")); connect(navNextSol, SIGNAL(triggered()), m_Canvas, SLOT(navNextSol())); navPrevSol = new QAction("To previous solution", this); addAction(navPrevSol); navPrevSol->setShortcut(QKeySequence("Shift+Left")); connect(navPrevSol, SIGNAL(triggered()), m_Canvas, SLOT(navPrevSol())); navNextLeaf = new QAction("To next leaf", this); addAction(navNextLeaf); navNextLeaf->setShortcut(QKeySequence("Ctrl+Right")); connect(navNextLeaf, SIGNAL(triggered()), m_Canvas, SLOT(navNextLeaf())); navPrevLeaf = new QAction("To previous leaf", this); addAction(navPrevLeaf); navPrevLeaf->setShortcut(QKeySequence("Ctrl+Left")); connect(navPrevLeaf, SIGNAL(triggered()), m_Canvas, SLOT(navPrevLeaf())); searchNext = new QAction("Next solution", this); addAction(searchNext); searchNext->setShortcut(QKeySequence("N")); searchAll = new QAction("All solutions", this); addAction(searchAll); searchAll->setShortcut(QKeySequence("A")); toggleHidden = new QAction("Hide/unhide", this); addAction(toggleHidden); toggleHidden->setShortcut(QKeySequence("H")); connect(toggleHidden, SIGNAL(triggered()), m_Canvas, SLOT(toggleHidden())); hideFailed = new QAction("Hide failed subtrees", this); addAction(hideFailed); hideFailed->setShortcut(QKeySequence("F")); connect(hideFailed, SIGNAL(triggered()), m_Canvas, SLOT(hideFailed())); hideSize = new QAction("Hide small subtrees", this); addAction(hideSize); connect(hideSize, SIGNAL(triggered()), m_Canvas, SLOT(hideSize())); #ifdef MAXIM_DEBUG auto printDebugInfo = new QAction("Print Debug Info", this); printDebugInfo->setShortcut(QKeySequence("Ctrl+Shift+D")); connect(printDebugInfo, &QAction::triggered, m_Canvas, &TreeCanvas::printDebugInfo); addAction(printDebugInfo); auto updateCanvas = new QAction{"Update Canvas", this}; updateCanvas->setShortcut(QKeySequence("Shift+U")); connect(updateCanvas, &QAction::triggered, [this]() { qDebug() << "action: update canvas"; m_Canvas->update(); }); addAction(updateCanvas); auto addChildren = new QAction{"Add 2 Children", this}; addChildren->setShortcut(QKeySequence("Shift+C")); connect(addChildren, &QAction::triggered, m_Canvas, &TreeCanvas::addChildren); addAction(addChildren); deleteNode = new QAction{"Delete Node", this}; deleteNode->setShortcut(QKeySequence("del")); connect(deleteNode, &QAction::triggered, m_Canvas, &TreeCanvas::deleteSelectedNode); addAction(deleteNode); dirtyUpNode = new QAction{"Dirty Up Node", this}; dirtyUpNode->setShortcut(QKeySequence("D")); connect(dirtyUpNode, &QAction::triggered, m_Canvas, &TreeCanvas::dirtyUpNode); addAction(dirtyUpNode); #endif unhideAll = new QAction("Unhide all", this); addAction(unhideAll); unhideAll->setShortcut(QKeySequence("U")); connect(unhideAll, SIGNAL(triggered()), m_Canvas, SLOT(unhideAll())); labelBranches = new QAction("Label/clear branches", this); addAction(labelBranches); labelBranches->setShortcut(QKeySequence("L")); /// TODO(maxim): should this be the default (Qt::WindowShortcut) instead? labelBranches->setShortcutContext(Qt::WidgetWithChildrenShortcut); connect(labelBranches, SIGNAL(triggered()), m_Canvas, SLOT(labelBranches())); labelPath = new QAction("Label/clear path", this); addAction(labelPath); labelPath->setShortcut(QKeySequence("Shift+L")); connect(labelPath, SIGNAL(triggered()), m_Canvas, SLOT(labelPath())); // labelPath->setShortcutContext(Qt::ApplicationShortcut); analyzeSimilarSubtrees = new QAction("Symilar Subtree Analysis", this); addAction(analyzeSimilarSubtrees); analyzeSimilarSubtrees->setShortcut(QKeySequence("Shift+s")); connect(analyzeSimilarSubtrees, SIGNAL(triggered()), m_Canvas, SLOT(analyzeSimilarSubtrees())); highlightNodesMenu = new QAction("Highlight Nodes Based On ...", this); addAction(highlightNodesMenu); connect(highlightNodesMenu, SIGNAL(triggered()), m_Canvas, SLOT(highlightNodesMenu())); showNogoods = new QAction("Show no-goods", this); addAction(showNogoods); showNogoods->setShortcut(QKeySequence("Shift+N")); connect(showNogoods, SIGNAL(triggered()), m_Canvas, SLOT(showNogoods())); showNodeInfo = new QAction("Show node info", this); addAction(showNodeInfo); showNodeInfo->setShortcut(QKeySequence("I")); connect(showNodeInfo, SIGNAL(triggered()), m_Canvas, SLOT(showNodeInfo())); showNodeOnPixelTree = new QAction("Show node on a pixel tree", this); addAction(showNodeOnPixelTree); showNodeOnPixelTree->setShortcut(QKeySequence("J")); connect(showNodeOnPixelTree, SIGNAL(triggered()), m_Canvas, SLOT(showNodeOnPixelTree())); toggleStop = new QAction("Stop/unstop", this); addAction(toggleStop); toggleStop->setShortcut(QKeySequence("X")); connect(toggleStop, SIGNAL(triggered()), m_Canvas, SLOT(toggleStop())); unstopAll = new QAction("Do not stop in subtree", this); addAction(unstopAll); unstopAll->setShortcut(QKeySequence("Shift+X")); connect(unstopAll, SIGNAL(triggered()), m_Canvas, SLOT(unstopAll())); zoomToFit = new QAction("Zoom to fit", this); addAction(zoomToFit); zoomToFit->setShortcut(QKeySequence("Z")); connect(zoomToFit, SIGNAL(triggered()), m_Canvas, SLOT(zoomToFit())); center = new QAction("Center current node", this); addAction(center); center->setShortcut(QKeySequence("C")); connect(center, SIGNAL(triggered()), m_Canvas, SLOT(centerCurrentNode())); exportPDF = new QAction("Export subtree PDF...", this); addAction(exportPDF); exportPDF->setShortcut(QKeySequence("P")); connect(exportPDF, SIGNAL(triggered()), m_Canvas, SLOT(exportPDF())); exportWholeTreePDF = new QAction("Export PDF...", this); addAction(exportWholeTreePDF); exportWholeTreePDF->setShortcut(QKeySequence("Ctrl+Shift+P")); connect(exportWholeTreePDF, SIGNAL(triggered()), m_Canvas, SLOT(exportWholeTreePDF())); print = new QAction("Print...", this); addAction(print); print->setShortcut(QKeySequence("Ctrl+P")); connect(print, SIGNAL(triggered()), m_Canvas, SLOT(print())); printSearchLog = new QAction("Export search log...", this); addAction(printSearchLog); connect(printSearchLog, SIGNAL(triggered()), m_Canvas, SLOT(printSearchLog())); bookmarkNode = new QAction("Add/remove bookmark", this); bookmarkNode->setShortcut(QKeySequence("Shift+B")); connect(bookmarkNode, SIGNAL(triggered()), m_Canvas, SLOT(bookmarkNode())); nullBookmark = new QAction("<none>",this); nullBookmark->setCheckable(true); nullBookmark->setChecked(false); nullBookmark->setEnabled(false); bookmarksGroup = new QActionGroup(this); bookmarksGroup->setExclusive(false); bookmarksGroup->addAction(nullBookmark); connect(bookmarksGroup, SIGNAL(triggered(QAction*)), this, SLOT(selectBookmark(QAction*))); bookmarksMenu = new QMenu("Bookmarks", this); connect(bookmarksMenu, SIGNAL(aboutToShow()), this, SLOT(populateBookmarksMenu())); showNodeStats = new QAction("Node statistics", this); addAction(showNodeStats); showNodeStats->setShortcut(QKeySequence("S")); connect(showNodeStats, SIGNAL(triggered()), this, SLOT(showStats())); nullComparator = new QAction("<none>",this); nullComparator->setCheckable(true); nullComparator->setChecked(false); nullComparator->setEnabled(false); comparatorGroup = new QActionGroup(this); comparatorGroup->setExclusive(false); comparatorGroup->addAction(nullComparator); // connect(comparatorGroup, SIGNAL(triggered(QAction*)), // this, SLOT(selectComparator(QAction*))); comparatorMenu = new QMenu("Comparators", this); comparatorMenu->addActions(comparatorGroup->actions()); contextMenu = new QMenu(this); contextMenu->addAction(collectMLStats_action); contextMenu->addAction(showNodeStats); contextMenu->addAction(center); contextMenu->addSeparator(); contextMenu->addAction(searchNext); contextMenu->addAction(searchAll); contextMenu->addSeparator(); contextMenu->addAction(toggleHidden); contextMenu->addAction(hideFailed); contextMenu->addAction(hideSize); contextMenu->addAction(unhideAll); contextMenu->addAction(labelBranches); contextMenu->addAction(labelPath); contextMenu->addAction(showNogoods); contextMenu->addAction(showNodeInfo); contextMenu->addAction(showNodeOnPixelTree); contextMenu->addAction(toggleStop); contextMenu->addAction(unstopAll); contextMenu->addSeparator(); contextMenu->addMenu(bookmarksMenu); contextMenu->addSeparator(); #ifdef MAXIM_DEBUG contextMenu->addAction(deleteNode); contextMenu->addAction(dirtyUpNode); #endif }