Skip to content
Snippets Groups Projects
Action.cpp 3.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include "Action.hpp"
    
    Action::Action(Action::Type type, std::function<void(Config & config, Action & action)> apply, std::function<void(Config & config, Action & action)> undo, std::function<bool(Config & config, Action & action)> appliable)
    {
      this->type = type;
      this->apply = apply;
      this->undo = undo;
      this->appliable = appliable;
    }
    
    Action Action::addLinesIfNeeded(int nbLines)
    {
      auto apply = [nbLines](Config & config, Action &)
      {
        config.addLines(1);
      };
    
      auto undo = [](Config &, Action &)
      {
      };
    
      auto appliable = [](Config &, Action &)
      {
        return true;
      };
    
      return {Type::AddLines, apply, undo, appliable};
    }
    
    Action Action::moveWordIndex(int movement)
    {
      auto apply = [movement](Config & config, Action &)
      {
        config.moveWordIndex(movement);
      };
    
      auto undo = [movement](Config & config, Action &)
      {
        config.moveWordIndex(movement);
      };
    
      auto appliable = [movement](Config & config, Action &)
      {
        bool possible = config.moveWordIndex(movement);
        if (possible)
          moveWordIndex(-movement);
        return possible;
      };
    
      return {Type::MoveWord, apply, undo, appliable};
    }
    
    Action Action::moveCharacterIndex(int movement)
    {
      auto apply = [movement](Config & config, Action &)
      {
        config.moveCharacterIndex(movement);
      };
    
      auto undo = [movement](Config & config, Action &)
      {
        config.moveCharacterIndex(movement);
      };
    
      auto appliable = [movement](Config & config, Action &)
      {
        bool possible = config.moveCharacterIndex(movement);
        if (possible)
          moveCharacterIndex(-movement);
        return possible;
      };
    
      return {Type::MoveChar, apply, undo, appliable};
    }
    
    
    Action Action::addHypothesis(const std::string & colName, std::size_t lineIndex, const std::string & hypothesis)
    {
      auto apply = [colName, lineIndex, hypothesis](Config & config, Action &)
      {
        config.getFirstEmpty(colName, lineIndex) = hypothesis;
      };
    
      auto undo = [colName, lineIndex](Config & config, Action &)
      {
        config.getLastNotEmpty(colName, lineIndex) = "";
      };
    
      auto appliable = [colName, lineIndex](Config & config, Action &)
      {
        return config.has(colName, lineIndex, 0);
      };
    
      return {Type::Write, apply, undo, appliable}; 
    }
    
    Action Action::addHypothesisRelative(const std::string & colName, Object object, int relativeIndex, const std::string & hypothesis)
    {
      auto apply = [colName, object, relativeIndex, hypothesis](Config & config, Action & a)
      {
        int lineIndex = 0;
        if (object == Object::Buffer)
          lineIndex = config.getWordIndex() + relativeIndex;
        else
          lineIndex = config.getStack(relativeIndex);
    
        return addHypothesis(colName, lineIndex, "").apply(config, a);
      };
    
      auto undo = [colName, object, relativeIndex](Config & config, Action & a)
      {
        int lineIndex = 0;
        if (object == Object::Buffer)
          lineIndex = config.getWordIndex() + relativeIndex;
        else
          lineIndex = config.getStack(relativeIndex);
    
        return addHypothesis(colName, lineIndex, "").undo(config, a);
      };
    
      auto appliable = [colName, object, relativeIndex](Config & config, Action & a)
      {
        int lineIndex = 0;
        if (object == Object::Buffer)
          lineIndex = config.getWordIndex() + relativeIndex;
        else if (config.hasStack(relativeIndex))
          lineIndex = config.getStack(relativeIndex);
        else
          return false;
    
        return addHypothesis(colName, lineIndex, "").appliable(config, a);
      };
    
      return {Type::Write, apply, undo, appliable}; 
    }
    
    Action::Object Action::str2object(const std::string & s)
    {
      if (s == "b")
        return Object::Buffer;
      if (s == "s")
        return Object::Stack;
    
      util::myThrow(fmt::format("Invalid object '{}'", s));
      return Object::Buffer;
    }