package org.archstudio.bna.demo;
import org.archstudio.bna.BNACanvas;
import org.archstudio.bna.IBNAModel;
import org.archstudio.bna.IBNAView;
import org.archstudio.bna.IBNAWorld;
import org.archstudio.bna.ICoordinateMapper;
import org.archstudio.bna.IThing;
import org.archstudio.bna.IThingLogicManager;
import org.archstudio.bna.constants.StickyMode;
import org.archstudio.bna.facets.IHasEndpoints;
import org.archstudio.bna.facets.IHasMutableReferencePoint;
import org.archstudio.bna.facets.IHasMutableSelected;
import org.archstudio.bna.facets.IHasStickyShape;
import org.archstudio.bna.facets.IHasText;
import org.archstudio.bna.logics.background.RotatingOffsetLogic;
import org.archstudio.bna.logics.coordinating.StickPointLogic;
import org.archstudio.bna.logics.editing.ClickSelectionLogic;
import org.archstudio.bna.logics.editing.DragMovableLogic;
import org.archstudio.bna.logics.editing.MarqueeSelectionLogic;
import org.archstudio.bna.logics.navigating.PanAndZoomLogic;
import org.archstudio.bna.things.shapes.EndpointThing;
import org.archstudio.bna.things.shapes.RectangleThing;
import org.archstudio.bna.things.shapes.SplineThing;
import org.archstudio.bna.things.utility.GridThing;
import org.archstudio.bna.things.utility.ShadowThing;
import org.archstudio.bna.ui.swt.SWTBNAUI;
import org.archstudio.bna.utils.Assemblies;
import org.archstudio.bna.utils.BNARenderingSettings;
import org.archstudio.bna.utils.BNAUtils;
import org.archstudio.bna.utils.DefaultBNAModel;
import org.archstudio.bna.utils.DefaultBNAView;
import org.archstudio.bna.utils.DefaultBNAWorld;
import org.archstudio.bna.utils.LinearCoordinateMapper;
import org.archstudio.bna.utils.UserEditableUtils;
import org.archstudio.swtutils.constants.Flow;
import org.archstudio.swtutils.constants.Orientation;
import org.archstudio.sysutils.Finally;
import org.archstudio.sysutils.SystemUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
public class BNAStressTest {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
IBNAModel model;
IBNAWorld world;
BNACanvas canvas;
IBNAView view;
try (Finally lock = BNAUtils.lock()) {
model = new DefaultBNAModel();
world = new DefaultBNAWorld("top view", model);
view = new DefaultBNAView(null, world, new LinearCoordinateMapper());
canvas = new BNACanvas(shell, SWT.V_SCROLL | SWT.H_SCROLL, view);
canvas.setBNAUI(new SWTBNAUI(view));
BNARenderingSettings.setAntialiasGraphics(canvas, true);
BNARenderingSettings.setAntialiasText(canvas, true);
BNARenderingSettings.setDecorativeGraphics(canvas, true);
BNARenderingSettings.setDisplayShadows(canvas, true);
populateModel(canvas.getBNAView(), 40, 40, 3, 2);
addUILogics(canvas.getBNAView());
}
canvas.setSize(500, 500);
canvas.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
shell.setSize(400, 400);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
try (Finally lock = BNAUtils.lock()) {
view.dispose();
world.dispose();
model.dispose();
}
display.dispose();
}
private static void addUILogics(IBNAView view) {
IThingLogicManager tlm = view.getBNAWorld().getThingLogicManager();
tlm.addThingLogic(RotatingOffsetLogic.class);
tlm.addThingLogic(PanAndZoomLogic.class);
tlm.addThingLogic(MarqueeSelectionLogic.class);
tlm.addThingLogic(ClickSelectionLogic.class);
tlm.addThingLogic(DragMovableLogic.class);
}
private static void populateModel(IBNAView view, int cw, int ch, int itbw, int ilrh) {
IBNAWorld world = view.getBNAWorld();
IBNAModel model = world.getBNAModel();
GridThing.createIn(world);
ShadowThing.createIn(world);
ICoordinateMapper cm = view.getCoordinateMapper();
Rectangle bounds = cm.getLocalBounds();
Point offset = new Point(bounds.x + bounds.width / 2, bounds.y + bounds.height / 2);
int x0 = offset.x;
int y0 = offset.y;
int w = 60;
int h = 40;
int sw = 20;
int sh = 20;
long lTime = System.nanoTime();
try (Finally lock = BNAUtils.lock(); Finally bulkChange = model.beginBulkChange()) {
for (int cwi = 0; cwi < cw; cwi++) {
for (int chi = 0; chi < ch; chi++) {
int cx1 = x0 + (w + sw) * cwi;
int cy1 = y0 + (h + sh) * chi;
Object id = id(cwi, chi);
RectangleThing b = Assemblies.createRectangle(world, id, null);
b.setBoundingBox(new Rectangle(cx1, cy1, w, h));
Assemblies.BOUNDED_TEXT_KEY.get(b, model).set(
IHasText.TEXT_KEY,
"Now is the time for all good men to come to the aid of their country (" + (cwi + chi * cw)
+ ")");
b.setColor(new RGB(255, 255, 128));
b.setSecondaryColor(new RGB(192, 192, 128));
UserEditableUtils.addEditableQualities(b, IHasMutableSelected.USER_MAY_SELECT,
IHasMutableReferencePoint.USER_MAY_MOVE);
Flow f = Flow.values()[(cwi + chi) % 4];
for (int iwi = 0; iwi < itbw; iwi++) {
createEndpoint(world, id(id, Orientation.NORTH, iwi), b, new Point(cx1 + w * (iwi + 1)
/ (itbw + 1), cy1), f, Orientation.NORTH);
createEndpoint(world, id(id, Orientation.SOUTH, iwi), b, new Point(cx1 + w * (iwi + 1)
/ (itbw + 1), cy1 + h), f, Orientation.SOUTH);
}
for (int ihi = 0; ihi < ilrh; ihi++) {
createEndpoint(world, id(id, Orientation.WEST, ihi), b, new Point(cx1, cy1 + h * (ihi + 1)
/ (ilrh + 1)), f, Orientation.WEST);
createEndpoint(world, id(id, Orientation.EAST, ihi), b, new Point(cx1 + w, cy1 + h * (ihi + 1)
/ (ilrh + 1)), f, Orientation.EAST);
}
createEndpoint(world, id(id, Orientation.NORTHWEST, 0), b, new Point(cx1, cy1), f,
Orientation.NORTHWEST);
createEndpoint(world, id(id, Orientation.NORTHEAST, 0), b, new Point(cx1 + w, cy1), f,
Orientation.NORTHEAST);
createEndpoint(world, id(id, Orientation.SOUTHWEST, 0), b, new Point(cx1, cy1 + h), f,
Orientation.SOUTHWEST);
createEndpoint(world, id(id, Orientation.SOUTHEAST, 0), b, new Point(cx1 + w, cy1 + h), f,
Orientation.SOUTHEAST);
}
}
for (int cwi = 0; cwi < cw; cwi++) {
for (int chi = 1; chi < ch; chi++) {
for (int iwi = 0; iwi < itbw; iwi++) {
createSpline(world, id(id(cwi, chi - 1), Orientation.SOUTH, iwi),
id(id(cwi, chi), Orientation.NORTH, iwi));
}
}
}
for (int cwi = 1; cwi < cw; cwi++) {
for (int chi = 0; chi < ch; chi++) {
for (int ihi = 0; ihi < ilrh; ihi++) {
createSpline(world, id(id(cwi - 1, chi), Orientation.EAST, ihi),
id(id(cwi, chi), Orientation.WEST, ihi));
}
}
}
for (int cwi = 1; cwi < cw; cwi++) {
for (int chi = 1; chi < ch; chi++) {
createSpline(world, id(id(cwi - 1, chi - 1), Orientation.SOUTHEAST, 0),
id(id(cwi, chi), Orientation.NORTHWEST, 0));
createSpline(world, id(id(cwi, chi - 1), Orientation.SOUTHWEST, 0),
id(id(cwi - 1, chi), Orientation.NORTHEAST, 0));
}
}
lTime = System.nanoTime() - lTime;
System.err.println("Time to add elements: " + lTime / 1000000f);
lTime = System.nanoTime();
for (IThing thing : model.getAllThings()) {
view.getThingPeer(thing);
}
lTime = System.nanoTime() - lTime;
System.err.println("Time to create peers: " + lTime / 1000000f);
final RectangleThing b = (RectangleThing) model.getThing(id(0, 0));
Thread movement = new Thread(new Runnable() {
int degree = 0;
@Override
public void run() {
while (true) {
try (Finally lock = BNAUtils.lock()) {
degree += 15;
double radius = 30;
double x = radius * Math.cos(degree * Math.PI / 180);
double y = radius * Math.sin(degree * Math.PI / 180);
Rectangle r = b.getBoundingBox();
r.x = SystemUtils.round(x);
r.y = SystemUtils.round(y);
b.setBoundingBox(r);
}
try {
Thread.sleep(1000 / 120);
}
catch (InterruptedException e) {
}
}
}
});
movement.setDaemon(true);
movement.start();
}
}
private static Object id(int cwi, int chi) {
return "(" + cwi + "," + chi + ")";
}
private static Object id(Object id, Orientation orientation, int index) {
return "(" + id + ":" + orientation + "," + index + ")";
}
private static void createEndpoint(IBNAWorld world, Object id, IHasStickyShape parent, Point location, Flow flow,
Orientation orientation) {
IBNAModel model = world.getBNAModel();
EndpointThing e = Assemblies.createEndpoint(world, id, parent);
e.setAnchorPoint(BNAUtils.toPoint2D(location));
Assemblies.DIRECTION_KEY.get(e, model).setFlow(flow);
Assemblies.DIRECTION_KEY.get(e, model).setOrientation(orientation);
UserEditableUtils.addEditableQualities(e, IHasMutableReferencePoint.USER_MAY_MOVE);
}
private static void createSpline(IBNAWorld world, Object id0, Object id1) {
IBNAModel model = world.getBNAModel();
IThingLogicManager tlm = world.getThingLogicManager();
SplineThing s = Assemblies.createSpline(world, null, null);
IHasStickyShape a0 = (IHasStickyShape) model.getThing(id0);
IHasStickyShape a1 = (IHasStickyShape) model.getThing(id1);
StickPointLogic spl = tlm.addThingLogic(StickPointLogic.class);
spl.stick(s, IHasEndpoints.ENDPOINT_1_KEY, StickyMode.CENTER, a0);
spl.stick(s, IHasEndpoints.ENDPOINT_2_KEY, StickyMode.CENTER, a1);
UserEditableUtils.addEditableQualities(s, IHasMutableSelected.USER_MAY_SELECT);
}
}