15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_MAC_BIND_OBJC_BLOCK_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_MAC_BIND_OBJC_BLOCK_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <Block.h>
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_forward.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/mac/scoped_block.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// BindBlock builds a callback from an Objective-C block. Example usages:
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Closure closure = BindBlock(^{DoSomething();});
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Callback<int(void)> callback = BindBlock(^{return 42;});
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Callback<void(const std::string&, const std::string&)> callback =
215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//     BindBlock(^(const std::string& arg0, const std::string& arg1) {
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//         ...
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//     });
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace internal {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Helper functions to run the block contained in the parameter.
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<typename R>
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)R RunBlock(base::mac::ScopedBlock<R(^)()> block) {
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  R(^extracted_block)() = block.get();
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return extracted_block();
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<typename R, typename A1>
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)R RunBlock(base::mac::ScopedBlock<R(^)(A1)> block, A1 a) {
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  R(^extracted_block)(A1) = block.get();
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return extracted_block(a);
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template<typename R, typename A1, typename A2>
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)R RunBlock(base::mac::ScopedBlock<R(^)(A1, A2)> block, A1 a, A2 b) {
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  R(^extracted_block)(A1, A2) = block.get();
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return extracted_block(a, b);
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace internal
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Construct a callback with no argument from an objective-C block.
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<typename R>
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::Callback<R(void)> BindBlock(R(^block)()) {
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return base::Bind(&base::internal::RunBlock<R>,
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    base::mac::ScopedBlock<R(^)()>(Block_copy(block)));
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Construct a callback with one argument from an objective-C block.
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)template<typename R, typename A1>
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)base::Callback<R(A1)> BindBlock(R(^block)(A1)) {
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return base::Bind(&base::internal::RunBlock<R, A1>,
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                    base::mac::ScopedBlock<R(^)(A1)>(Block_copy(block)));
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Construct a callback with two arguments from an objective-C block.
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)template<typename R, typename A1, typename A2>
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::Callback<R(A1, A2)> BindBlock(R(^block)(A1, A2)) {
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::Bind(&base::internal::RunBlock<R, A1, A2>,
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    base::mac::ScopedBlock<R(^)(A1, A2)>(Block_copy(block)));
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // BASE_MAC_BIND_OBJC_BLOCK_H_
74