/** * Copyright 2008 - 2015 The Loon Game Engine Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * 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. * * @project loon * @author cping * @email:javachenpeng@yahoo.com * @version 0.5 */ package loon; import loon.utils.TArray; import loon.utils.reply.Act; import loon.utils.reply.GoPromise; import loon.utils.reply.Port; public abstract class Asyn { public static class Default extends Asyn { /** 为了语法转换到C#和C++,只能忍痛放弃匿名构造类了…… **/ private class CallDefaultPort<T> extends Port<T>{ private Default _def; CallDefaultPort(Default d){ this._def = d; } @Override public void onEmit(Object event) { _def.dispatch(); } } private final TArray<Runnable> pending = new TArray<>(); private final TArray<Runnable> running = new TArray<>(); protected final Log log; public Default(Log log, Act<? extends Object> frame) { this.log = log; frame.connect(new CallDefaultPort<Object>(this)).setPriority(Short.MAX_VALUE); } @Override public boolean isAsyncSupported() { return false; } @Override public void invokeAsync(Runnable action) { throw new UnsupportedOperationException(); } @Override public synchronized void invokeLater(Runnable action) { pending.add(action); } private void dispatch() { synchronized (this) { running.addAll(pending); pending.clear(); } for (int ii = 0, ll = running.size; ii < ll; ii++) { Runnable action = running.get(ii); try { action.run(); } catch (Exception e) { log.warn("invokeLater Runnable failed: " + action, e); } } running.clear(); } } public abstract void invokeLater(Runnable action); /** 为了语法转换到C#和C++,只能忍痛放弃匿名构造类了…… **/ private static class DeferredPromiseRunnable<T> implements Runnable { private GoPromise<T> _promise; private int _mode = 0; private T _value; private Throwable _cause; public DeferredPromiseRunnable(int m, GoPromise<T> p, T val, Throwable c) { this._mode = m; this._promise = p; this._value = val; this._cause = c; } @Override public void run() { switch (_mode) { case 0: _promise.succeed(_value); break; default: _promise.fail(_cause); break; } } } /** 为了语法转换到C#和C++,只能忍痛放弃匿名构造类了…… **/ private class CallDeferredPromise<T> extends GoPromise<T> { private Asyn _asyn; public CallDeferredPromise(Asyn a) { this._asyn = a; } @Override public void succeed(final T value) { _asyn.invokeLater(new DeferredPromiseRunnable<T>(0, this, value, null)); } @Override public void fail(final Throwable cause) { _asyn.invokeLater(new DeferredPromiseRunnable<T>(1, this, null, cause)); } } public <T> GoPromise<T> deferredPromise() { return new CallDeferredPromise<T>(this); } public abstract boolean isAsyncSupported(); public void invokeAsync(Runnable action) { throw new UnsupportedOperationException(); } }