1// Copyright (C) 2013 Google Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// An object to store a pointer to a method in an object with the following
16// signature:
17//
18//    void Observer::ObserveEvent(bool success, Key key, Data data);
19
20#ifndef I18N_ADDRESSINPUT_CALLBACK_H_
21#define I18N_ADDRESSINPUT_CALLBACK_H_
22
23#include <cassert>
24#include <cstddef>
25
26namespace i18n {
27namespace addressinput {
28
29// Stores a pointer to a method in an object. Sample usage:
30//    class MyClass {
31//     public:
32//      typedef Callback<const MyType&, const MyDataType&> MyCallback;
33//
34//      void GetDataAsynchronously() {
35//        scoped_ptr<MyCallback> callback(BuildCallback(
36//            this, &MyClass::OnDataReady));
37//        bool success = ...
38//        MyKeyType key = ...
39//        MyDataType data = ...
40//        (*callback)(success, key, data);
41//      }
42//
43//      void OnDataReady(bool success,
44//                       const MyKeyType& key,
45//                       const MyDataType& data) {
46//        ...
47//      }
48//    };
49template <typename Key, typename Data>
50class Callback {
51 public:
52  virtual ~Callback() {}
53  virtual void operator()(bool success, Key key, Data data) const = 0;
54};
55
56namespace {
57
58template <typename Observer, typename Key, typename Data>
59class CallbackImpl : public Callback<Key, Data> {
60 public:
61  typedef void (Observer::*ObserveEvent)(bool, Key, Data);
62
63  CallbackImpl(Observer* observer, ObserveEvent observe_event)
64      : observer_(observer),
65        observe_event_(observe_event) {
66    assert(observer_ != NULL);
67    assert(observe_event_ != NULL);
68  }
69
70  virtual ~CallbackImpl() {}
71
72  virtual void operator()(bool success, Key key, Data data) const {
73    (observer_->*observe_event_)(success, key, data);
74  }
75
76 private:
77  Observer* observer_;
78  ObserveEvent observe_event_;
79};
80
81}  // namespace
82
83// Returns a callback to |observer->observe_event| method. The caller owns the
84// result.
85template <typename Observer, typename Key, typename Data>
86Callback<Key, Data>* BuildCallback(
87    Observer* observer,
88    void (Observer::*observe_event)(bool, Key, Data)) {
89  return new CallbackImpl<Observer, Key, Data>(observer, observe_event);
90}
91
92}  // namespace addressinput
93}  // namespace i18n
94
95#endif  // I18N_ADDRESSINPUT_CALLBACK_H_
96