From ca097f7e268034cdafce9f736962ea5844e28e2d Mon Sep 17 00:00:00 2001 From: villberg Date: Fri, 9 Jul 2010 05:04:24 +0000 Subject: [PATCH] Sysdyn dev git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@16567 ac1ea38d-2e2b-0410-8846-a27921b304fc --- .../simantics/modelica/ModelicaManager.java | 1 + .../simantics/objmap/schema/SimpleSchema.java | 20 +- org.simantics.sysdyn.ui/adapters.xml | 2 +- .../ui/editor/DiagramToCompositeMapping3.java | 2 +- .../ui/editor/participant/ConnectTool.java | 3 +- .../simantics/sysdyn/ui/elements2/Arcs.java | 211 ++++++++++++ .../sysdyn/ui/elements2/Dependencies.java | 227 +++++++++++++ .../DependencyConnectionFactory.java | 106 +++++- .../ui/elements2/DependencyEdgeClass.java | 180 +++++----- .../sysdyn/ui/elements2/DependencyNode.java | 222 ++++-------- .../sysdyn/ui/elements2/FlowEdgeClass.java | 153 ++++----- .../sysdyn/ui/elements2/FlowNode.java | 209 +++--------- .../simantics/sysdyn/ui/elements2/Flows.java | 175 ++++++++++ .../ui/elements2/GraphPropertyNode.java | 101 ++++++ .../sysdyn/ui/elements2/ModuleFactory.java | 59 ++++ .../ui/elements2/SysdynConnectionClass.java | 29 +- .../sysdyn/ui/elements2/ValveFactory.java | 1 + .../sysdyn/ui/handlers/NewModelHandler.java | 1 + .../widgets/expressions/StockExpression.java | 4 +- org.simantics.sysdyn/META-INF/MANIFEST.MF | 3 +- .../org/simantics/sysdyn/SysdynResource.java | 33 +- .../simantics/sysdyn/manager/SysdynModel.java | 43 ++- .../sysdyn/modelica/ModelicaWriter.java | 20 +- .../sysdyn/representation/Configuration.java | 8 + .../sysdyn/representation/Module.java | 7 + .../sysdyn/representation/ModuleType.java | 21 ++ .../sysdyn/representation/SysdynSchema.java | 3 + .../expressions/InputExpression.java | 25 ++ sysdyn_ontologies/sysdyn.graph | 317 +++++++++++++----- 29 files changed, 1592 insertions(+), 594 deletions(-) create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Arcs.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Dependencies.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Flows.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/GraphPropertyNode.java create mode 100644 org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ModuleFactory.java create mode 100644 org.simantics.sysdyn/src/org/simantics/sysdyn/representation/ModuleType.java create mode 100644 org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/InputExpression.java diff --git a/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java b/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java index 29120737..1eb99156 100644 --- a/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java +++ b/org.simantics.modelica/src/org/simantics/modelica/ModelicaManager.java @@ -62,6 +62,7 @@ public class ModelicaManager { if((char)c != '\n') b.append((char)c); else { + System.out.println("OMC output: " + b.toString()); monitor.message(b.toString()); b.delete(0, b.length()); } diff --git a/org.simantics.objmap/src/org/simantics/objmap/schema/SimpleSchema.java b/org.simantics.objmap/src/org/simantics/objmap/schema/SimpleSchema.java index a0f648f5..9c779251 100644 --- a/org.simantics.objmap/src/org/simantics/objmap/schema/SimpleSchema.java +++ b/org.simantics.objmap/src/org/simantics/objmap/schema/SimpleSchema.java @@ -13,6 +13,8 @@ package org.simantics.objmap.schema; import gnu.trove.THashMap; +import java.util.Set; + import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; @@ -43,13 +45,17 @@ public class SimpleSchema implements IMappingSchema { @Override public ILinkType linkTypeOfDomainElement(ReadGraph g, Resource element) throws MappingException { try { - ILinkType type = domainLinkTypes.get( - g.getSingleObject(element, g.getBuiltins().InstanceOf)); - if(type == null) - throw new MappingException("Didn't find a link type for " + - GraphUtils.getReadableName(g, element) + "." - ); - return type; + + for(Resource type : g.getTypes(element)) { + + ILinkType linkType = domainLinkTypes.get(type); + if(linkType != null) return linkType; + + } + + throw new MappingException("Didn't find a link type for " + + GraphUtils.getReadableName(g, element) + "."); + } catch (DatabaseException e) { throw new MappingException(e); } diff --git a/org.simantics.sysdyn.ui/adapters.xml b/org.simantics.sysdyn.ui/adapters.xml index 2b16b667..07396da1 100644 --- a/org.simantics.sysdyn.ui/adapters.xml +++ b/org.simantics.sysdyn.ui/adapters.xml @@ -25,5 +25,5 @@ - none 0 fill 1 + none 0 fill 1 \ No newline at end of file diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java index 27bfbfab..cf7fbc51 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java @@ -17,7 +17,6 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.layer0.utils.binaryPredicates.InversePredicate; import org.simantics.layer0.utils.binaryPredicates.OrderedSetElementsPredicate; import org.simantics.mapping.constraint.instructions.IInstruction; -import org.simantics.mapping.constraint.instructions.PrintStateInstruction; import org.simantics.mapping.constraint.instructions.TypedBracketInstruction.CreationInstruction; import org.simantics.mapping.rule.instructions.IRuleInstruction; import org.simantics.sysdyn.SysdynResource; @@ -110,6 +109,7 @@ public class DiagramToCompositeMapping3 extends org.simantics.modeling.mapping.D Connection ), bb(b.InstanceOf, Connection, ComponentType), + bb(b.PartOf, Connection, Configuration), b(mapped, Connection) ); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java index 2ccc3124..d36ba476 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/participant/ConnectTool.java @@ -506,7 +506,8 @@ public class ConnectTool extends AbstractDiagramParticipant { soa = endElement.getElementClass().getSingleItem(StaticObjectAdapter.class); Resource end = soa.adapt(Resource.class); if(conntype.equals(sr.DependencyConnection)) { - if(!(end.equals(sr.AuxiliarySymbol) || end.equals(sr.ValveSymbol))) return null; + if(end.equals(sr.CloudSymbol)) return null; + //if(!(end.equals(sr.AuxiliarySymbol) || end.equals(sr.ValveSymbol))) return null; } else if (conntype.equals(sr.FlowConnection)) { if(!(end.equals(sr.StockSymbol) || end.equals(sr.ValveSymbol) || end.equals(sr.CloudSymbol))) return null; } else { diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Arcs.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Arcs.java new file mode 100644 index 00000000..98d04a60 --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Arcs.java @@ -0,0 +1,211 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * 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 + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements2; + +import java.awt.geom.Rectangle2D; + +public class Arcs { + + public static final double PI2 = Math.PI*2.0; + + /** + * Returns angle + 2PI * n such that the + * result is between -PI and PI. + */ + public static double normalizeAngle(double angle) { + return Math.IEEEremainder(angle, PI2); + } + + /** + * Returns true, if three normalized angles are clockwise oriented. + */ + public static boolean areClockwiseOrdered(double angle1, double angle2, double angle3) { + //System.out.println(angle1 + " " + angle2 + " " + angle3); + return angle1 < angle2 + ? (angle2 < angle3 || angle3 < angle1) + : (angle2 < angle3 && angle3 < angle1) + ; + } + + /** + * Returns an angle in radians between straight line from (x0,y0) to (x2,y2) + * and an arc from (x0,y0) to (x2,y2) thru (x1,y1). The angle + * is measured at (x0,y0) and is between -PI and PI. + */ + public static double angleOfArc( + double x0, double y0, + double x1, double y1, + double x2, double y2) { + double dx0 = x1-x0; + double dy0 = y1-y0; + double dx1 = x1-x2; + double dy1 = y1-y2; + double dx = x2-x0; + double dy = y2-y0; + // Length of cross product (p1-p0)x(p2-p0) + double dd = dx0*dy - dy0*dx; + + if(Math.abs(dd) < 1e-6) // Points are (almost) collinear + return 0.0; + else { + // (p1-p0)*(p1-p2) / dd + double offset = (dx0*dx1 + dy0*dy1) / dd; + double angle = Math.PI*0.5 - Math.atan(offset); + if(dd > 0.0) + angle = angle-Math.PI; + return angle; + + } + } + + private static double updateBestNextAngle(double curAngle, double bestAngle, double newAngle) { + if(newAngle < curAngle) + newAngle += PI2; + if(newAngle < bestAngle) + return newAngle; + return bestAngle; + } + + private static double updateBestPrevAngle(double curAngle, double bestAngle, double newAngle) { + if(newAngle > curAngle) + newAngle -= PI2; + if(newAngle > bestAngle) + return newAngle; + return bestAngle; + } + + public static double nextIntersectingAngle(double cx, double cy, double r, + double curAngle, Rectangle2D rect, boolean dir) { + if(!dir) { + double bestAngle = curAngle + PI2; + { + double dx = rect.getMinX() - cx; + if(Math.abs(dx) < r) { + double angle = normalizeAngle(Math.acos(dx / r)); + bestAngle = updateBestNextAngle(curAngle, bestAngle, angle); + bestAngle = updateBestNextAngle(curAngle, bestAngle, -angle); + } + } + { + double dx = rect.getMaxX() - cx; + if(Math.abs(dx) < r) { + double angle = normalizeAngle(Math.acos(dx / r)); + bestAngle = updateBestNextAngle(curAngle, bestAngle, angle); + bestAngle = updateBestNextAngle(curAngle, bestAngle, -angle); + } + } + { + double dy = cy - rect.getMinY(); + if(Math.abs(dy) < r) { + double angle = Math.asin(dy / r); + bestAngle = updateBestNextAngle(curAngle, bestAngle, angle); + bestAngle = updateBestNextAngle(curAngle, bestAngle, + normalizeAngle(Math.PI-angle)); + } + } + { + double dy = cy - rect.getMaxY(); + if(Math.abs(dy) < r) { + double angle = Math.asin(dy / r); + bestAngle = updateBestNextAngle(curAngle, bestAngle, angle); + bestAngle = updateBestNextAngle(curAngle, bestAngle, + normalizeAngle(Math.PI-angle)); + } + } + return normalizeAngle(bestAngle); + } + else { + double bestAngle = curAngle - PI2; + { + double dx = rect.getMinX() - cx; + if(Math.abs(dx) < r) { + double angle = normalizeAngle(Math.acos(dx / r)); + bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle); + bestAngle = updateBestPrevAngle(curAngle, bestAngle, -angle); + } + } + { + double dx = rect.getMaxX() - cx; + if(Math.abs(dx) < r) { + double angle = normalizeAngle(Math.acos(dx / r)); + bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle); + bestAngle = updateBestPrevAngle(curAngle, bestAngle, -angle); + } + } + { + double dy = cy - rect.getMinY(); + if(Math.abs(dy) < r) { + double angle = Math.asin(dy / r); + bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle); + bestAngle = updateBestPrevAngle(curAngle, bestAngle, + normalizeAngle(Math.PI-angle)); + } + } + { + double dy = cy - rect.getMaxY(); + if(Math.abs(dy) < r) { + double angle = Math.asin(dy / r); + bestAngle = updateBestPrevAngle(curAngle, bestAngle, angle); + bestAngle = updateBestPrevAngle(curAngle, bestAngle, + normalizeAngle(Math.PI-angle)); + } + } + return normalizeAngle(bestAngle); + } + } + + public static boolean hitTest(Rectangle2D beginBounds, Rectangle2D endBounds, double angle, double x, double y, double tolerance) { + + boolean clockWise = angle > 0; + + double x0 = beginBounds.getCenterX(); + double y0 = beginBounds.getCenterY(); + double x1 = endBounds.getCenterX(); + double y1 = endBounds.getCenterY(); + + double offset = + Math.abs(angle) < 1.0e-6 + ? 1e3 * Math.signum(angle) + : Math.tan(Math.PI*0.5-angle)*0.5; + double cx = 0.5*(x0+x1) + offset * (y1-y0); + double cy = 0.5*(y0+y1) + offset * (x0-x1); + double dx0 = x0 - cx; + double dy0 = y0 - cy; + double dx1 = x1 - cx; + double dy1 = y1 - cy; + double r = Math.sqrt(dx0*dx0 + dy0*dy0); + double angle0 = Arcs.nextIntersectingAngle(cx, cy, r, + Math.atan2(-dy0, dx0), beginBounds, angle < 0.0); + double angle1 = Arcs.nextIntersectingAngle(cx, cy, r, + Math.atan2(-dy1, dx1), endBounds, angle > 0.0); + + double dx = x-cx; + double dy = y-cy; + double dist = dx*dx + dy*dy; + +// System.out.println("HitTest: x0=" + x0 + " y0=" + y0 + " y=" + y + " x=" + x + " dist=" + dist + " r2=" + r*r); + + if(dist < (r+tolerance)*(r+tolerance) && + dist > (r-tolerance)*(r-tolerance)) { + double ang = Arcs.normalizeAngle(Math.atan2(-dy, dx)); +// System.out.println("test " + angle0 + " " + ang + " " + angle1); + if(Arcs.areClockwiseOrdered(angle0, ang, angle1) == clockWise) { +// System.out.println("hit"); + return true; + } + } + + return false; + + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Dependencies.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Dependencies.java new file mode 100644 index 00000000..0240ca8a --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Dependencies.java @@ -0,0 +1,227 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * 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 + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements2; + +import java.awt.Shape; +import java.awt.geom.Arc2D; +import java.awt.geom.Path2D; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.utils.datastructures.Pair; + +public class Dependencies { + + /* + * Total length of the arrow is ARROW_LENGTH1 + ARROW_LENGTH2 + */ + public static double ARROW_LENGTH1 = 0.2; + public static double ARROW_LENGTH2 = 1.0; + public static double ARROW_WIDTH = 0.5; + +// +// // Auxiliary +// double angle0; +// double angle1; +// double cx; +// double cy; +// double r; +// +// // Scene graph +// ShapeNode arcNode; +// FilledShapeNode arrowNode; +// +// public Dependencies() { +// } +// +// public Dependencies(Connectable tail, Connectable head) { +// super(); +// this.tail = tail; +// this.head = head; +// } +// +// @Override +// public void elementUpdated(IElement element) { +// update(); +// } +// +// @Override +// public void remove() { +// arcNode.remove(); +// arrowNode.remove(); +// tail.removeListener(this); +// head.removeListener(this); +// super.remove(); +// } +// +// @Override +// public void init(G2DParentNode parent) { +// tail.addListener(this); +// head.addListener(this); +// +// arcNode = parent.addNode(ShapeNode.class); +// arcNode.setScaleStroke(true); +// arcNode.setStroke(new BasicStroke(1)); +// arrowNode = parent.addNode(FilledShapeNode.class); +// update(); +// } +// + + private static Shape createArrow(double x, double y, double dx, double dy) { + Path2D path = new Path2D.Double(); + path.moveTo(x+ARROW_LENGTH1*dx, y+ARROW_LENGTH1*dy); + x -= ARROW_LENGTH2*dx; + y -= ARROW_LENGTH2*dy; + path.lineTo(x-ARROW_WIDTH*dy, y+ARROW_WIDTH*dx); + path.lineTo(x+ARROW_WIDTH*dy, y-ARROW_WIDTH*dx); + path.closePath(); + return path; + } + + public static Point2D computeCenter(Rectangle2D tail, Rectangle2D head, double angle) { + + double x0 = tail.getCenterX(); + double y0 = tail.getCenterY(); + double x1 = head.getCenterX(); + double y1 = head.getCenterY(); + +// System.out.println("createArrowShape " + x0 + " " + y0 + " " + x1 + " " + y1); + + double offset = + Math.abs(angle) < 1.0e-6 + ? 1e3 * Math.signum(angle) + : Math.tan(Math.PI*0.5-angle)*0.5; + + double cx = 0.5*(x0+x1) + offset * (y1-y0); + double cy = 0.5*(y0+y1) + offset * (x0-x1); + + return new Point2D.Double(cx, cy); + + } + + public static Pair createArrowShape(Rectangle2D tail, Rectangle2D head, double angle) { + + double x0 = tail.getCenterX(); + double y0 = tail.getCenterY(); + double x1 = head.getCenterX(); + double y1 = head.getCenterY(); + +// System.out.println("createArrowShape " + x0 + " " + y0 + " " + x1 + " " + y1); + + double offset = + Math.abs(angle) < 1.0e-6 + ? 1e3 * Math.signum(angle) + : Math.tan(Math.PI*0.5-angle)*0.5; + + double cx = 0.5*(x0+x1) + offset * (y1-y0); + double cy = 0.5*(y0+y1) + offset * (x0-x1); + double dx0 = x0 - cx; + double dy0 = y0 - cy; + double dx1 = x1 - cx; + double dy1 = y1 - cy; + + double r = Math.sqrt(dx0*dx0 + dy0*dy0); + +// Rectangle2D bounds = new Rectangle2D.Double(); +// tail.getBounds(bounds); + double angle0 = Arcs.nextIntersectingAngle(cx, cy, r, + Math.atan2(-dy0, dx0), tail, angle < 0.0); +// head.getBounds(bounds); + double angle1 = Arcs.nextIntersectingAngle(cx, cy, r, + Math.atan2(-dy1, dx1), head, angle > 0.0); + double extent = angle1-angle0; + //double arcAngle = angle0; + if(angle < 0.0) { + double temp = angle0; + angle0 = angle1; + angle1 = temp; + extent = -extent; + } + if(extent < 0) + extent += Math.PI*2.0; + else if(extent >= 360.0) + extent -= Math.PI*2.0; + Shape shape1 = new Arc2D.Double(cx-r, cy-r, 2*r, 2*r, + Math.toDegrees(angle0), + Math.toDegrees(extent), + Arc2D.OPEN); +// + double xx = Math.cos(angle > 0.0 ? angle1 : angle0); + double yy = -Math.sin(angle > 0.0 ? angle1 : angle0); + + Shape arrowShape = createArrow(cx + r*xx, cy + r*yy, + angle < 0.0 ? -yy : yy, + angle > 0.0 ? -xx : xx); + + return Pair.make(shape1, arrowShape); + + } +// +// public void update() { +// if(arcNode != null) +// updateSceneGraph(); +// fireElementUpdated(); +// } +// +// @Override +// public void getBounds(Rectangle2D bounds) { +// bounds.setFrame(arcNode.getBounds()); +// } +// +// @Override +// public boolean hitTest(double x, double y, double tolerance) { +// double dx = x-cx; +// double dy = y-cy; +// double dist = dx*dx + dy*dy; +// if(dist < (r+tolerance)*(r+tolerance) && +// dist > (r-tolerance)*(r-tolerance)) { +// double angle = Arcs.normalizeAngle(Math.atan2(-dy, dx)); +// if(Arcs.areClockwiseOrdered(angle0, angle, angle1)) +// return true; +// } +// return false; +// } +// +// class EventHandler extends DragEventHandler { +// @Override +// protected boolean begin(IDiagramEditor editor, DragEvent event) { +// return event.startModifiers.equals("left"); +// } +// +// @Override +// protected void update(IDiagramEditor editor, DragEvent event) { +// if(event == null) +// return; +// angle = Arcs.angleOfArc( +// tail.getOrigo().getX(), tail.getOrigo().getY(), +// event.current.getX(), event.current.getY(), +// head.getOrigo().getX(), head.getOrigo().getY() +// ); +// Dependencies.this.update(); +// editor.requestRepaint(); +// } +// } +// +// @SuppressWarnings("unchecked") +// @Override +// public T getInterface(Class clazz) { +// if(clazz == IEventHandler.class) +// return (T)new EventHandler(); +// return super.getInterface(clazz); +// } +// +// @Override +// public void elementRemoved(IElement element) { +// remove(); +// } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyConnectionFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyConnectionFactory.java index 8f699654..6be62fe2 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyConnectionFactory.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyConnectionFactory.java @@ -11,8 +11,15 @@ *******************************************************************************/ package org.simantics.sysdyn.ui.elements2; +import java.util.HashMap; +import java.util.concurrent.ConcurrentSkipListMap; +import java.util.concurrent.atomic.AtomicInteger; + +import org.simantics.databoard.binding.java.StringBindingDefault; import org.simantics.db.AsyncReadGraph; import org.simantics.db.Resource; +import org.simantics.db.Statement; +import org.simantics.db.procedure.AsyncMultiProcedure; import org.simantics.db.procedure.AsyncProcedure; import org.simantics.diagram.adapter.ElementFactoryAdapter; import org.simantics.diagram.stubs.DiagramResource; @@ -22,8 +29,8 @@ import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.element.ElementClass; import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; -import org.simantics.g2d.elementclass.connection.ConnectionClass; import org.simantics.g2d.routing.RouterFactory; +import org.simantics.utils.datastructures.Pair; /** * An element class for single connection entity elements. A connection entity @@ -45,16 +52,107 @@ public class DependencyConnectionFactory extends ElementFactoryAdapter { } @Override public void execute(AsyncReadGraph graph, Resource connectionType) { - procedure.execute(graph, ConnectionClass.CLASS.newClassWith(false, new StaticObjectAdapter(connectionType))); + procedure.execute(graph, SysdynConnectionClass.CLASS.newClassWith(false, new StaticObjectAdapter(connectionType))); } }); } @Override - public void load(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, Resource elementResource, + public void load(AsyncReadGraph graph, ICanvasContext canvas, IDiagram diagram, final Resource elementResource, final IElement element, final AsyncProcedure procedure) { + + final AtomicInteger ready = new AtomicInteger(1); + final ConcurrentSkipListMap> properties = new ConcurrentSkipListMap>(); + element.setHint(DiagramHints.ROUTE_ALGORITHM, RouterFactory.create(false, false)); - procedure.execute(graph, element); + + graph.forEachPredicate(elementResource, new AsyncMultiProcedure() { + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void execute(AsyncReadGraph graph, final Resource property) { + + ready.incrementAndGet(); + + graph.forIsSubrelationOf(property, graph.getBuiltins().HasProperty, new AsyncProcedure() { + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void execute(AsyncReadGraph graph, final Boolean isProperty) { + + if(isProperty) { + + graph.forPossibleRelatedValue(elementResource, property, new AsyncProcedure() { + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void execute(AsyncReadGraph graph, final Object value) { + + graph.forPossibleRelatedValue(property, graph.getBuiltins().HasName, StringBindingDefault.INSTANCE, new AsyncProcedure() { + + @Override + public void exception(AsyncReadGraph graph, Throwable throwable) { + throwable.printStackTrace(); + } + + @Override + public void execute(AsyncReadGraph graph, String name) { + + properties.put(name, Pair.make(property, value)); +// System.out.println("load properties " + name + " => " + value); + if(ready.decrementAndGet() == 0) { + element.setHint(DiagramHints.PROPERTIES, new HashMap>(properties)); + procedure.execute(graph, element); + } + + } + + }); + + } + + }); + + + } else { + + if(ready.decrementAndGet() == 0) { + element.setHint(DiagramHints.PROPERTIES, new HashMap>(properties)); + procedure.execute(graph, element); + } + + } + + } + + }); + + } + + @Override + public void finished(AsyncReadGraph graph) { + + if(ready.decrementAndGet() == 0) { + element.setHint(DiagramHints.PROPERTIES, new HashMap(properties)); + procedure.execute(graph, element); + } + + } + + }); + } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyEdgeClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyEdgeClass.java index 5a2d9a41..bfc0f5a0 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyEdgeClass.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyEdgeClass.java @@ -15,47 +15,69 @@ import java.awt.BasicStroke; import java.awt.Color; import java.awt.Shape; import java.awt.Stroke; -import java.awt.geom.AffineTransform; -import java.awt.geom.GeneralPath; import java.awt.geom.Path2D; -import java.awt.geom.PathIterator; -import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.Collection; - +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Map; + +import org.simantics.db.Resource; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.DiagramMutator; +import org.simantics.g2d.diagram.DiagramUtils; import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.diagram.handler.Topology; +import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy; import org.simantics.g2d.diagram.handler.Topology.Connection; import org.simantics.g2d.element.ElementClass; import org.simantics.g2d.element.ElementUtils; import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.SceneGraphNodeKey; -import org.simantics.g2d.element.handler.BendsHandler; import org.simantics.g2d.element.handler.EdgeVisuals; -import org.simantics.g2d.element.handler.EdgeVisuals.ArrowType; -import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd; -import org.simantics.g2d.element.handler.Rotate; +import org.simantics.g2d.element.handler.Pick; import org.simantics.g2d.element.handler.SceneGraph; import org.simantics.g2d.element.handler.TerminalLayout; +import org.simantics.g2d.element.handler.Transform; +import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd; import org.simantics.g2d.element.handler.impl.ConfigurableEdgeVisuals; import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline; import org.simantics.g2d.element.handler.impl.FillColorImpl; import org.simantics.g2d.element.handler.impl.ParentImpl; -import org.simantics.g2d.element.handler.impl.ShapePick; import org.simantics.g2d.element.handler.impl.SimpleElementLayers; -import org.simantics.g2d.elementclass.BranchPoint; import org.simantics.g2d.elementclass.connection.EdgeClass.EdgeHandler; import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform; -import org.simantics.g2d.utils.PathUtils; import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.utils.datastructures.Callback; +import org.simantics.utils.datastructures.Pair; import org.simantics.utils.datastructures.hints.IHintContext.Key; -/** - * @author Toni Kalajainen - */ public class DependencyEdgeClass { + public static class NodePick implements Pick { + + private static final long serialVersionUID = 1L; + + @Override + public boolean pickTest(IElement e, Shape s, PickPolicy policy) { + Rectangle2D pickRect = null; + if (s instanceof Rectangle2D) + pickRect = (Rectangle2D) s; + else + // FIXME: suboptimal, but works. + pickRect = s.getBounds2D(); + + DependencyNode node = e.getHint(SysdynEdgeSceneGraph.KEY_SG_NODE); + if(node == null) { + System.out.println("pickTest no node!"); + return false; + } + + return Arcs.hitTest(node.beginBounds, node.endBounds, node.angle, pickRect.getCenterX(), pickRect.getCenterY(), 3.0); + + } + + } + // TODO scale, rotate, move, transform public static final ElementClass CLASS = ElementClass.compile( @@ -64,7 +86,7 @@ public class DependencyEdgeClass { ConfigurableEdgeVisuals.DEFAULT, FillColorImpl.BLACK, FixedTransform.INSTANCE, - ShapePick.INSTANCE, + new NodePick(), ConnectionSelectionOutline.INSTANCE, SimpleElementLayers.INSTANCE, ParentImpl.INSTANCE @@ -90,23 +112,42 @@ public class DependencyEdgeClass { public void cleanup(IElement e) { ElementUtils.removePossibleNode(e, KEY_SG_NODE); } - + public void update(final IElement e) { + DependencyNode node = e.getHint(KEY_SG_NODE); if(node == null) return; + + final IDiagram diagram = ElementUtils.peekDiagram(e); + + node.setFieldListener(new PropertyChangeListener() { + + @Override + public void propertyChange(final PropertyChangeEvent event) { + + String field = event.getPropertyName(); + Map> properties = e.getHint(DiagramHints.PROPERTIES); + if(properties == null) return; + final Pair property = properties.get(field); + if(property == null) return; + + DiagramUtils.mutateDiagram(diagram, new Callback() { + + @Override + public void run(DiagramMutator mutator) { + mutator.modifyProperty(e, property.first, event.getNewValue()); + } + + }); + + } + + }); EdgeVisuals vh = e.getElementClass().getSingleItem(EdgeVisuals.class); - ArrowType at1 = vh.getArrowType(e, EdgeEnd.Begin); - ArrowType at2 = vh.getArrowType(e, EdgeEnd.End); Stroke stroke = vh.getStroke(e); - //StrokeType strokeType = vh.getStrokeType(e); - double as1 = vh.getArrowSize(e, EdgeEnd.Begin); - double as2 = vh.getArrowSize(e, EdgeEnd.End); - Color c = ElementUtils.getFillColor(e, Color.BLACK); - // Get terminal shape for clipping the painted edge to its bounds. - IDiagram diagram = ElementUtils.peekDiagram(e); Shape beginTerminalShape = null; Shape endTerminalShape = null; if (diagram != null) { @@ -114,82 +155,51 @@ public class DependencyEdgeClass { if (topology != null) { Connection beginConnection = topology.getConnection(e, EdgeEnd.Begin); Connection endConnection = topology.getConnection(e, EdgeEnd.End); - beginTerminalShape = getTerminalShape(beginConnection); - endTerminalShape = getTerminalShape(endConnection); - int beginBranchDegree = getBranchPointDegree(beginConnection, topology); - int endBranchDegree = getBranchPointDegree(endConnection, topology); - if (beginBranchDegree > 0 && beginBranchDegree < 3) { - at1 = ArrowType.None; - } - if (endBranchDegree > 0 && endBranchDegree < 3) { - at2 = ArrowType.None; - } + beginTerminalShape = getCanvasTerminalShape(beginConnection); + endTerminalShape = getCanvasTerminalShape(endConnection); } } - - // Read bends - BendsHandler bh = e.getElementClass().getSingleItem(BendsHandler.class); - Path2D line = bh.getPath(e); - boolean drawArrows = at1 != ArrowType.None || at2 != ArrowType.None; - //line = clipLineEnds(line, beginTerminalShape, endTerminalShape); - - Point2D first = new Point2D.Double(); - Point2D dir1 = new Point2D.Double(); - Point2D last = new Point2D.Double(); - Point2D dir2 = new Point2D.Double(); - PathIterator pi = line.getPathIterator(null); - drawArrows &= PathUtils.getPathArrows(pi, first, dir1, last, dir2); - - DependencyNode.ArrowType pat1 = convert(at1); - DependencyNode.ArrowType pat2 = convert(at2); - - node.init(new GeneralPath(line), stroke, c, dir1, dir2, first, last, as1, as2, pat1, pat2, null, null); - } - - private static DependencyNode.ArrowType convert(ArrowType at) { - switch (at) { - case None: return DependencyNode.ArrowType.None; - case Stroke: return DependencyNode.ArrowType.Stroke; - case Fill: return DependencyNode.ArrowType.Fill; - default: - throw new IllegalArgumentException("unsupported arrow type: " + at); + if(beginTerminalShape == null || endTerminalShape == null) return; + + node.setProperty("beginBounds", beginTerminalShape.getBounds2D()); + node.setProperty("endBounds", endTerminalShape.getBounds2D()); + node.setProperty("stroke", stroke); + node.setProperty("color", c); + node.setProperty("angle", 0.1); + + Map> properties = e.getHint(DiagramHints.PROPERTIES); + if(properties != null) { + for(Map.Entry> entry : properties.entrySet()) { + node.setProperty(entry.getKey(), entry.getValue().second); +// System.out.println("setProperty " + entry.getKey() + " => " + entry.getValue().second); + } } - } + + Pair shapes = Dependencies.createArrowShape(beginTerminalShape.getBounds2D(), endTerminalShape.getBounds2D(), node.angle); + EdgeHandler eh = e.getElementClass().getAtMostOneItemOfClass(EdgeHandler.class); + Path2D path = new Path2D.Double(shapes.first); + eh.setPath(e, path); - private static final Rectangle2D EMPTY = new Rectangle2D.Double(); + } - private static Shape getTerminalShape(Connection connection) { + private static Shape getCanvasTerminalShape(Connection connection) { if (connection != null && connection.node != null && connection.terminal != null) { TerminalLayout layout = connection.node.getElementClass().getAtMostOneItemOfClass(TerminalLayout.class); if (layout != null) { //return layout.getTerminalShape(connection.node, connection.terminal); Shape shp = layout.getTerminalShape(connection.node, connection.terminal); - Rotate rotate = connection.node.getElementClass().getAtMostOneItemOfClass(Rotate.class); - if (rotate == null) + Transform tr = connection.node.getElementClass().getAtMostOneItemOfClass(Transform.class); + if (tr == null) return shp; - double theta = rotate.getAngle(connection.node); - return AffineTransform.getRotateInstance(theta).createTransformedShape(shp); + return tr.getTransform(connection.node).createTransformedShape(shp); + } } return null; } - private final Collection connectionsTemp = new ArrayList(); - private int getBranchPointDegree(Connection connection, Topology topology) { - if (connection != null && connection.node != null) { - if (connection.node.getElementClass().containsClass(BranchPoint.class)) { - connectionsTemp.clear(); - topology.getConnections(connection.node, connection.terminal, connectionsTemp); - int degree = connectionsTemp.size(); - connectionsTemp.clear(); - return degree; - } - } - return -1; - } - } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyNode.java index 3584f169..a99bd6ad 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyNode.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/DependencyNode.java @@ -1,182 +1,96 @@ package org.simantics.sysdyn.ui.elements2; -import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; -import java.awt.Composite; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; -import java.awt.geom.AffineTransform; -import java.awt.geom.GeneralPath; -import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; -import org.simantics.scenegraph.g2d.G2DNode; -public class DependencyNode extends G2DNode { +import org.simantics.scenegraph.ISelectionPainterNode; +import org.simantics.scenegraph.g2d.events.SGMouseEvent; +import org.simantics.scenegraph.utils.NodeUtil; +import org.simantics.utils.datastructures.Pair; - private static final long serialVersionUID = 1294351381209071074L; - - public static enum ArrowType { None, Stroke, Fill, Both } - - protected Color color = null; - protected Stroke stroke = null; - protected Shape shape = null; - protected Point2D firstdir = null; - protected Point2D lastdir = null; - protected Point2D first = null; - protected Point2D last = null; - protected double firstsize = 0; - protected double lastsize = 0; - protected ArrowType first_at = null; - protected ArrowType last_at = null; - protected Shape firstShape = null; - protected Shape lastShape = null; - - private transient Rectangle2D bounds; - - @SyncField({"color", "stroke", "shape", "firstdir", "lastdir", "first", "last", "firstsize", "lastsize", "first_at", "last_at"}) - public void init(Shape shape, Stroke stroke, Color color, Point2D firstdir, Point2D lastdir, Point2D first, Point2D last, double firstsize, double lastsize, ArrowType first_at, ArrowType last_at, Shape firstShape, Shape lastShape) { - this.color = color; - this.stroke = stroke; - this.shape = shape; - this.firstdir = firstdir; - this.lastdir = lastdir; - this.first = first; - this.last = last; - this.firstsize = firstsize; - this.lastsize = lastsize; - this.first_at = first_at; - this.last_at = last_at; - this.firstShape = firstShape; - this.lastShape = lastShape; +public class DependencyNode extends GraphPropertyNode implements ISelectionPainterNode { - if (shape != null) { - this.bounds = shape.getBounds2D(); - } - } + private static final long serialVersionUID = 1294351381209071074L; + public Color color; + public Stroke stroke; + public Rectangle2D beginBounds; + public Rectangle2D endBounds; + public double angle = 0.1; + + transient public boolean hover = false; + @Override public void render(Graphics2D g) { - if(color != null) g.setColor(color); - if(stroke == null || shape == null) return; - - if(alphaComposite != null) { - g.setComposite(alphaComposite); - } - - Stroke effectiveStroke = stroke; - if(dynamicStroke != null) { - effectiveStroke = dynamicStroke; - } - - Color effectiveColor = color; - if(dynamicColor != null) { - effectiveColor = dynamicColor; - } - - g.setStroke(effectiveStroke); // NICENESS g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - //g.draw(shape); - - // Draw line "halo" - float f = 0.1f * 3f; - Color background = Color.WHITE; // FIXME - g.setColor(background); - g.setStroke(new BasicStroke(f)); - g.draw(shape); - - // Draw line - g.setColor(effectiveColor); - g.setStroke(effectiveStroke); - g.draw(shape); - - // Draw line ends if necessary. - boolean drawArrows = first_at != ArrowType.None || last_at != ArrowType.None; - if (!drawArrows) - return; - - g.setStroke(ARROW_STROKE); - AffineTransform at = g.getTransform(); - - double theta = Math.atan2(firstdir.getY(), firstdir.getX()) - Math.PI/2; - g.translate(first.getX(), first.getY()); - g.rotate(theta); - g.scale(firstsize, firstsize); - - if (first_at == ArrowType.Fill) - g.fill(FILLED_ARROW); - else if (first_at == ArrowType.Stroke) - g.draw(NORMAL_ARROW); - - g.setTransform(at); - - theta = Math.atan2(lastdir.getY(), lastdir.getX()) - Math.PI/2; - - g.translate(last.getX(), last.getY()); - g.rotate(theta); - g.scale(lastsize, lastsize); - - if (last_at == ArrowType.Fill) - g.fill(FILLED_ARROW); - else if (last_at == ArrowType.Stroke) - g.draw(NORMAL_ARROW); - } - - - public transient final static GeneralPath NORMAL_ARROW; - public transient final static GeneralPath FILLED_ARROW; - public transient static final Stroke ARROW_STROKE = new BasicStroke(1.0f); - - static { - FILLED_ARROW = new GeneralPath(); - FILLED_ARROW.moveTo(-0.5f, 1f); - FILLED_ARROW.lineTo( 0f, 0f); - FILLED_ARROW.lineTo( 0.5f, 1f); - FILLED_ARROW.closePath(); +// System.out.println("dep " + angle + " " + beginBounds + " " + endBounds); + + Pair shapes = Dependencies.createArrowShape(beginBounds, endBounds, angle); + + boolean selected = NodeUtil.isSelected(this, 2); + if(selected) { + g.setColor(Color.PINK); + g.setStroke(new BasicStroke(1.0f)); + g.draw(shapes.first); + g.fill(shapes.second); + if(color != null) g.setColor(color); + g.setStroke(stroke); + g.draw(shapes.first); + g.fill(shapes.second); + } else if (hover){ + g.setColor(Color.LIGHT_GRAY); + g.setStroke(new BasicStroke(1.0f)); + g.draw(shapes.first); + g.fill(shapes.second); + if(color != null) g.setColor(color); + g.setStroke(stroke); + g.draw(shapes.first); + g.fill(shapes.second); + } else { + if(color != null) g.setColor(color); + if(stroke != null) g.setStroke(stroke); + g.draw(shapes.first); + g.fill(shapes.second); + } - NORMAL_ARROW = new GeneralPath(); - NORMAL_ARROW.moveTo(-0.5f, 1f); - NORMAL_ARROW.lineTo( 0f, 0f); - NORMAL_ARROW.lineTo( 0.5f, 1f); } @Override - public Rectangle2D getBoundsInLocal() { - return bounds; - } - - protected Composite alphaComposite = null; - protected Stroke dynamicStroke = null; - protected Color dynamicColor = null; - + public boolean hitTest(double x, double y, double tolerance) { + return Arcs.hitTest(beginBounds, endBounds, angle, x, y, tolerance); + } + @Override - public void setValue(String key, Object value) { - - if ("alpha".equals(key)) { - Float val = Float.parseFloat((String)value); - alphaComposite = AlphaComposite.getInstance(AlphaComposite. SRC_OVER, val); - } else if ("width".equals(key)) { - dynamicStroke = new BasicStroke(((Double)value).floatValue()); - } else if ("color".equals(key)) { - try { - dynamicColor = new Color(Integer.parseInt(value.toString(), 16)); - } catch (Throwable t) { - t.printStackTrace(); - } - } - } - + public void mouseDragged(SGMouseEvent event, boolean pressHit, boolean currentHit) { + + if(!pressHit) return; + + angle = Arcs.angleOfArc( + beginBounds.getCenterX(), beginBounds.getCenterY(), + event.getDoubleX(), event.getDoubleY(), + endBounds.getCenterX(), endBounds.getCenterY()); + + } + @Override - public void initValues() { - dynamicStroke = null; - dynamicColor = null; - alphaComposite = null; + public void mouseReleased(SGMouseEvent event, boolean hit) { + if(hit) commitProperty("angle", angle); + } + + @Override + public void mouseMoved(SGMouseEvent event, boolean hit) { + if(hit != hover) { + hover = hit; + repaint(); + } } - } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowEdgeClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowEdgeClass.java index 9e6f4771..dbe63010 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowEdgeClass.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowEdgeClass.java @@ -15,15 +15,14 @@ import java.awt.BasicStroke; import java.awt.Color; import java.awt.Shape; import java.awt.Stroke; -import java.awt.geom.AffineTransform; -import java.awt.geom.GeneralPath; -import java.awt.geom.Path2D; -import java.awt.geom.PathIterator; -import java.awt.geom.Point2D; -import java.awt.geom.Rectangle2D; -import java.util.ArrayList; -import java.util.Collection; - +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Map; + +import org.simantics.db.Resource; +import org.simantics.g2d.diagram.DiagramHints; +import org.simantics.g2d.diagram.DiagramMutator; +import org.simantics.g2d.diagram.DiagramUtils; import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.diagram.handler.Topology; import org.simantics.g2d.diagram.handler.Topology.Connection; @@ -31,24 +30,23 @@ import org.simantics.g2d.element.ElementClass; import org.simantics.g2d.element.ElementUtils; import org.simantics.g2d.element.IElement; import org.simantics.g2d.element.SceneGraphNodeKey; -import org.simantics.g2d.element.handler.BendsHandler; -import org.simantics.g2d.element.handler.EdgeVisuals; -import org.simantics.g2d.element.handler.EdgeVisuals.ArrowType; -import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd; -import org.simantics.g2d.element.handler.Rotate; import org.simantics.g2d.element.handler.SceneGraph; import org.simantics.g2d.element.handler.TerminalLayout; +import org.simantics.g2d.element.handler.Transform; +import org.simantics.g2d.element.handler.EdgeVisuals.EdgeEnd; import org.simantics.g2d.element.handler.impl.ConfigurableEdgeVisuals; import org.simantics.g2d.element.handler.impl.ConnectionSelectionOutline; import org.simantics.g2d.element.handler.impl.FillColorImpl; import org.simantics.g2d.element.handler.impl.ParentImpl; import org.simantics.g2d.element.handler.impl.ShapePick; import org.simantics.g2d.element.handler.impl.SimpleElementLayers; -import org.simantics.g2d.elementclass.BranchPoint; import org.simantics.g2d.elementclass.connection.EdgeClass.EdgeHandler; import org.simantics.g2d.elementclass.connection.EdgeClass.FixedTransform; -import org.simantics.g2d.utils.PathUtils; +import org.simantics.g2d.elementclass.valve.ValveClass.ValveHandle; import org.simantics.scenegraph.g2d.G2DParentNode; +import org.simantics.sysdyn.ui.elements2.ValveFactory.ValveSceneGraph; +import org.simantics.utils.datastructures.Callback; +import org.simantics.utils.datastructures.Pair; import org.simantics.utils.datastructures.hints.IHintContext.Key; /** @@ -92,107 +90,90 @@ public class FlowEdgeClass { } public void update(final IElement e) { + FlowNode node = e.getHint(KEY_SG_NODE); if(node == null) return; - EdgeVisuals vh = e.getElementClass().getSingleItem(EdgeVisuals.class); - ArrowType at1 = vh.getArrowType(e, EdgeEnd.Begin); - ArrowType at2 = vh.getArrowType(e, EdgeEnd.End); - Stroke stroke = new FlowStroke( - new BasicStroke(0.4f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER), - new BasicStroke(0.1f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER)); -// Stroke stroke = vh.getStroke(e); - //StrokeType strokeType = vh.getStrokeType(e); - double as1 = vh.getArrowSize(e, EdgeEnd.Begin); - double as2 = vh.getArrowSize(e, EdgeEnd.End); - + final IDiagram diagram = ElementUtils.peekDiagram(e); + + node.setFieldListener(new PropertyChangeListener() { + + @Override + public void propertyChange(final PropertyChangeEvent event) { + + DiagramUtils.mutateDiagram(diagram, new Callback() { + + @Override + public void run(DiagramMutator mutator) { + + String field = event.getPropertyName(); + Map> properties = e.getHint(DiagramHints.PROPERTIES); + Pair property = properties.get(field); + + mutator.modifyProperty(e, property.first, event.getNewValue()); + + } + + }); + + } + + }); + + Stroke stroke = new BasicStroke(0.1f); Color c = ElementUtils.getFillColor(e, Color.BLACK); - // Get terminal shape for clipping the painted edge to its bounds. - IDiagram diagram = ElementUtils.peekDiagram(e); Shape beginTerminalShape = null; Shape endTerminalShape = null; + boolean toValve = false; if (diagram != null) { Topology topology = diagram.getDiagramClass().getAtMostOneItemOfClass(Topology.class); if (topology != null) { Connection beginConnection = topology.getConnection(e, EdgeEnd.Begin); Connection endConnection = topology.getConnection(e, EdgeEnd.End); - beginTerminalShape = getTerminalShape(beginConnection); - endTerminalShape = getTerminalShape(endConnection); - int beginBranchDegree = getBranchPointDegree(beginConnection, topology); - int endBranchDegree = getBranchPointDegree(endConnection, topology); - if (beginBranchDegree > 0 && beginBranchDegree < 3) { - at1 = ArrowType.None; - } - if (endBranchDegree > 0 && endBranchDegree < 3) { - at2 = ArrowType.None; - } + beginTerminalShape = getCanvasTerminalShape(beginConnection); + endTerminalShape = getCanvasTerminalShape(endConnection); + toValve = endConnection.node.getElementClass().containsClass(ValveSceneGraph.class); +// System.out.println("end connection class = " + endConnection.node.getElementClass()); } } - // Read bends - BendsHandler bh = e.getElementClass().getSingleItem(BendsHandler.class); - Path2D line = bh.getPath(e); + if(beginTerminalShape == null || endTerminalShape == null) return; - boolean drawArrows = at1 != ArrowType.None || at2 != ArrowType.None; - //line = clipLineEnds(line, beginTerminalShape, endTerminalShape); - - Point2D first = new Point2D.Double(); - Point2D dir1 = new Point2D.Double(); - Point2D last = new Point2D.Double(); - Point2D dir2 = new Point2D.Double(); - PathIterator pi = line.getPathIterator(null); - drawArrows &= PathUtils.getPathArrows(pi, first, dir1, last, dir2); - - FlowNode.ArrowType pat1 = convert(at1); - FlowNode.ArrowType pat2 = convert(at2); - - node.init(new GeneralPath(line), stroke, c, dir1, dir2, first, last, as1, as2, pat1, pat2, null, null); - } - - private static FlowNode.ArrowType convert(ArrowType at) { - switch (at) { - case None: return FlowNode.ArrowType.None; - case Stroke: return FlowNode.ArrowType.Stroke; - case Fill: return FlowNode.ArrowType.Fill; - default: - throw new IllegalArgumentException("unsupported arrow type: " + at); + node.setProperty("beginBounds", beginTerminalShape.getBounds2D()); + node.setProperty("endBounds", endTerminalShape.getBounds2D()); + node.setProperty("stroke", stroke); + node.setProperty("color", c); + node.setProperty("toValve", toValve); +// System.out.println("set toValve = " + toValve); + node.toValve = toValve; + + Map> properties = e.getHint(DiagramHints.PROPERTIES); + if(properties != null) { + for(Map.Entry> entry : properties.entrySet()) { + node.setProperty(entry.getKey(), entry.getValue().second); + } } + } - private static final Rectangle2D EMPTY = new Rectangle2D.Double(); - - private static Shape getTerminalShape(Connection connection) { + private static Shape getCanvasTerminalShape(Connection connection) { if (connection != null && connection.node != null && connection.terminal != null) { TerminalLayout layout = connection.node.getElementClass().getAtMostOneItemOfClass(TerminalLayout.class); if (layout != null) { //return layout.getTerminalShape(connection.node, connection.terminal); Shape shp = layout.getTerminalShape(connection.node, connection.terminal); - Rotate rotate = connection.node.getElementClass().getAtMostOneItemOfClass(Rotate.class); - if (rotate == null) + Transform tr = connection.node.getElementClass().getAtMostOneItemOfClass(Transform.class); + if (tr == null) return shp; - double theta = rotate.getAngle(connection.node); - return AffineTransform.getRotateInstance(theta).createTransformedShape(shp); + return tr.getTransform(connection.node).createTransformedShape(shp); + } } return null; } - private final Collection connectionsTemp = new ArrayList(); - private int getBranchPointDegree(Connection connection, Topology topology) { - if (connection != null && connection.node != null) { - if (connection.node.getElementClass().containsClass(BranchPoint.class)) { - connectionsTemp.clear(); - topology.getConnections(connection.node, connection.terminal, connectionsTemp); - int degree = connectionsTemp.size(); - connectionsTemp.clear(); - return degree; - } - } - return -1; - } - } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowNode.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowNode.java index 5bfb68d6..f610330d 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowNode.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/FlowNode.java @@ -1,182 +1,75 @@ package org.simantics.sysdyn.ui.elements2; -import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.Color; -import java.awt.Composite; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; -import java.awt.geom.AffineTransform; -import java.awt.geom.GeneralPath; -import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; -import org.simantics.scenegraph.g2d.G2DNode; -public class FlowNode extends G2DNode { +import org.simantics.scenegraph.ISelectionPainterNode; +import org.simantics.scenegraph.utils.NodeUtil; +import org.simantics.utils.datastructures.Pair; - private static final long serialVersionUID = 1294351381209071074L; - - public static enum ArrowType { None, Stroke, Fill, Both } - - protected Color color = null; - protected Stroke stroke = null; - protected Shape shape = null; - protected Point2D firstdir = null; - protected Point2D lastdir = null; - protected Point2D first = null; - protected Point2D last = null; - protected double firstsize = 0; - protected double lastsize = 0; - protected ArrowType first_at = null; - protected ArrowType last_at = null; - protected Shape firstShape = null; - protected Shape lastShape = null; - - private transient Rectangle2D bounds; - - @SyncField({"color", "stroke", "shape", "firstdir", "lastdir", "first", "last", "firstsize", "lastsize", "first_at", "last_at"}) - public void init(Shape shape, Stroke stroke, Color color, Point2D firstdir, Point2D lastdir, Point2D first, Point2D last, double firstsize, double lastsize, ArrowType first_at, ArrowType last_at, Shape firstShape, Shape lastShape) { - this.color = color; - this.stroke = stroke; - this.shape = shape; - this.firstdir = firstdir; - this.lastdir = lastdir; - this.first = first; - this.last = last; - this.firstsize = firstsize; - this.lastsize = lastsize; - this.first_at = first_at; - this.last_at = last_at; - this.firstShape = firstShape; - this.lastShape = lastShape; - - if (shape != null) { - this.bounds = shape.getBounds2D(); - } - } +public class FlowNode extends GraphPropertyNode implements ISelectionPainterNode { + private static final long serialVersionUID = 328942356917631237L; + + public Color color; + public Stroke stroke; + public Rectangle2D beginBounds; + public Rectangle2D endBounds; + public Boolean toValve; + @Override public void render(Graphics2D g) { - if(color != null) g.setColor(color); - if(stroke == null || shape == null) return; - - if(alphaComposite != null) { - g.setComposite(alphaComposite); - } - - Stroke effectiveStroke = stroke; - if(dynamicStroke != null) { - effectiveStroke = dynamicStroke; - } - - Color effectiveColor = color; - if(dynamicColor != null) { - effectiveColor = dynamicColor; - } - - g.setStroke(effectiveStroke); - + // NICENESS g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - //g.draw(shape); - - // Draw line "halo" - float f = 0.1f * 3f; - Color background = Color.WHITE; // FIXME - g.setColor(background); - g.setStroke(new BasicStroke(f)); - g.draw(shape); - - // Draw line - g.setColor(effectiveColor); - g.setStroke(effectiveStroke); - g.draw(shape); - - // Draw line ends if necessary. - boolean drawArrows = first_at != ArrowType.None || last_at != ArrowType.None; - if (!drawArrows) - return; - - g.setStroke(ARROW_STROKE); - AffineTransform at = g.getTransform(); - - double theta = Math.atan2(firstdir.getY(), firstdir.getX()) - Math.PI/2; - g.translate(first.getX(), first.getY()); - g.rotate(theta); - g.scale(firstsize, firstsize); - - if (first_at == ArrowType.Fill) - g.fill(FILLED_ARROW); - else if (first_at == ArrowType.Stroke) - g.draw(NORMAL_ARROW); - - g.setTransform(at); - - theta = Math.atan2(lastdir.getY(), lastdir.getX()) - Math.PI/2; - - g.translate(last.getX(), last.getY()); - g.rotate(theta); - g.scale(lastsize, lastsize); - - if (last_at == ArrowType.Fill) - g.fill(FILLED_ARROW); - else if (last_at == ArrowType.Stroke) - g.draw(NORMAL_ARROW); - } - - - public transient final static GeneralPath NORMAL_ARROW; - public transient final static GeneralPath FILLED_ARROW; - public transient static final Stroke ARROW_STROKE = new BasicStroke(1.0f); - - static { - FILLED_ARROW = new GeneralPath(); - FILLED_ARROW.moveTo(-0.5f, 1f); - FILLED_ARROW.lineTo( 0f, 0f); - FILLED_ARROW.lineTo( 0.5f, 1f); - FILLED_ARROW.closePath(); - - NORMAL_ARROW = new GeneralPath(); - NORMAL_ARROW.moveTo(-0.5f, 1f); - NORMAL_ARROW.lineTo( 0f, 0f); - NORMAL_ARROW.lineTo( 0.5f, 1f); - } - - @Override - public Rectangle2D getBoundsInLocal() { - return bounds; - } + /* + * There are two cases, first is from Stock|Cloud to Valve and second is from Valve to Stock|Cloud + * -In the first case there is no arrow and valve is endBounds + * -In the second case there is an arrow and valve is beginBounds + */ + + Pair lines = null; + Shape arrow = null; - protected Composite alphaComposite = null; - protected Stroke dynamicStroke = null; - protected Color dynamicColor = null; +// System.out.println("FlowNode.render toValve = " + toValve); + + if(toValve) { + + lines = Flows.createLines(false, endBounds, beginBounds); - @Override - public void setValue(String key, Object value) { + } else { - if ("alpha".equals(key)) { - Float val = Float.parseFloat((String)value); - alphaComposite = AlphaComposite.getInstance(AlphaComposite. SRC_OVER, val); - } else if ("width".equals(key)) { - dynamicStroke = new BasicStroke(((Double)value).floatValue()); - } else if ("color".equals(key)) { - try { - dynamicColor = new Color(Integer.parseInt(value.toString(), 16)); - } catch (Throwable t) { - t.printStackTrace(); - } + lines = Flows.createLines(true, beginBounds, endBounds); + arrow = Flows.createArrow(beginBounds, endBounds); + } + + boolean selected = NodeUtil.isSelected(this, 2); + if(selected) { + g.setColor(Color.PINK); + g.setStroke(new BasicStroke(1.0f)); + g.draw(lines.first); + g.draw(lines.second); + if(color != null) g.setColor(color); + g.setStroke(stroke); + g.draw(lines.first); + g.draw(lines.second); + if(arrow != null) g.fill(arrow); + } else { + if(color != null) g.setColor(color); + if(stroke != null) g.setStroke(stroke); + g.draw(lines.first); + g.draw(lines.second); + if(arrow != null) g.fill(arrow); + } + + } - @Override - public void initValues() { - dynamicStroke = null; - dynamicColor = null; - alphaComposite = null; - } - - } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Flows.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Flows.java new file mode 100644 index 00000000..af6bf2dc --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/Flows.java @@ -0,0 +1,175 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * 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 + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements2; + +import java.awt.Shape; +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; + +import org.simantics.utils.datastructures.Pair; + +public class Flows { + + public static double ARROW_LENGTH = 3.2; + public static double ARROW_WIDTH = 2; + + static final double OFFSET = 1.0; + static final double ARROW_OFFSET = 3.2; + + public static Path2D createArrow(Rectangle2D tail, Rectangle2D head) { + + double x = tail.getCenterX(); + double y = tail.getCenterY(); + +// Rectangle2D rect = new Rectangle2D.Double(); +// head.getBounds(rect); + double cx = head.getCenterX(); + double minx = head.getMinX(); + double maxx = head.getMaxX(); + double miny = head.getMinY(); + double maxy = head.getMaxY(); + + Path2D path = new Path2D.Double(); + + // approach from top + if (y < miny) { + path.moveTo(cx, miny); + path.lineTo(cx + ARROW_WIDTH, miny - ARROW_LENGTH); + path.lineTo(cx - ARROW_WIDTH, miny - ARROW_LENGTH); + } + + // approach from beneath + else if (y > maxy) { + path.moveTo(cx, maxy); + path.lineTo(cx + ARROW_WIDTH, maxy + ARROW_LENGTH); + path.lineTo(cx - ARROW_WIDTH, maxy + ARROW_LENGTH); + } + + // approach from left + else if (x < minx) { + path.moveTo(minx, y); + path.lineTo(minx - ARROW_LENGTH, y - ARROW_WIDTH); + path.lineTo(minx - ARROW_LENGTH, y + ARROW_WIDTH); + } + + // approach from right + else if (x > maxx) { + path.moveTo(maxx, y); + path.lineTo(maxx + ARROW_LENGTH, y - ARROW_WIDTH); + path.lineTo(maxx + ARROW_LENGTH, y + ARROW_WIDTH); + } + else + return null; // FIXME (HN) This is just a quick bugfix, didn't understand the logic completely + + path.closePath(); + + return path; + + } + + private static Pair createLines(boolean vertical, double ... coordinates) { + +// lineNode1.setShape(createOffsetLine(vertical, OFFSET, coordinates)); +// lineNode2.setShape(createOffsetLine(vertical, -OFFSET, coordinates)); + return new Pair(createOffsetLine(vertical, OFFSET, coordinates), Flows.createOffsetLine(vertical, -OFFSET, coordinates)); + + } + + public static Pair createLines(boolean hasArrow, Rectangle2D valve, Rectangle2D node) { + + double x0 = valve.getCenterX(); + double y0 = valve.getCenterY(); + double x1 = node.getCenterX(); + double y1 = node.getCenterY(); + +// System.out.println("FlowNode " + x0 + " " + y0 + " x1 " + x1 + " y1 " + y1); + +// Rectangle2D rect = new Rectangle2D.Double(); +// node.getBounds(rect); + + double minY = hasArrow ? node.getMinY() - ARROW_OFFSET : node.getMinY(); + double maxY = hasArrow ? node.getMaxY() + ARROW_OFFSET : node.getMaxY(); + double minX = hasArrow ? node.getMinX() - ARROW_OFFSET : node.getMinX(); + double maxX = hasArrow ? node.getMaxX() + ARROW_OFFSET : node.getMaxX(); + +// boolean rotated = ((ValveElement)valve).rotated; + boolean rotated = false; + + if( rotated ) { + if(y1 > y0) + y0 += OFFSET; + else + y0 -= OFFSET; + if(node.getMinX() <= x0 && node.getMaxX() >= x0) { + if(y1 > y0) + return createLines(true, y0, x0, minY); + else + return createLines(true, y0, x0, maxY); + } + else { + if(x1 > x0) + return createLines(true, y0, x0, y1, minX); + else + return createLines(true, y0, x0, y1, maxX); + } + } + else { + if(x1 > x0) + x0 += OFFSET; + else + x0 -= OFFSET; + if(node.getMinY() <= y0 && node.getMaxY() >= y0) { + if(x1 > x0) + return createLines(false, x0, y0, minX); + else + return createLines(false, x0, y0, maxX); + } + else { + if(y1 > y0) + return createLines(false, x0, y0, x1, minY); + else + return createLines(false, x0, y0, x1, maxY); + } + } + + + } + + public static Path2D createLine(boolean vertical, double ... coordinates) { + Path2D path = new Path2D.Double(); + if(vertical) + path.moveTo(coordinates[1], coordinates[0]); + else + path.moveTo(coordinates[0], coordinates[1]); + for(int i=2;i fields = new HashMap(); + + private PropertyChangeListener fieldListener = null; + + GraphPropertyNode() { + for(Field f : getClass().getFields()) { +// System.out.println("register field '" + f.getName() + "'"); + fields.put(f.getName(), f); + } + } + + public void setFieldListener(PropertyChangeListener listener) { + this.fieldListener = listener; + } + + public void propertyChange(String field, Object value) { + } + + public void setProperty(String field, Object value) { + Field f = fields.get(field); + if(f == null) { + System.err.println("GraphPropertyNode tried to set undefined property '" + field + "'"); + return; + } + try { + //System.out.println("setting field '" + field + "'"); + f.set(this, value); + propertyChange(field, value); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + public void commitProperty(String field, Object value) { + if(fieldListener != null) { + fieldListener.propertyChange(new PropertyChangeEvent(this, field, null, value)); + } + } + + boolean pressHit = false; + + public boolean hitTest(double x, double y, double tolerance) { + return false; + } + + @Override + public void handleEvent(AWTEvent event) { + if(event instanceof SGMouseEvent) { + SGMouseEvent e = (SGMouseEvent)event; + boolean hit = hitTest(e.getDoubleX(), e.getDoubleY(), 3.0); + if(e.getID() == MouseEvent.MOUSE_DRAGGED) { + mouseDragged((SGMouseEvent)event, pressHit, hit); + } + if(e.getID() == MouseEvent.MOUSE_PRESSED) { + pressHit = hit; + mouseReleased((SGMouseEvent)event, hit); + } + if(e.getID() == MouseEvent.MOUSE_RELEASED) + mouseReleased((SGMouseEvent)event, hit); + if(e.getID() == MouseEvent.MOUSE_MOVED) + mouseMoved((SGMouseEvent)event, hit); + } + } + + public void mouseDragged(SGMouseEvent event, boolean pressHit, boolean currentHit) { + + } + + public void mouseReleased(SGMouseEvent event, boolean hit) { + + } + + public void mouseMoved(SGMouseEvent event, boolean hit) { + + } + + @Override + public Rectangle2D getBoundsInLocal() { + return null; + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ModuleFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ModuleFactory.java new file mode 100644 index 00000000..4976c7dc --- /dev/null +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ModuleFactory.java @@ -0,0 +1,59 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * 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 + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.ui.elements2; + +import java.awt.BasicStroke; +import java.awt.geom.Rectangle2D; +import java.util.Collection; + +import org.simantics.db.Resource; +import org.simantics.diagram.elements.TextElementHandler; +import org.simantics.g2d.element.ElementClass; +import org.simantics.g2d.element.handler.impl.BoundsOutline; +import org.simantics.g2d.element.handler.impl.DefaultTransform; +import org.simantics.g2d.element.handler.impl.ObjectTerminal; +import org.simantics.g2d.element.handler.impl.OutlinePick; +import org.simantics.g2d.element.handler.impl.SimpleElementLayers; +import org.simantics.g2d.element.handler.impl.StaticObjectAdapter; +import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer; +import org.simantics.g2d.element.handler.impl.StaticSymbolImpl; +import org.simantics.g2d.element.handler.impl.TextColorImpl; +import org.simantics.g2d.element.handler.impl.TextFontImpl; +import org.simantics.g2d.element.handler.impl.TextImpl; +import org.simantics.g2d.image.Image; +import org.simantics.g2d.image.impl.ShapeImage; + +public class ModuleFactory extends SysdynElementFactory { + + private static final BasicStroke STROKE = new BasicStroke(1f); + private static final Image DEFAULT_IMAGE = new ShapeImage(new Rectangle2D.Double(-5, -2.5, 10, 5), null, STROKE, true); + + @Override + protected ElementClass compileElementClass(Resource elementType, Collection terminals) { + return ElementClass.compile( + SimpleElementLayers.INSTANCE, + OutlinePick.INSTANCE, + TextImpl.INSTANCE, + TextColorImpl.BLACK, + TextFontImpl.DEFAULT, + DefaultTransform.INSTANCE, + new StaticObjectAdapter(elementType), + new StaticSymbolImpl(DEFAULT_IMAGE), + StaticSymbolImageInitializer.INSTANCE, + TextElementHandler.INSTANCE, + BorderSceneGraph.INSTANCE, + BoundsOutline.INSTANCE, + new WholeElementTerminals(terminals) + ).setId(ModuleFactory.class.getSimpleName()); + } + +} diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynConnectionClass.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynConnectionClass.java index 0291a898..c8940eaf 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynConnectionClass.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/SysdynConnectionClass.java @@ -19,14 +19,18 @@ import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; +import org.simantics.db.Resource; import org.simantics.g2d.connection.ConnectionEntity; import org.simantics.g2d.connection.ConnectionEntity.ConnectionEvent; import org.simantics.g2d.connection.ConnectionEntity.ConnectionListener; import org.simantics.g2d.connection.handler.ConnectionHandler; +import org.simantics.g2d.diagram.DiagramHints; import org.simantics.g2d.diagram.handler.PickRequest.PickPolicy; import org.simantics.g2d.diagram.handler.Topology.Connection; import org.simantics.g2d.element.ElementClass; @@ -51,6 +55,7 @@ import org.simantics.scenegraph.g2d.G2DParentNode; import org.simantics.scenegraph.g2d.IG2DNode; import org.simantics.scenegraph.g2d.nodes.SingleElementNode; import org.simantics.utils.datastructures.ListenerList; +import org.simantics.utils.datastructures.Pair; import org.simantics.utils.datastructures.hints.IHintContext.Key; import org.simantics.utils.datastructures.hints.IHintContext.KeyOf; @@ -178,8 +183,11 @@ public class SysdynConnectionClass { Set tmp = new HashSet(); + Map> properties = connection.getHint(DiagramHints.PROPERTIES); + int zIndex = 0; for (IElement child : children) { + ElementClass ec = child.getElementClass(); Transform transform = child.getElementClass().getSingleItem(Transform.class); @@ -188,6 +196,9 @@ public class SysdynConnectionClass { if (at2 == null) continue; + if(properties != null) + child.setHint(DiagramHints.PROPERTIES, properties); + SingleElementNode holder = child.getHint(ElementHints.KEY_SG_NODE); if (holder == null) { holder = parent.addNode(ElementUtils.generateNodeId(child), SingleElementNode.class); @@ -237,7 +248,8 @@ public class SysdynConnectionClass { @Override public Rectangle2D getBounds(IElement e, Rectangle2D size) { - if (size == null) + + if (size == null) size = new Rectangle2D.Double(); size.setFrame(0, 0, 0, 0); @@ -257,7 +269,7 @@ public class SysdynConnectionClass { // coordinates are always absolute. Therefore branch point // bounds also need to be calculated in absolute coordinates. ElementUtils.getElementBoundsOnDiagram(part, size); - //System.out.println("InternalSize BOUNDS: " + size + " for part " + part); +// System.out.println("InternalSize BOUNDS: " + size + " for part " + part + " " + part.getElementClass()); if (temp == null) { temp = new Rectangle2D.Double(); temp.setRect(size); @@ -267,6 +279,7 @@ public class SysdynConnectionClass { } size.setRect(temp); return size; + } private Shape getSelectionShape(IElement forPart) { @@ -364,7 +377,7 @@ public class SysdynConnectionClass { for (IElement part : parts) { for (Pick pick : part.getElementClass().getItemsByClass(Pick.class)) { - //System.out.println("TESTING: " + part + " : " + s + " : " + policy); +// System.out.println("TESTING: " + part + " : " + s + " : " + policy); if (pick.pickTest(part, s, policy)) { //System.out.println(" HIT!"); return true; @@ -379,6 +392,8 @@ public class SysdynConnectionClass { public int pick(IElement e, Shape s, PickPolicy policy, Collection result) { int oldResultSize = result.size(); +// new Exception("SysdynConnectionClass.pick: " + e + " : " + s + " : " + policy).printStackTrace(); + ConnectionEntity ce = e.getHint(ElementHints.KEY_CONNECTION_ENTITY); if (ce == null) return 0; @@ -427,12 +442,12 @@ public class SysdynConnectionClass { for (int i = 0; i < edges; ++i) { IElement part = parts.get(i); for (Pick pick : part.getElementClass().getItemsByClass(Pick.class)) { - //System.out.println("TESTING SEGMENT: " + part + " : " + s + " : " + policy); +// System.out.println("TESTING SEGMENT: " + part + " : " + s + " : " + policy); if (pick.pickTest(part, s, policy)) { - //System.out.println(" HIT!"); +// System.out.println(" HIT!"); if (picks == null) picks = new ArrayList(4); - picks.add(part); + picks.add(e); break; } } @@ -471,6 +486,8 @@ public class SysdynConnectionClass { } } +// System.out.println("pick result size = " + result.size()); + return result.size() - oldResultSize; } } diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ValveFactory.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ValveFactory.java index 030ff856..a2fb18f9 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ValveFactory.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/elements2/ValveFactory.java @@ -15,6 +15,7 @@ import java.awt.BasicStroke; import java.awt.Color; import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; +import java.awt.geom.Rectangle2D.Double; import java.util.Collection; import org.simantics.db.Resource; diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewModelHandler.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewModelHandler.java index 6b1a9a25..b4c6265c 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewModelHandler.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewModelHandler.java @@ -47,6 +47,7 @@ public class NewModelHandler extends AbstractHandler { Resource conf = GraphUtils.create2(g, sr.Configuration, + b.PartOf, model, b.HasName, "Configuration", sr.HasStartTime, 0.0, sr.HasStopTime, 10.0); diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java index 0fe2f8de..2f09a953 100644 --- a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java +++ b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/properties/widgets/expressions/StockExpression.java @@ -181,8 +181,10 @@ public class StockExpression implements IExpression { Resource tail = graph.getPossibleObject(r, sr.HasTail); if(tail != null) { Object name = graph.getPossibleRelatedValue(tail, b.HasName); - if (name != null) + if (name != null) { + System.out.println("STOCK += " + name); builder.append(" + " + name); + } } } } diff --git a/org.simantics.sysdyn/META-INF/MANIFEST.MF b/org.simantics.sysdyn/META-INF/MANIFEST.MF index 801b2fe2..63ce9759 100644 --- a/org.simantics.sysdyn/META-INF/MANIFEST.MF +++ b/org.simantics.sysdyn/META-INF/MANIFEST.MF @@ -14,7 +14,8 @@ Require-Bundle: org.simantics.objmap;bundle-version="0.1.0", org.eclipse.core.runtime;bundle-version="3.5.0", org.eclipse.jface;bundle-version="3.5.2", org.simantics.project;bundle-version="1.0.0", - org.simantics.layer0.utils;bundle-version="0.8.0" + org.simantics.layer0.utils;bundle-version="0.8.0", + org.simantics.structural.stubs;bundle-version="1.0.0" Export-Package: org.simantics.sysdyn, org.simantics.sysdyn.expressionParser, org.simantics.sysdyn.manager, diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java index f9c329fd..d6c844b2 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java @@ -20,15 +20,19 @@ import org.simantics.db.exception.DatabaseException; public class SysdynResource { + public final Resource Admin1; + public final Resource Admin2; public final Resource Asiakasmoduuli; public final Resource Auxiliary; public final Resource AuxiliarySymbol; public final Resource BasicExperiment; + public final Resource CapacitySymbol; public final Resource Cloud; public final Resource CloudSymbol; public final Resource Configuration; public final Resource ConfigurationDiagram; public final Resource ConstantExpression; + public final Resource CustomersSymbol; public final Resource DelayExpression; public final Resource Dependency; public final Resource DependencyConnection; @@ -39,10 +43,10 @@ public class SysdynResource { public final Resource Flow; public final Resource FlowConnection; public final Resource GameExperiment; - public final Resource HasAngle; public final Resource HasEquation; public final Resource HasExpression; public final Resource HasHead; + public final Resource HasHeadTerminal; public final Resource HasInitialEquation; public final Resource HasLookup; public final Resource HasMaxX; @@ -58,10 +62,12 @@ public class SysdynResource { public final Resource HasStartTime; public final Resource HasStopTime; public final Resource HasTail; + public final Resource HasTailTerminal; public final Resource HasUnit; public final Resource HasX; public final Resource HasY; public final Resource IndependentVariable; + public final Resource InputExpression; public final Resource IsHeadOf; public final Resource IsHeadOfTerminal; public final Resource IsInput; @@ -71,10 +77,12 @@ public class SysdynResource { public final Resource Kapasiteettimoduuli; public final Resource LookupExpression; public final Resource Module; + public final Resource ModuleSymbol; public final Resource NormalExpression; public final Resource ParameterExpression; public final Resource RefersTo; public final Resource Result; + public final Resource RootConfigurationDiagram; public final Resource SecondModule; public final Resource SimulateOnChangeExperiment; public final Resource Stock; @@ -89,17 +97,22 @@ public class SysdynResource { public final Resource ValveSymbol; public final Resource Variable; public final Resource WithLookupExpression; + public final Resource angle; public static class URIs { + public static final String Admin1 = "http://www.simantics.org/Sysdyn-1.0/Admin1"; + public static final String Admin2 = "http://www.simantics.org/Sysdyn-1.0/Admin2"; public static final String Asiakasmoduuli = "http://www.simantics.org/Sysdyn-1.0/Asiakasmoduuli"; public static final String Auxiliary = "http://www.simantics.org/Sysdyn-1.0/Auxiliary"; public static final String AuxiliarySymbol = "http://www.simantics.org/Sysdyn-1.0/AuxiliarySymbol"; public static final String BasicExperiment = "http://www.simantics.org/Sysdyn-1.0/BasicExperiment"; + public static final String CapacitySymbol = "http://www.simantics.org/Sysdyn-1.0/CapacitySymbol"; public static final String Cloud = "http://www.simantics.org/Sysdyn-1.0/Cloud"; public static final String CloudSymbol = "http://www.simantics.org/Sysdyn-1.0/CloudSymbol"; public static final String Configuration = "http://www.simantics.org/Sysdyn-1.0/Configuration"; public static final String ConfigurationDiagram = "http://www.simantics.org/Sysdyn-1.0/ConfigurationDiagram"; public static final String ConstantExpression = "http://www.simantics.org/Sysdyn-1.0/ConstantExpression"; + public static final String CustomersSymbol = "http://www.simantics.org/Sysdyn-1.0/CustomersSymbol"; public static final String DelayExpression = "http://www.simantics.org/Sysdyn-1.0/DelayExpression"; public static final String Dependency = "http://www.simantics.org/Sysdyn-1.0/Dependency"; public static final String DependencyConnection = "http://www.simantics.org/Sysdyn-1.0/DependencyConnection"; @@ -110,10 +123,10 @@ public class SysdynResource { public static final String Flow = "http://www.simantics.org/Sysdyn-1.0/Flow"; public static final String FlowConnection = "http://www.simantics.org/Sysdyn-1.0/FlowConnection"; public static final String GameExperiment = "http://www.simantics.org/Sysdyn-1.0/GameExperiment"; - public static final String HasAngle = "http://www.simantics.org/Sysdyn-1.0/HasAngle"; public static final String HasEquation = "http://www.simantics.org/Sysdyn-1.0/HasEquation"; public static final String HasExpression = "http://www.simantics.org/Sysdyn-1.0/HasExpression"; public static final String HasHead = "http://www.simantics.org/Sysdyn-1.0/HasHead"; + public static final String HasHeadTerminal = "http://www.simantics.org/Sysdyn-1.0/HasHeadTerminal"; public static final String HasInitialEquation = "http://www.simantics.org/Sysdyn-1.0/HasInitialEquation"; public static final String HasLookup = "http://www.simantics.org/Sysdyn-1.0/HasLookup"; public static final String HasMaxX = "http://www.simantics.org/Sysdyn-1.0/HasMaxX"; @@ -129,10 +142,12 @@ public class SysdynResource { public static final String HasStartTime = "http://www.simantics.org/Sysdyn-1.0/HasStartTime"; public static final String HasStopTime = "http://www.simantics.org/Sysdyn-1.0/HasStopTime"; public static final String HasTail = "http://www.simantics.org/Sysdyn-1.0/HasTail"; + public static final String HasTailTerminal = "http://www.simantics.org/Sysdyn-1.0/HasTailTerminal"; public static final String HasUnit = "http://www.simantics.org/Sysdyn-1.0/HasUnit"; public static final String HasX = "http://www.simantics.org/Sysdyn-1.0/HasX"; public static final String HasY = "http://www.simantics.org/Sysdyn-1.0/HasY"; public static final String IndependentVariable = "http://www.simantics.org/Sysdyn-1.0/IndependentVariable"; + public static final String InputExpression = "http://www.simantics.org/Sysdyn-1.0/InputExpression"; public static final String IsHeadOf = "http://www.simantics.org/Sysdyn-1.0/IsHeadOf"; public static final String IsHeadOfTerminal = "http://www.simantics.org/Sysdyn-1.0/IsHeadOfTerminal"; public static final String IsInput = "http://www.simantics.org/Sysdyn-1.0/IsInput"; @@ -142,10 +157,12 @@ public class SysdynResource { public static final String Kapasiteettimoduuli = "http://www.simantics.org/Sysdyn-1.0/Kapasiteettimoduuli"; public static final String LookupExpression = "http://www.simantics.org/Sysdyn-1.0/LookupExpression"; public static final String Module = "http://www.simantics.org/Sysdyn-1.0/Module"; + public static final String ModuleSymbol = "http://www.simantics.org/Sysdyn-1.0/ModuleSymbol"; public static final String NormalExpression = "http://www.simantics.org/Sysdyn-1.0/NormalExpression"; public static final String ParameterExpression = "http://www.simantics.org/Sysdyn-1.0/ParameterExpression"; public static final String RefersTo = "http://www.simantics.org/Sysdyn-1.0/RefersTo"; public static final String Result = "http://www.simantics.org/Sysdyn-1.0/Result"; + public static final String RootConfigurationDiagram = "http://www.simantics.org/Sysdyn-1.0/RootConfigurationDiagram"; public static final String SecondModule = "http://www.simantics.org/Sysdyn-1.0/SecondModule"; public static final String SimulateOnChangeExperiment = "http://www.simantics.org/Sysdyn-1.0/SimulateOnChangeExperiment"; public static final String Stock = "http://www.simantics.org/Sysdyn-1.0/Stock"; @@ -160,6 +177,7 @@ public class SysdynResource { public static final String ValveSymbol = "http://www.simantics.org/Sysdyn-1.0/ValveSymbol"; public static final String Variable = "http://www.simantics.org/Sysdyn-1.0/Variable"; public static final String WithLookupExpression = "http://www.simantics.org/Sysdyn-1.0/WithLookupExpression"; + public static final String angle = "http://www.simantics.org/Sysdyn-1.0/angle"; } public static Resource getResourceOrNull(ReadGraph graph, String uri) { @@ -172,15 +190,19 @@ public class SysdynResource { } public SysdynResource(ReadGraph graph) { + Admin1 = getResourceOrNull(graph, URIs.Admin1); + Admin2 = getResourceOrNull(graph, URIs.Admin2); Asiakasmoduuli = getResourceOrNull(graph, URIs.Asiakasmoduuli); Auxiliary = getResourceOrNull(graph, URIs.Auxiliary); AuxiliarySymbol = getResourceOrNull(graph, URIs.AuxiliarySymbol); BasicExperiment = getResourceOrNull(graph, URIs.BasicExperiment); + CapacitySymbol = getResourceOrNull(graph, URIs.CapacitySymbol); Cloud = getResourceOrNull(graph, URIs.Cloud); CloudSymbol = getResourceOrNull(graph, URIs.CloudSymbol); Configuration = getResourceOrNull(graph, URIs.Configuration); ConfigurationDiagram = getResourceOrNull(graph, URIs.ConfigurationDiagram); ConstantExpression = getResourceOrNull(graph, URIs.ConstantExpression); + CustomersSymbol = getResourceOrNull(graph, URIs.CustomersSymbol); DelayExpression = getResourceOrNull(graph, URIs.DelayExpression); Dependency = getResourceOrNull(graph, URIs.Dependency); DependencyConnection = getResourceOrNull(graph, URIs.DependencyConnection); @@ -191,10 +213,10 @@ public class SysdynResource { Flow = getResourceOrNull(graph, URIs.Flow); FlowConnection = getResourceOrNull(graph, URIs.FlowConnection); GameExperiment = getResourceOrNull(graph, URIs.GameExperiment); - HasAngle = getResourceOrNull(graph, URIs.HasAngle); HasEquation = getResourceOrNull(graph, URIs.HasEquation); HasExpression = getResourceOrNull(graph, URIs.HasExpression); HasHead = getResourceOrNull(graph, URIs.HasHead); + HasHeadTerminal = getResourceOrNull(graph, URIs.HasHeadTerminal); HasInitialEquation = getResourceOrNull(graph, URIs.HasInitialEquation); HasLookup = getResourceOrNull(graph, URIs.HasLookup); HasMaxX = getResourceOrNull(graph, URIs.HasMaxX); @@ -210,10 +232,12 @@ public class SysdynResource { HasStartTime = getResourceOrNull(graph, URIs.HasStartTime); HasStopTime = getResourceOrNull(graph, URIs.HasStopTime); HasTail = getResourceOrNull(graph, URIs.HasTail); + HasTailTerminal = getResourceOrNull(graph, URIs.HasTailTerminal); HasUnit = getResourceOrNull(graph, URIs.HasUnit); HasX = getResourceOrNull(graph, URIs.HasX); HasY = getResourceOrNull(graph, URIs.HasY); IndependentVariable = getResourceOrNull(graph, URIs.IndependentVariable); + InputExpression = getResourceOrNull(graph, URIs.InputExpression); IsHeadOf = getResourceOrNull(graph, URIs.IsHeadOf); IsHeadOfTerminal = getResourceOrNull(graph, URIs.IsHeadOfTerminal); IsInput = getResourceOrNull(graph, URIs.IsInput); @@ -223,10 +247,12 @@ public class SysdynResource { Kapasiteettimoduuli = getResourceOrNull(graph, URIs.Kapasiteettimoduuli); LookupExpression = getResourceOrNull(graph, URIs.LookupExpression); Module = getResourceOrNull(graph, URIs.Module); + ModuleSymbol = getResourceOrNull(graph, URIs.ModuleSymbol); NormalExpression = getResourceOrNull(graph, URIs.NormalExpression); ParameterExpression = getResourceOrNull(graph, URIs.ParameterExpression); RefersTo = getResourceOrNull(graph, URIs.RefersTo); Result = getResourceOrNull(graph, URIs.Result); + RootConfigurationDiagram = getResourceOrNull(graph, URIs.RootConfigurationDiagram); SecondModule = getResourceOrNull(graph, URIs.SecondModule); SimulateOnChangeExperiment = getResourceOrNull(graph, URIs.SimulateOnChangeExperiment); Stock = getResourceOrNull(graph, URIs.Stock); @@ -241,6 +267,7 @@ public class SysdynResource { ValveSymbol = getResourceOrNull(graph, URIs.ValveSymbol); Variable = getResourceOrNull(graph, URIs.Variable); WithLookupExpression = getResourceOrNull(graph, URIs.WithLookupExpression); + angle = getResourceOrNull(graph, URIs.angle); } public static SysdynResource getInstance(ReadGraph graph) { diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java index 1aea00e4..3bc82721 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/manager/SysdynModel.java @@ -15,7 +15,9 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import org.simantics.db.Builtins; @@ -33,6 +35,7 @@ import org.simantics.objmap.Mappings; import org.simantics.simulation.experiment.IExperiment; import org.simantics.simulation.model.IModel; import org.simantics.simulation.project.IExperimentActivationListener; +import org.simantics.structural.stubs.StructuralResource2; import org.simantics.sysdyn.SysdynResource; import org.simantics.sysdyn.modelica.ModelicaWriter; import org.simantics.sysdyn.representation.Configuration; @@ -50,6 +53,7 @@ public class SysdynModel implements IMappingListener, IModel { IMapping mapping; Configuration configuration; + Set modules = new HashSet(); SimulationResult result; CopyOnWriteArrayList modificationListeners = @@ -59,11 +63,39 @@ public class SysdynModel implements IMappingListener, IModel { Map services = new HashMap(); + void readModules(ReadGraph graph, Resource configResource, Set result) throws DatabaseException { + + if(!result.add(configResource)) return; + + Builtins b = graph.getBuiltins(); + SysdynResource sr = SysdynResource.getInstance(graph); + StructuralResource2 str = StructuralResource2.getInstance(graph); + + for(Resource part : graph.getObjects(configResource, b.ConsistsOf)) { + if(graph.isInstanceOf(part, sr.Module)) { + Resource type = graph.getPossibleType(part, sr.Module); + Resource config = graph.getPossibleObject(type, str.IsDefinedBy); + readModules(graph, config, result); + } + } + + } + + Set readModules(ReadGraph graph, Resource configResource) throws DatabaseException { + HashSet result = new HashSet(); + readModules(graph, configResource, result); + return result; + } + private void createMapping(ReadGraph g) throws DatabaseException { SysdynSchema schema = new SysdynSchema(g); mapping = Mappings.createWithListening(schema); mapping.addMappingListener(SysdynModel.this); - configuration = (Configuration)mapping.map(g, configurationResource); + configuration = (Configuration)mapping.map(g, configurationResource); + for(Resource config : readModules(g, configurationResource)) { + modules.add((Configuration)mapping.map(g, config)); + } + System.out.println("Loaded model with " + modules.size() + " modules."); } public SysdynModel(ReadGraph g, Resource configurationResource) { @@ -88,8 +120,15 @@ public class SysdynModel implements IMappingListener, IModel { public synchronized void simulate(IModelicaMonitor monitor) throws IOException { try { ModelicaWriter writer = new ModelicaWriter(); - writer.write(configuration); + //writer.write(configuration); + for(Configuration c : modules) { + writer.write(c); + } + System.out.println("== Modelica == "); + System.out.println(writer.toString()); + System.out.println("== Modelica ends == "); + result = ModelicaManager.runModelica( configuration.getName(), writer.toString(), diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java index 143f8888..02e71a7d 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/modelica/ModelicaWriter.java @@ -17,6 +17,7 @@ import org.simantics.sysdyn.representation.Configuration; import org.simantics.sysdyn.representation.Dependency; import org.simantics.sysdyn.representation.IElement; import org.simantics.sysdyn.representation.Module; +import org.simantics.sysdyn.representation.ModuleType; import org.simantics.sysdyn.representation.Stock; import org.simantics.sysdyn.representation.Variable; import org.simantics.sysdyn.representation.expressions.IExpression; @@ -82,7 +83,9 @@ public class ModelicaWriter { } - b.append("class ").append(configuration.getName().replace(" ", "")).append('\n'); + ModuleType mt = configuration.getModuleType(); + String className = mt != null ? (mt.getName().replace(" ", "")) : (configuration.getName().replace(" ", "")); + b.append("class ").append(className).append('\n'); b.append("// Variable definitions\n"); for(Variable variable : variables) { @@ -97,7 +100,7 @@ public class ModelicaWriter { if(!modules.isEmpty()) { b.append("// Module definitions\n"); for(Module m : modules) { - b.append(" " + m.getName() + " " + m.getLabel() + ";\n"); + b.append(" " + m.getType().getName() + " " + m.getLabel() + ";\n"); } } @@ -133,7 +136,7 @@ public class ModelicaWriter { Variable variable = (Variable)dependency.getHead(); Module module = (Module)dependency.getTail(); Variable reference = (Variable)dependency.refersTo(); - b.append(" " + variable.getName() + " = " + module.getLabel() + "." + reference.getName()); + b.append(" " + variable.getName() + " = " + module.getLabel() + "." + reference.getName() + ";\n"); } b.append("// Outputs\n"); @@ -141,15 +144,16 @@ public class ModelicaWriter { Variable variable = (Variable)dependency.getTail(); Module module = (Module)dependency.getHead(); Variable reference = (Variable)dependency.refersTo(); - b.append(" " + module.getLabel() + "." + reference.getName() + " = " + variable.getName()); + b.append(" " + module.getLabel() + "." + reference.getName() + " = " + variable.getName() + ";\n"); } - b.append("end ").append(configuration.getName().replace(" ", "")).append(";\n\n"); + b.append("end ").append(className).append(";\n\n"); - for(Module m : modules) { - writeConfiguration(m.getConfiguration()); - } +// for(Module m : modules) { +// writeConfiguration(m.getConfiguration()); +// } + } public String escape(String name) { diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Configuration.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Configuration.java index 792ed2bb..e59128a8 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Configuration.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Configuration.java @@ -14,6 +14,7 @@ package org.simantics.sysdyn.representation; import java.util.ArrayList; import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedElement; import org.simantics.objmap.annotations.RelatedElements; import org.simantics.objmap.annotations.RelatedValue; import org.simantics.sysdyn.representation.visitors.ElementVisitorVoidAdapter; @@ -35,6 +36,9 @@ public class Configuration { @RelatedValue("http://www.simantics.org/Layer0-1.0/HasLabel") private String label; + @RelatedElement("http://www.simantics.org/Structural-1.0/Defines") + private ModuleType moduleType; + @RelatedElements( value = "http://www.simantics.org/Layer0-1.0/ConsistsOf", composition = true) @@ -77,5 +81,9 @@ public class Configuration { return label; } + public ModuleType getModuleType() { + return moduleType; + } + } diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Module.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Module.java index fd5b84ba..b28a7ffe 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Module.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/Module.java @@ -18,6 +18,9 @@ public class Module implements IElement { @RelatedElement("http://www.simantics.org/Layer0-1.0/PartOf") private Configuration parentConfiguration; + @RelatedElement("http://www.simantics.org/Layer0-1.0/InstanceOf") + private ModuleType type; + @RelatedElement("http://www.simantics.org/Structural-1.0/IsDefinedBy") private Configuration configuration; @@ -52,6 +55,10 @@ public class Module implements IElement { public String getLabel() { return label; } + + public ModuleType getType() { + return type; + } public Configuration getParentConfiguration() { return this.parentConfiguration; diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/ModuleType.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/ModuleType.java new file mode 100644 index 00000000..af934555 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/ModuleType.java @@ -0,0 +1,21 @@ +package org.simantics.sysdyn.representation; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.objmap.annotations.RelatedValue; +import org.simantics.sysdyn.representation.visitors.IElementVisitorVoid; + +@GraphType("http://www.simantics.org/Structural-1.0/ComponentType") +public class ModuleType implements IElement { + + @RelatedValue("http://www.simantics.org/Layer0-1.0/HasName") + private String name; + + public String getName() { + return name; + } + + @Override + public void accept(IElementVisitorVoid v) { + } + +} diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SysdynSchema.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SysdynSchema.java index a4279318..877401e2 100644 --- a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SysdynSchema.java +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/SysdynSchema.java @@ -16,6 +16,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.objmap.schema.MappingSchemas; import org.simantics.objmap.schema.SimpleSchema; import org.simantics.sysdyn.representation.expressions.ConstantExpression; +import org.simantics.sysdyn.representation.expressions.InputExpression; import org.simantics.sysdyn.representation.expressions.LookupExpression; import org.simantics.sysdyn.representation.expressions.NormalExpression; import org.simantics.sysdyn.representation.expressions.ParameterExpression; @@ -34,7 +35,9 @@ public class SysdynSchema extends SimpleSchema { addLinkType(MappingSchemas.fromAnnotations(g, Stock.class)); addLinkType(MappingSchemas.fromAnnotations(g, Valve.class)); addLinkType(MappingSchemas.fromAnnotations(g, Module.class)); + addLinkType(MappingSchemas.fromAnnotations(g, ModuleType.class)); addLinkType(MappingSchemas.fromAnnotations(g, NormalExpression.class)); + addLinkType(MappingSchemas.fromAnnotations(g, InputExpression.class)); addLinkType(MappingSchemas.fromAnnotations(g, ParameterExpression.class)); addLinkType(MappingSchemas.fromAnnotations(g, StockExpression.class)); addLinkType(MappingSchemas.fromAnnotations(g, ConstantExpression.class)); diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/InputExpression.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/InputExpression.java new file mode 100644 index 00000000..84590be6 --- /dev/null +++ b/org.simantics.sysdyn/src/org/simantics/sysdyn/representation/expressions/InputExpression.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * 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 + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.sysdyn.representation.expressions; + +import org.simantics.objmap.annotations.GraphType; +import org.simantics.sysdyn.representation.Variable; + +@GraphType("http://www.simantics.org/Sysdyn-1.0/InputExpression") +public class InputExpression extends Expression { + + @Override + public String getDeclaration(Variable variable) { + return " " + variable.getType() + " " + variable.getName() + ";\n"; + } + +} diff --git a/sysdyn_ontologies/sysdyn.graph b/sysdyn_ontologies/sysdyn.graph index 5b9e1c64..20908392 100644 --- a/sysdyn_ontologies/sysdyn.graph +++ b/sysdyn_ontologies/sysdyn.graph @@ -20,10 +20,23 @@ %define tag($pred) $subject $pred $subject + %define symmetric() $subject $layer0.InverseOf $subject +%define defSymbol($label, $componentType) + $subject