Program Listing for File Negotiator.hpp

Return to documentation for file (include/rmf_traffic/schedule/Negotiator.hpp)

/*
 * Copyright (C) 2020 Open Source Robotics Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
*/

#ifndef RMF_TRAFFIC__SCHEDULE__NEGOTIATOR_HPP
#define RMF_TRAFFIC__SCHEDULE__NEGOTIATOR_HPP

#include <rmf_traffic/schedule/Negotiation.hpp>

namespace rmf_traffic {
namespace schedule {

//==============================================================================
class Negotiator
{
public:

  using TableViewerPtr = Negotiation::Table::ViewerPtr;

  class Responder
  {
  public:

    using ParticipantId = rmf_traffic::schedule::ParticipantId;
    using ItineraryVersion = rmf_traffic::schedule::ItineraryVersion;
    using UpdateVersion = rmf_utils::optional<ItineraryVersion>;
    using ApprovalCallback = std::function<UpdateVersion()>;
    using Alternatives = Negotiation::Alternatives;

    virtual void submit(
      PlanId plan_id,
      std::vector<Route> itinerary,
      ApprovalCallback approval_callback = nullptr) const = 0;

    virtual void reject(const Alternatives& alternatives) const = 0;

    virtual void forfeit(const std::vector<ParticipantId>& blockers) const = 0;

    // Virtual destructor
    virtual ~Responder() = default;
  };

  using ResponderPtr = std::shared_ptr<const Responder>;

  virtual void respond(
    const TableViewerPtr& table_viewer,
    const ResponderPtr& responder) = 0;

  virtual ~Negotiator() = default;
};

//==============================================================================
class SimpleResponder : public Negotiator::Responder
{
public:

  using ApprovalMap =
    std::unordered_map<
    Negotiation::ConstTablePtr,
    std::function<UpdateVersion()>
    >;

  using BlockerSet = std::unordered_set<schedule::ParticipantId>;

  SimpleResponder(
    const Negotiation::TablePtr& table,
    std::vector<schedule::ParticipantId>* report_blockers = nullptr);

  SimpleResponder(
    const Negotiation::TablePtr& table,
    std::shared_ptr<ApprovalMap> approval_map,
    std::shared_ptr<BlockerSet> blockers);

  template<typename... Args>
  static std::shared_ptr<SimpleResponder> make(Args&& ... args)
  {
    return std::make_shared<SimpleResponder>(std::forward<Args>(args)...);
  }

  // Documentation inherited
  // NOTE: approval_callback does not get used
  void submit(
    PlanId plan_id,
    std::vector<Route> itinerary,
    std::function<UpdateVersion()> approval_callback = nullptr) const final;

  // Documentation inherited
  void reject(
    const Negotiation::Alternatives& alternatives) const final;

  // Documentation inherited
  void forfeit(const std::vector<ParticipantId>& blockers) const final;

  const std::vector<ParticipantId>& blockers() const;

  class Implementation;
private:
  rmf_utils::impl_ptr<Implementation> _pimpl;
};

} // namespace schedule
} // namespace rmf_traffic

#endif // RMF_TRAFFIC__SCHEDULE__NEGOTIATOR_HPP