1 package ch
.cyberduck
.binding
;
4 * Copyright (c) 2005 David Kocher. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * Bug fixes, suggestions and comments should be sent to:
18 * dkocher@cyberduck.ch
21 import ch
.cyberduck
.binding
.foundation
.NSNotificationCenter
;
22 import ch
.cyberduck
.binding
.foundation
.NSObject
;
23 import ch
.cyberduck
.binding
.foundation
.NSThread
;
24 import ch
.cyberduck
.core
.AbstractController
;
25 import ch
.cyberduck
.core
.threading
.MainAction
;
27 import org
.apache
.log4j
.Logger
;
28 import org
.rococoa
.Foundation
;
29 import org
.rococoa
.ID
;
30 import org
.rococoa
.Rococoa
;
35 public class ProxyController
extends AbstractController
{
36 private static Logger log
= Logger
.getLogger(ProxyController
.class);
39 * You need to keep a reference to the returned value for as long as it is
40 * active. When it is GCd, it will release the Objective-C proxy.
42 private NSObject proxy
;
46 public NSObject
proxy() {
47 return this.proxy(NSObject
.class);
50 protected NSObject
proxy(Class
<?
extends NSObject
> type
) {
52 proxy
= Rococoa
.proxy(this, type
);
58 return this.id(NSObject
.class);
61 protected ID
id(Class
<?
extends NSObject
> type
) {
63 id
= this.proxy(type
).id();
69 * Free all locked resources by this controller; also remove me from all observables;
70 * marks this controller to be garbage collected as soon as needed
73 public void invalidate() {
74 if(log
.isDebugEnabled()) {
75 log
.debug(String
.format("Invalidate controller %s", this));
78 NSNotificationCenter
.defaultCenter().removeObserver(id
);
84 * You can use this method to deliver messages to the main thread of your application. The main thread
85 * encompasses the application’s main run loop, and is where the NSApplication object receives
86 * events. The message in this case is a method of the current object that you want to execute
89 * Execute the passed <code>Runnable</code> on the main thread also known as NSRunLoop.DefaultRunLoopMode
91 * @param runnable The <code>Runnable</code> to run
92 * @param wait Block until execution on main thread exits. A Boolean that specifies whether the current
93 * thread blocks until after the specified selector is performed on the receiver on the main thread.
94 * Specify YES to block this thread; otherwise, specify NO to have this method return immediately.
95 * If the current thread is also the main thread, and you specify YES for this parameter,
96 * the message is delivered and processed immediately.
99 public void invoke(final MainAction runnable
, final boolean wait
) {
100 if(!runnable
.isValid()) {
103 if(NSThread
.isMainThread()) {
104 if(log
.isDebugEnabled()) {
105 log
.debug(String
.format("Already on main thread. Invoke %s directly.", runnable
));
110 synchronized(runnable
.lock()) {
111 if(log
.isTraceEnabled()) {
112 log
.trace(String
.format("Invoke runnable %s on main thread", runnable
));
115 //Defer to main thread
116 Foundation
.runOnMainThread(runnable
, wait
);
119 log
.error(String
.format("Exception %s running task on main thread", e
.getMessage()), e
);