// This file was GENERATED by command:
//     pump.py genericslot.h.pump
// DO NOT EDIT BY HAND!!!

/*
 *  Copyright 2014 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef WEBRTC_BASE_GENERICSLOT_H_
#define WEBRTC_BASE_GENERICSLOT_H_

// To generate genericslot.h from genericslot.h.pump, execute:
// /home/build/google3/third_party/gtest/scripts/pump.py genericslot.h.pump

// Generic-slots are pure slots that can be hooked up to signals. They're
// mainly intended to be used in tests where we want to check if a signal
// was invoked and what arguments were passed. NOTE: They do not do any
// lifetime management of the arguments received via callbacks.
//
// Example:
//   /* Some signal */
//   sigslot::signal1<int> foo;
//
//   /* We want to monitor foo in some test */
//   rtc::GenericSlot1<int> slot(&foo, 0);
//   foo.emit(5);
//   EXPECT_TRUE(slot.callback_received());
//   EXPECT_EQ(5, *(slot.arg1()));
//

#include "webrtc/base/constructormagic.h"
#include "webrtc/base/sigslot.h"

namespace rtc {

template <class A1>
class GenericSlot1 : public sigslot::has_slots<> {
 public:
  GenericSlot1(sigslot::signal1<A1>* signal,
                const A1& arg1_initial)
      : arg1_initial_(arg1_initial) {
    Reset();
    signal->connect(this, &GenericSlot1::OnSignalCallback);
  }

  void Reset() {
    callback_received_ = false;
    arg1_ = arg1_initial_;
  }

  bool callback_received() const { return callback_received_; }
  const A1& arg1() const { return arg1_; }

 private:
  void OnSignalCallback(A1 arg1) {
    callback_received_ = true;
    arg1_ = arg1;
  }

  bool callback_received_;
  A1 arg1_initial_, arg1_;

  DISALLOW_COPY_AND_ASSIGN(GenericSlot1);
};

template <class A1, class A2>
class GenericSlot2 : public sigslot::has_slots<> {
 public:
  GenericSlot2(sigslot::signal2<A1, A2>* signal,
                const A1& arg1_initial, const A2& arg2_initial)
      : arg1_initial_(arg1_initial), arg2_initial_(arg2_initial) {
    Reset();
    signal->connect(this, &GenericSlot2::OnSignalCallback);
  }

  void Reset() {
    callback_received_ = false;
    arg1_ = arg1_initial_;
    arg2_ = arg2_initial_;
  }

  bool callback_received() const { return callback_received_; }
  const A1& arg1() const { return arg1_; }
  const A2& arg2() const { return arg2_; }

 private:
  void OnSignalCallback(A1 arg1, A2 arg2) {
    callback_received_ = true;
    arg1_ = arg1;
    arg2_ = arg2;
  }

  bool callback_received_;
  A1 arg1_initial_, arg1_;
  A2 arg2_initial_, arg2_;

  DISALLOW_COPY_AND_ASSIGN(GenericSlot2);
};

template <class A1, class A2, class A3>
class GenericSlot3 : public sigslot::has_slots<> {
 public:
  GenericSlot3(sigslot::signal3<A1, A2, A3>* signal,
                const A1& arg1_initial, const A2& arg2_initial,
                    const A3& arg3_initial)
      : arg1_initial_(arg1_initial), arg2_initial_(arg2_initial),
          arg3_initial_(arg3_initial) {
    Reset();
    signal->connect(this, &GenericSlot3::OnSignalCallback);
  }

  void Reset() {
    callback_received_ = false;
    arg1_ = arg1_initial_;
    arg2_ = arg2_initial_;
    arg3_ = arg3_initial_;
  }

  bool callback_received() const { return callback_received_; }
  const A1& arg1() const { return arg1_; }
  const A2& arg2() const { return arg2_; }
  const A3& arg3() const { return arg3_; }

 private:
  void OnSignalCallback(A1 arg1, A2 arg2, A3 arg3) {
    callback_received_ = true;
    arg1_ = arg1;
    arg2_ = arg2;
    arg3_ = arg3;
  }

  bool callback_received_;
  A1 arg1_initial_, arg1_;
  A2 arg2_initial_, arg2_;
  A3 arg3_initial_, arg3_;

  DISALLOW_COPY_AND_ASSIGN(GenericSlot3);
};

template <class A1, class A2, class A3, class A4>
class GenericSlot4 : public sigslot::has_slots<> {
 public:
  GenericSlot4(sigslot::signal4<A1, A2, A3, A4>* signal,
                const A1& arg1_initial, const A2& arg2_initial,
                    const A3& arg3_initial, const A4& arg4_initial)
      : arg1_initial_(arg1_initial), arg2_initial_(arg2_initial),
          arg3_initial_(arg3_initial), arg4_initial_(arg4_initial) {
    Reset();
    signal->connect(this, &GenericSlot4::OnSignalCallback);
  }

  void Reset() {
    callback_received_ = false;
    arg1_ = arg1_initial_;
    arg2_ = arg2_initial_;
    arg3_ = arg3_initial_;
    arg4_ = arg4_initial_;
  }

  bool callback_received() const { return callback_received_; }
  const A1& arg1() const { return arg1_; }
  const A2& arg2() const { return arg2_; }
  const A3& arg3() const { return arg3_; }
  const A4& arg4() const { return arg4_; }

 private:
  void OnSignalCallback(A1 arg1, A2 arg2, A3 arg3, A4 arg4) {
    callback_received_ = true;
    arg1_ = arg1;
    arg2_ = arg2;
    arg3_ = arg3;
    arg4_ = arg4;
  }

  bool callback_received_;
  A1 arg1_initial_, arg1_;
  A2 arg2_initial_, arg2_;
  A3 arg3_initial_, arg3_;
  A4 arg4_initial_, arg4_;

  DISALLOW_COPY_AND_ASSIGN(GenericSlot4);
};

template <class A1, class A2, class A3, class A4, class A5>
class GenericSlot5 : public sigslot::has_slots<> {
 public:
  GenericSlot5(sigslot::signal5<A1, A2, A3, A4, A5>* signal,
                const A1& arg1_initial, const A2& arg2_initial,
                    const A3& arg3_initial, const A4& arg4_initial,
                    const A5& arg5_initial)
      : arg1_initial_(arg1_initial), arg2_initial_(arg2_initial),
          arg3_initial_(arg3_initial), arg4_initial_(arg4_initial),
          arg5_initial_(arg5_initial) {
    Reset();
    signal->connect(this, &GenericSlot5::OnSignalCallback);
  }

  void Reset() {
    callback_received_ = false;
    arg1_ = arg1_initial_;
    arg2_ = arg2_initial_;
    arg3_ = arg3_initial_;
    arg4_ = arg4_initial_;
    arg5_ = arg5_initial_;
  }

  bool callback_received() const { return callback_received_; }
  const A1& arg1() const { return arg1_; }
  const A2& arg2() const { return arg2_; }
  const A3& arg3() const { return arg3_; }
  const A4& arg4() const { return arg4_; }
  const A5& arg5() const { return arg5_; }

 private:
  void OnSignalCallback(A1 arg1, A2 arg2, A3 arg3, A4 arg4, A5 arg5) {
    callback_received_ = true;
    arg1_ = arg1;
    arg2_ = arg2;
    arg3_ = arg3;
    arg4_ = arg4;
    arg5_ = arg5;
  }

  bool callback_received_;
  A1 arg1_initial_, arg1_;
  A2 arg2_initial_, arg2_;
  A3 arg3_initial_, arg3_;
  A4 arg4_initial_, arg4_;
  A5 arg5_initial_, arg5_;

  DISALLOW_COPY_AND_ASSIGN(GenericSlot5);
};
}  // namespace rtc

#endif  // WEBRTC_BASE_GENERICSLOT_H_
