1   package org.opentrafficsim.draw.network;
2   
3   import java.rmi.RemoteException;
4   import java.util.HashSet;
5   import java.util.Set;
6   
7   import javax.naming.Binding;
8   import javax.naming.NamingEnumeration;
9   import javax.naming.NamingException;
10  import javax.naming.event.EventContext;
11  
12  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
13  import org.opentrafficsim.core.network.Link;
14  import org.opentrafficsim.core.network.NetworkException;
15  import org.opentrafficsim.core.network.Node;
16  import org.opentrafficsim.core.network.OTSLink;
17  import org.opentrafficsim.core.network.OTSNetwork;
18  import org.opentrafficsim.core.network.OTSNetworkUtils;
19  import org.opentrafficsim.core.network.OTSNode;
20  import org.opentrafficsim.draw.core.ClonableRenderable2DInterface;
21  
22  import nl.tudelft.simulation.dsol.animation.Locatable;
23  import nl.tudelft.simulation.dsol.animation.D2.Renderable2DInterface;
24  import nl.tudelft.simulation.dsol.simulators.AnimatorInterface;
25  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
26  import nl.tudelft.simulation.naming.context.ContextUtil;
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  public final class OTSNetworkAnimationUtils
37  {
38      
39      private OTSNetworkAnimationUtils()
40      {
41          
42      }
43  
44      
45  
46  
47  
48  
49  
50  
51  
52  
53      @SuppressWarnings("checkstyle:designforextension")
54      public static OTSNetwork clone(final OTSNetwork network, final String newId,
55              final SimulatorInterface.TimeDoubleUnit oldSimulator, final OTSSimulatorInterface newSimulator)
56              throws NetworkException
57      {
58          OTSNetwork newNetwork = OTSNetworkUtils.clone(network, newId, oldSimulator, newSimulator);
59  
60          
61          for (Link oldLink : network.getLinkMap().values())
62          {
63              OTSLink newLink = (OTSLink) newNetwork.getLink(oldLink.getId());
64              cloneAnimation(oldLink, newLink, oldSimulator, newSimulator);
65          }
66  
67          
68          for (Node oldNode : network.getNodeMap().values())
69          {
70              OTSNode newNode = (OTSNode) newNetwork.getNode(oldNode.getId());
71              cloneAnimation(oldNode, newNode, oldSimulator, newSimulator);
72          }
73  
74          
75  
76          return newNetwork;
77      }
78  
79      
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91      @SuppressWarnings("checkstyle:designforextension")
92      public static <T extends Locatable> void cloneAnimation(final Locatable oldSource, final T newSource,
93              final SimulatorInterface.TimeDoubleUnit oldSimulator, final SimulatorInterface.TimeDoubleUnit newSimulator)
94      {
95          if (!(oldSimulator instanceof AnimatorInterface) || !(newSimulator instanceof AnimatorInterface))
96          {
97              return;
98          }
99  
100         try
101         {
102             EventContext context =
103                     (EventContext) ContextUtil.lookup(oldSimulator.getReplication().getContext(), "/animation/2D");
104             NamingEnumeration<Binding> list = context.listBindings("");
105             while (list.hasMore())
106             {
107                 Binding binding = list.next();
108                 @SuppressWarnings("unchecked")
109                 Renderable2DInterface<T> animationObject = (Renderable2DInterface<T>) binding.getObject();
110                 T locatable = animationObject.getSource();
111                 if (oldSource.equals(locatable) && animationObject instanceof ClonableRenderable2DInterface)
112                 {
113                     ((ClonableRenderable2DInterface<T>) animationObject).clone(newSource, newSimulator);
114                 }
115             }
116         }
117         catch (NamingException | RemoteException exception)
118         {
119             System.err.println("Error when cloning animation objects for object " + oldSource);
120         }
121     }
122 
123     
124 
125 
126 
127 
128     @SuppressWarnings("checkstyle:designforextension")
129     public static void destroy(final OTSNetwork network, final SimulatorInterface.TimeDoubleUnit simulator)
130     {
131         Set<Renderable2DInterface<?>> animationObjects = new HashSet<>();
132         try
133         {
134             EventContext context = (EventContext) ContextUtil.lookup(simulator.getReplication().getContext(), "/animation/2D");
135             NamingEnumeration<Binding> list = context.listBindings("");
136             while (list.hasMore())
137             {
138                 Binding binding = list.next();
139                 Renderable2DInterface<?> animationObject = (Renderable2DInterface<?>) binding.getObject();
140                 animationObjects.add(animationObject);
141             }
142 
143             for (Renderable2DInterface<?> ao : animationObjects)
144             {
145                 try
146                 {
147                     ao.destroy();
148                 }
149                 catch (Exception e)
150                 {
151                     
152                 }
153             }
154         }
155         catch (NamingException exception)
156         {
157             System.err.println("Error when destroying animation objects");
158         }
159 
160         
161         OTSNetworkUtils.destroy(network, simulator);
162     }
163 
164     
165 
166 
167 
168 
169     @SuppressWarnings("checkstyle:designforextension")
170     public static void removeAnimation(final Class<?> clazz, final SimulatorInterface.TimeDoubleUnit oldSimulator)
171     {
172         if (!(oldSimulator instanceof AnimatorInterface))
173         {
174             return;
175         }
176 
177         try
178         {
179             EventContext context =
180                     (EventContext) ContextUtil.lookup(oldSimulator.getReplication().getContext(), "/animation/2D");
181             NamingEnumeration<Binding> list = context.listBindings("");
182             while (list.hasMore())
183             {
184                 Binding binding = list.next();
185                 Renderable2DInterface<?> animationObject = (Renderable2DInterface<?>) binding.getObject();
186                 Locatable locatable = animationObject.getSource();
187                 if (clazz.isAssignableFrom(locatable.getClass()))
188                 {
189                     animationObject.destroy();
190                 }
191             }
192         }
193         catch (NamingException | RemoteException exception)
194         {
195             System.err.println("Error when destroying animation objects for class " + clazz.getSimpleName());
196         }
197     }
198 
199 }