1515import com .modsim .tools .PlaceTool ;
1616import com .modsim .util .Vec2 ;
1717
18+ import static java .lang .Math .abs ;
19+
1820/**
1921 * The main viewport for the simulator
2022 * @author aw12700
@@ -38,6 +40,7 @@ public class View extends JPanel {
3840
3941 private BufferedImage staticCanvas = null ;
4042 private boolean staticIsDirty = true ;
43+ private long lastDynamicPaint = 0 ;
4144
4245 public View () {
4346 setFocusable (true );
@@ -59,106 +62,113 @@ public void calcXForm() {
5962 wToV .scale (zoom , zoom );
6063 }
6164
62- @ Override
63- public void paintComponent (Graphics oldG ) {
64- Graphics2D g = (Graphics2D ) oldG ;
65-
66- // The static canvas is used for drawing parts which do not vary with simulation state
65+ public void paintStatic () {
66+ // Renders the static portion of the viewport
6767 if (staticCanvas == null || staticCanvas .getWidth () != getWidth () || staticCanvas .getHeight () != getHeight ()) {
6868 staticCanvas = getGraphicsConfiguration ().createCompatibleImage (getWidth (), getHeight ());
6969 staticIsDirty = true ;
7070 }
7171 Graphics2D staticG = staticCanvas .createGraphics ();
72+ AffineTransform oldStatic = new AffineTransform (staticG .getTransform ());
73+
74+ if (staticIsDirty ) {
75+ // Antialiasing
76+ if (useAA ) {
77+ staticG .setRenderingHint (RenderingHints .KEY_ANTIALIASING , RenderingHints .VALUE_ANTIALIAS_ON );
78+ }
79+ else {
80+ staticG .setRenderingHint (RenderingHints .KEY_ANTIALIASING , RenderingHints .VALUE_ANTIALIAS_OFF );
81+ }
82+
83+ // Fill background
84+ staticG .setTransform (oldStatic );
85+ staticG .setColor (Colors .background );
86+ staticG .fillRect (0 , 0 , getWidth (), getHeight ());
87+ // Grid
88+ staticG .setColor (Colors .grid );
89+ double xD = (camX + getWidth () / 2 );
90+ double yD = (camY + getHeight () / 2 );
91+ double xOff = xD % (Main .sim .grid * zoom );
92+ double yOff = yD % (Main .sim .grid * zoom );
93+ staticG .translate (xOff , yOff );
94+ drawGrid (staticG );
95+ staticG .setTransform (oldStatic );
96+
97+ // Draw links
98+ staticG .transform (wToV );
99+ for (Link l : Main .sim .getLinks ()) {
100+ if (l == null ) {
101+ System .err .println ("Warning: Null link encountered while drawing" );
102+ continue ;
103+ }
104+ l .draw (staticG );
105+ }
106+
107+ // Draw modules - static
108+ staticG .setTransform (oldStatic );
109+ for (BaseModule m : Main .sim .getModules ()) {
110+ m .updateXForm ();
111+ staticG .transform (m .toView );
112+ m .paintStatic (staticG );
113+ staticG .setTransform (oldStatic );
114+ }
115+
116+ staticG .setTransform (oldStatic );
117+
118+ // Static canvas is now up-to-date
119+ staticIsDirty = false ;
120+ }
121+ }
122+
123+ @ Override
124+ public void paintComponent (Graphics oldG ) {
125+ lastDynamicPaint = System .currentTimeMillis ();
126+ Graphics2D g = (Graphics2D ) oldG ;
72127
73128 // Antialiasing
74129 if (useAA ) {
75130 g .setRenderingHint (RenderingHints .KEY_ANTIALIASING , RenderingHints .VALUE_ANTIALIAS_ON );
76- staticG .setRenderingHint (RenderingHints .KEY_ANTIALIASING , RenderingHints .VALUE_ANTIALIAS_ON );
77131 }
78132 else {
79133 g .setRenderingHint (RenderingHints .KEY_ANTIALIASING , RenderingHints .VALUE_ANTIALIAS_OFF );
80- staticG .setRenderingHint (RenderingHints .KEY_ANTIALIASING , RenderingHints .VALUE_ANTIALIAS_OFF );
81134 }
82135
83136 // Refresh the view's transform
84137 calcXForm ();
85138 // Store the original view transform for restoration to a known state
86139 AffineTransform old = new AffineTransform (g .getTransform ());
87- AffineTransform oldStatic = new AffineTransform (staticG .getTransform ());
88-
89- synchronized (Main .sim ) {
90- // Static drawing
91- if (staticIsDirty ) {
92- // Fill background
93- staticG .setTransform (oldStatic );
94- staticG .setColor (Colors .background );
95- staticG .fillRect (0 , 0 , getWidth (), getHeight ());
96- // Grid
97- staticG .setColor (Colors .grid );
98- double xD = (camX + getWidth () / 2 );
99- double yD = (camY + getHeight () / 2 );
100- double xOff = xD % (Main .sim .grid * zoom );
101- double yOff = yD % (Main .sim .grid * zoom );
102- staticG .translate (xOff , yOff );
103- drawGrid (staticG );
104- staticG .setTransform (oldStatic );
105140
106- // Draw links
107- staticG .transform (wToV );
108- for (Link l : Main .sim .getLinks ()) {
109- if (l == null ) {
110- System .err .println ("Warning: Null link encountered while drawing" );
111- continue ;
112- }
113- l .draw (staticG );
114- }
115-
116- // Draw modules - static
117- staticG .setTransform (oldStatic );
118- for (BaseModule m : Main .sim .getModules ()) {
119- m .updateXForm ();
120- staticG .transform (m .toView );
121- m .paintStatic (staticG );
122- staticG .setTransform (oldStatic );
123- }
141+ // Static stuff is drawn below all dynamic stuff
142+ paintStatic ();
143+ g .drawImage (staticCanvas , 0 , 0 , getWidth (), getHeight (), null );
124144
125- staticG .setTransform (oldStatic );
145+ // Draw modules - dynamic
146+ for (BaseModule m : Main .sim .getModules ()) {
147+ m .updateXForm ();
148+ g .transform (m .toView );
149+ m .paintDynamic (g );
126150
127- // Static canvas is now up-to-date
128- staticIsDirty = false ;
151+ if ( m . error ) {
152+ drawError ( g ) ;
129153 }
130154
131- // Static stuff is drawn below all dynamic stuff
132- g .drawImage (staticCanvas , 0 , 0 , getWidth (), getHeight (), null );
133-
134- // Draw modules - dynamic
135- for (BaseModule m : Main .sim .getModules ()) {
136- m .updateXForm ();
137- g .transform (m .toView );
138- m .paintDynamic (g );
139-
140- if (m .error ) {
141- drawError (g );
142- }
155+ g .setTransform (old );
156+ }
143157
144- g .setTransform (old );
145- }
158+ // Labels are drawn over all module renderings
159+ for (BaseModule m : Main .sim .getModules ()) {
160+ g .transform (m .toView );
161+ m .drawLabel (g );
162+ g .setTransform (old );
163+ }
146164
147- // Labels are drawn over all module renderings
148- for (BaseModule m : Main .sim .getModules ()) {
165+ // Highlighted bounds are drawn over labels
166+ for (BaseModule m : Main .sim .getModules ()) {
167+ if (m .selected ) {
149168 g .transform (m .toView );
150- m .drawLabel (g );
169+ m .drawBounds (g );
151170 g .setTransform (old );
152171 }
153-
154- // Highlighted bounds are drawn over labels
155- for (BaseModule m : Main .sim .getModules ()) {
156- if (m .selected ) {
157- g .transform (m .toView );
158- m .drawBounds (g );
159- g .setTransform (old );
160- }
161- }
162172 }
163173
164174 // Draw the tool
@@ -290,5 +300,20 @@ public void zoomOut(int x, int y) {
290300 */
291301 public void flagStaticRedraw () {
292302 staticIsDirty = true ;
303+ repaint ();
304+ }
305+
306+ /***
307+ * "Soft" request for a redraw, used for simulation updates. Capped at 30Hz refresh rate.
308+ */
309+ public void flagDynamicRedraw () {
310+ long currentTime = System .currentTimeMillis ();
311+ if (abs (currentTime - lastDynamicPaint ) > 33 ) {
312+ repaint ();
313+ }
314+ else {
315+ // persistence-of-vision simulation
316+ // TODO!!
317+ }
293318 }
294319}
0 commit comments