Skip to content
Snippets Groups Projects
Action.cpp 3.52 KiB
Newer Older
#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(const Config & config, const 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 = [](const Config &, const 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](const Config & config, const Action &)
    return config.canMoveWordIndex(movement);
  };

  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](const Config & config, const Action &)
    return config.canMoveCharacterIndex(movement);
  };

  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](const Config & config, const 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);

Franck Dary's avatar
Franck Dary committed
    return addHypothesis(colName, lineIndex, hypothesis).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](const Config & config, const 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;
}