/* * Copyright 2013, The gwtquery team. * * 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. */ package com.google.gwt.query.client.plugins.deferred; import com.google.gwt.query.client.Function; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Implementation of jQuery.Callbacks for gwtquery. */ public class Callbacks { /** * Iterface used for callbacks which could cancel the execution * when returning false. */ public interface Callback { /** * Return false to avoid executing the rest of functions. */ boolean f(Object... objects); } private List<Object> stack = new ArrayList<>(); private boolean done = false; private List<Object> memory = null; private boolean isOnce, isMemory, isUnique, stopOnFalse; public Callbacks() { this(""); } /** * Create a new Callbacks object with options given as a space delimited string. * * Valid options are: * * once, memory, unique, stopOnFalse */ public Callbacks(String options) { isOnce = options.contains("once"); isMemory = options.contains("memory"); isUnique = options.contains("unique"); stopOnFalse = options.contains("stopOnFalse"); } /** * Add a Callback or a collection of callbacks to a callback list. * */ public Callbacks add(Callback... c) { addAll((Object[]) c); return this; } /** * Add a Callback or a collection of callbacks to a callback list. */ public Callbacks add(com.google.gwt.core.client.Callback<?, ?>... c) { addAll((Object[]) c); return this; } /** * Add a Function or a collection of Function to a callback list. */ public Callbacks add(Function... f) { addAll((Object[]) f); return this; } /** * Disable a callback list from doing anything more. */ public Callbacks disable() { stack = null; done = true; return this; } /** * lock. */ public Callbacks lock() { if (!isMemory) { disable(); } stack = null; return this; } /** * Call all of the callbacks with the given arguments. */ public Callbacks fire(Object... o) { if (!done) { done = isOnce; if (isMemory) { memory = new ArrayList<>(Arrays.asList(o)); } if (stack != null) for (Object c : stack) { if (!run(c, o) && stopOnFalse) { break; } } } return this; } /** * Remove a callback or a collection of callbacks from a callback list. */ public Callbacks remove(Object... o) { stack.removeAll(Arrays.asList(o)); return this; } private void addAll(Object... o) { for (Object c : o) { if (!done && stack != null && c != null && (!isUnique || !stack.contains(c))) { stack.add(c); } // In jQuery add always is run when memory is true even when unique is set if (isMemory && memory != null) { run(c, memory.toArray()); } } } @SuppressWarnings({"unchecked", "rawtypes"}) private boolean run(Object c, Object... o) { // Unbox array inside array when there is only an element. // It happens when running filters in Promise.then() if (o != null && o.length == 1 && o[0] != null && o[0].getClass().isArray()) { o = (Object[]) o[0]; } if (c instanceof Callback) { return ((Callback) c).f(o); } else if (c instanceof Function) { Object r = ((Function) c).f(o); return (r instanceof Boolean) ? (Boolean) r : true; } else if (c instanceof com.google.gwt.core.client.Callback) { ((com.google.gwt.core.client.Callback) c).onSuccess(o); } return true; } public String status() { return "stack=" + (stack == null ? "null" : stack.size()) + " " + done; } }