/*******************************************************************************
* Copyright 2011 Google Inc. All Rights Reserved.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
package com.google.gwt.dev.shell.mac;
import java.util.List;
import com.google.gdt.eclipse.designer.mac.BrowserShellMac;
import com.google.gdt.eclipse.designer.mac.BrowserShellMac.DispatchObject;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.dev.javac.JsniMethod;
import com.google.gwt.dev.shell.CompilingClassLoader;
import com.google.gwt.dev.shell.DispatchIdOracle;
import com.google.gwt.dev.shell.JsValue;
import com.google.gwt.dev.shell.JsValueGlue;
import com.google.gwt.dev.shell.Jsni;
import com.google.gwt.dev.shell.ModuleSpace;
import com.google.gwt.dev.shell.ModuleSpaceHost;
/**
* An implementation of {@link com.google.gwt.dev.shell.ModuleSpace} for Safari.
*/
public class ModuleSpaceSaf extends ModuleSpace {
private final long m_window;
private StaticWebKitDispatchAdapter m_staticContext;
/**
* Constructs a browser interface for use with a global window object.
*
* @param moduleName name of the module
* @param key unique key for this instance of the module
*/
public ModuleSpaceSaf(ModuleSpaceHost host, long scriptGlobalObject,
String moduleName, Object key) {
super(host.getLogger(), host, moduleName);
// Hang on to the global execution state.
//
this.m_window = scriptGlobalObject;
}
protected void doCreateNativeMethods(String jsni) {
BrowserShellMac.executeScript(m_window, jsni);
}
@Override
public void dispose() {
super.dispose();
m_staticContext = null;
JsValueSaf.clearDispatchObjectRefs(getIsolatedClassLoader());
System.gc();
JsValue.mainThreadCleanup();
}
/**
* Invokes a native JavaScript function.
*
* @param name the name of the function to invoke
* @param jthis the function's 'this' context
* @param types the type of each argument
* @param args the arguments to be passed
* @return the return value as a Object.
*/
@Override
protected JsValue doInvoke(String name, Object jthis, Class<?>[] types, Object[] args) {
try {
m_staticContext.push(name);
CompilingClassLoader isolatedClassLoader = getIsolatedClassLoader();
JsValueSaf jsValueThis = new JsValueSaf();
Class<?> jthisType = jthis == null ? Object.class : jthis.getClass();
JsValueGlue.set(jsValueThis, isolatedClassLoader, jthisType, jthis);
long jsthis = jsValueThis.getJsValue();
int argc = args.length;
long[] argv = new long[argc];
JsValueSaf[] jsValueArgs = new JsValueSaf[argc];
for (int i = 0; i < argc; ++i) {
JsValueSaf jsValue = jsValueArgs[i] = new JsValueSaf();
JsValueGlue.set(jsValue, isolatedClassLoader, types[i], args[i]);
argv[i] = jsValue.getJsValue();
}
long result = BrowserShellMac.invoke(m_window, name, jsthis, argv);
return new JsValueSaf(result);
} catch (Throwable e) {
e.printStackTrace();
return new JsValueSaf();
} finally {
m_staticContext.pop();
}
}
@Override
protected void initializeStaticDispatcher() throws Throwable {
long staticDisp = BrowserShellMac.wrapDispatch((DispatchObject) getStaticDispatcher());
BrowserShellMac.invoke(m_window, "__defineStatic", m_window, new long[]{staticDisp});
// let the WebKit to be the owner of the object
BrowserShellMac.objcRelease(staticDisp);
}
@Override
protected void createStaticDispatcher(TreeLogger logger) {
String newScript = createNativeMethodInjector("__defineStatic", new String[] {"__arg0"}, "window.__static = __arg0;");
BrowserShellMac.executeScript(m_window, newScript);
}
@Override
protected Object getStaticDispatcher() {
if (m_staticContext == null) {
m_staticContext = new StaticWebKitDispatchAdapter(getIsolatedClassLoader());
}
return m_staticContext;
}
}