// ********************************************************************** // // Copyright (c) 2003-2016 ZeroC, Inc. All rights reserved. // // This copy of Ice is licensed to you under the terms described in the // ICE_LICENSE file included in this distribution. // // ********************************************************************** #import #import #import #import #include namespace { class DispatcherI : public Ice::Dispatcher { public: // We must explicitely retain/release so that the garbage // collector does not trash the dispatcher. DispatcherI(void(^dispatcher)(id, id)) : _dispatcher(Block_copy(dispatcher)) { } virtual ~DispatcherI() { Block_release(_dispatcher); } virtual void dispatch(const Ice::DispatcherCallPtr& call, const Ice::ConnectionPtr& connection) { NSException* ex = nil; @autoreleasepool { id con = [ICEConnection localObjectWithCxxObject:connection.get()]; id c = [[ICEDispatcherCall alloc] initWithCall:call.get()]; @try { _dispatcher(c, con); } @catch(id e) { ex = [e retain]; } @finally { [c release]; } } if(ex != nil) { rethrowCxxException(ex, true); // True = release the exception. } } private: void(^_dispatcher)(id, id); }; typedef IceUtil::Handle DispatcherIPtr; } @implementation ICEDispatcher +(Ice::Dispatcher*) dispatcherWithDispatcher:(void(^)(id, id))dispatcher { return new DispatcherI(dispatcher); } @end @implementation ICEDispatcherCall -(id) initWithCall:(Ice::DispatcherCall*)call { self = [super init]; if(!self) { return nil; } cxxCall_ = call; cxxCall_->__incRef(); return self; } -(void) dealloc { cxxCall_->__decRef(); cxxCall_ = 0; [super dealloc]; } -(void) run { cppCall(^ { cxxCall_->run(); }); } @end