blob: e4aa7db54fff1ca696d18c6f38657f2227c2ea03 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.kie.lienzo.client;
import java.util.function.Supplier;
import com.ait.lienzo.client.core.animation.AnimationCallback;
import com.ait.lienzo.client.core.animation.AnimationProperties;
import com.ait.lienzo.client.core.animation.AnimationProperty;
import com.ait.lienzo.client.core.animation.AnimationTweener;
import com.ait.lienzo.client.core.animation.IAnimation;
import com.ait.lienzo.client.core.animation.IAnimationHandle;
import com.ait.lienzo.client.core.shape.Circle;
import com.ait.lienzo.client.core.shape.Shape;
import com.ait.lienzo.client.widget.panel.LienzoPanel;
import com.ait.lienzo.shared.core.types.Color;
import com.google.gwt.core.client.Duration;
import com.google.gwt.dom.client.Style.Display;
import elemental2.dom.CSSProperties;
import elemental2.dom.DomGlobal;
import elemental2.dom.HTMLButtonElement;
import elemental2.dom.HTMLDivElement;
import org.kie.lienzo.client.util.FPSCounter;
import org.kie.lienzo.client.util.Util;
public class PerformanceTests extends BaseExample implements Example {
private static final int TOTAL_CIRCLES = 100;
private HTMLButtonElement decreaseCountButton;
private HTMLDivElement countText;
private HTMLButtonElement increaseCountButton;
private HTMLButtonElement runTestButton;
private HTMLDivElement timeText;
private HTMLButtonElement startAnimationButton;
private HTMLButtonElement stopAnimationButton;
private int count = TOTAL_CIRCLES;
private Shape[] instances;
private IAnimationHandle[] handles;
private boolean isAnimationEnabled = false;
private FPSCounter fpsCounter;
private static Supplier<Shape> shapeBuilder =
() -> new Circle(10).setStrokeColor(Color.getRandomHexColor()).setStrokeWidth(2).setFillColor(Color.getRandomHexColor()).setDraggable(true);
public PerformanceTests(String title) {
super(title);
}
@Override
public void init(LienzoPanel panel,
HTMLDivElement topDiv) {
super.init(panel, topDiv);
HTMLDivElement fpsDiv = (HTMLDivElement) DomGlobal.document.createElement("div");
HTMLDivElement buttonsDiv = (HTMLDivElement) DomGlobal.document.createElement("div");
buttonsDiv.style.display = Display.INLINE_FLEX.getCssName();
topDiv.style.display = Display.INLINE.getCssName();
topDiv.appendChild(fpsDiv);
topDiv.appendChild(buttonsDiv);
heightOffset = 30;
fpsCounter = FPSCounter.toElement(displayer -> {
displayer.style.cssFloat = "right";
fpsDiv.appendChild(displayer);
}).start();
decreaseCountButton = createButton("[-]", this::decreaseInstanceCount);
buttonsDiv.appendChild(decreaseCountButton);
countText = createText("" + count);
buttonsDiv.appendChild(countText);
increaseCountButton = createButton("[+]", this::increaseInstanceCount);
buttonsDiv.appendChild(increaseCountButton);
runTestButton = createButton("Run", this::run);
buttonsDiv.appendChild(runTestButton);
timeText = createText("" + count);
timeText.style.color = "blue";
buttonsDiv.appendChild(timeText);
startAnimationButton = createButton("Start", this::startAnimation);
startAnimationButton.style.marginLeft = CSSProperties.MarginLeftUnionType.of("25px");
buttonsDiv.appendChild(startAnimationButton);
stopAnimationButton = createButton("Stop", this::stopAnimation);
buttonsDiv.appendChild(stopAnimationButton);
updateAnimationButtonsState();
width = 300;
height = 300;
}
private void decreaseInstanceCount() {
setCountIncrement(-1 * getCountInc());
}
private void increaseInstanceCount() {
setCountIncrement(getCountInc());
}
private void updateAnimationButtonsState() {
startAnimationButton.disabled = isAnimationEnabled;
stopAnimationButton.disabled = !isAnimationEnabled;
}
private void stopAnimation() {
isAnimationEnabled = false;
if (null != handles) {
for (int i = 0; i < handles.length; i++) {
IAnimationHandle handle = handles[i];
handle.stop();
handles[i] = null;
}
handles = null;
}
updateAnimationButtonsState();
}
private void startAnimation() {
isAnimationEnabled = true;
handles = new IAnimationHandle[instances.length];
int i = 0;
for (Shape instance : instances) {
animateInstance(i, instance);
i++;
}
updateAnimationButtonsState();
}
private IAnimationHandle animateInstance(final int i,
final Shape shape) {
final double[] location = Util.getRandomLocation(shape, width, height, leftPadding, topPadding, rightPadding, bottomPadding);
// DomGlobal.console.log("Shape animated to [" + location[0] + ", " + location[1] + "]");
IAnimationHandle handle = shape.animate(AnimationTweener.LINEAR,
AnimationProperties.toPropertyList(AnimationProperty.Properties.X(location[0]),
AnimationProperty.Properties.Y(location[1])),
500,
new AnimationCallback() {
@Override
public void onStart(IAnimation animation, IAnimationHandle handle) {
super.onStart(animation, handle);
}
@Override
public void onFrame(IAnimation animation, IAnimationHandle handle) {
super.onFrame(animation, handle);
}
@Override
public void onClose(IAnimation animation, IAnimationHandle handle) {
super.onClose(animation, handle);
if (isAnimationEnabled) {
animateInstance(i, shape);
}
}
});
handles[i] = handle;
return handle;
}
private void setCountIncrement(int value) {
if (count + value > 0) {
count = count + value;
countText.textContent = "" + count;
run();
}
}
@Override
public void run() {
boolean wasAnimationEnabled = isAnimationEnabled;
clear();
Duration duration = new Duration();
instances = new Shape[count];
for (int i = 0; i < count; i++) {
final Shape shape = shapeBuilder.get();
instances[i] = shape;
setRandomLocation(shape);
layer.add(shape);
}
layer.draw();
int ellapsed = duration.elapsedMillis();
console.log("Rendering Test completed - #[" + count + "] took [" + ellapsed + "ms]");
timeText.textContent = "[ " + ellapsed + "ms ]";
if (wasAnimationEnabled) {
startAnimation();
}
}
@Override
public void onResize() {
super.onResize();
for (Shape shape : instances) {
setRandomLocation(shape);
}
}
private void clear() {
stopAnimation();
if (null != instances) {
for (Shape instance : instances) {
instance.removeFromParent();
}
instances = null;
}
layer.clear();
layer.draw();
}
private int getCountInc() {
return count / 4;
}
@Override
public void destroy() {
super.destroy();
clear();
fpsCounter.destroy();
fpsCounter = null;
decreaseCountButton.remove();
countText.remove();
increaseCountButton.remove();
runTestButton.remove();
timeText.remove();
startAnimationButton.remove();
stopAnimationButton.remove();
}
}