summaryrefslogtreecommitdiff
path: root/src/main/java/simulator/engine/VisualizationAdapter.java
blob: 119596b1e3e44cfc835140bef8e672832ede6375 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package simulator.engine;

import simulator.*;
import core.*;
import prefs.VSPrefs;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Adapter that allows VSSimulatorVisualization to work with the new SimulationEngine interface.
 * This provides backward compatibility during the refactoring process.
 */
public class VisualizationAdapter {
    
    /**
     * Inject a simulation engine into an existing VSSimulatorVisualization.
     * This replaces direct simulation logic with delegated calls to the engine.
     */
    public static void injectEngine(VSSimulatorVisualization viz, SimulationEngine engine) 
            throws Exception {
        
        // Replace sendMessage method behavior using a proxy
        installSendMessageProxy(viz, engine);
        
        // Sync process list
        syncProcessList(viz, engine);
        
        // Sync task manager
        syncTaskManager(viz, engine);
    }
    
    /**
     * Install a proxy for the sendMessage method that delegates to the engine.
     */
    private static void installSendMessageProxy(VSSimulatorVisualization viz, 
                                                SimulationEngine engine) throws Exception {
        // This is complex with standard Java, so we'll use a different approach
        // We'll override the behavior by setting a flag that the paint method checks
        
        // Set a flag indicating headless mode
        Field headlessField = findOrCreateField(viz, "isHeadlessMode");
        headlessField.setAccessible(true);
        headlessField.set(viz, true);
        
        // Store engine reference
        Field engineField = findOrCreateField(viz, "simulationEngine");
        engineField.setAccessible(true);
        engineField.set(viz, engine);
    }
    
    /**
     * Find a field or create it dynamically if possible.
     */
    private static Field findOrCreateField(Object obj, String fieldName) {
        try {
            return obj.getClass().getDeclaredField(fieldName);
        } catch (NoSuchFieldException e) {
            // In real implementation, we'd need to use bytecode manipulation
            // For now, we'll work with existing fields
            return null;
        }
    }
    
    /**
     * Sync the process list between visualization and engine.
     */
    private static void syncProcessList(VSSimulatorVisualization viz, 
                                       SimulationEngine engine) throws Exception {
        Field processesField = VSSimulatorVisualization.class.getDeclaredField("processes");
        processesField.setAccessible(true);
        
        // Get current processes from viz
        java.util.ArrayList<VSInternalProcess> vizProcesses = 
            (java.util.ArrayList<VSInternalProcess>) processesField.get(viz);
        
        // Add all to engine
        for (VSInternalProcess process : vizProcesses) {
            engine.addProcess(process);
        }
    }
    
    /**
     * Sync the task manager between visualization and engine.
     */
    private static void syncTaskManager(VSSimulatorVisualization viz, 
                                       SimulationEngine engine) throws Exception {
        Field taskManagerField = VSSimulatorVisualization.class.getDeclaredField("taskManager");
        taskManagerField.setAccessible(true);
        
        VSTaskManager vizTaskManager = (VSTaskManager) taskManagerField.get(viz);
        VSTaskManager engineTaskManager = engine.getTaskManager();
        
        // Copy tasks if needed
        // This would require access to internal task manager state
    }
    
    /**
     * Create a headless wrapper for VSSimulatorVisualization that prevents paint operations.
     */
    public static VSSimulatorVisualization createHeadlessWrapper(
            final VSSimulatorVisualization original, 
            final SimulationEngine engine) {
        
        try {
            // Get prefs, simulator, and loging via reflection
            Field prefsField = VSSimulatorVisualization.class.getDeclaredField("prefs");
            prefsField.setAccessible(true);
            VSPrefs prefs = (VSPrefs) prefsField.get(original);
            
            Field simulatorField = VSSimulatorVisualization.class.getDeclaredField("simulator");
            simulatorField.setAccessible(true);
            VSSimulator simulator = (VSSimulator) simulatorField.get(original);
            
            Field logingField = VSSimulatorVisualization.class.getDeclaredField("loging");
            logingField.setAccessible(true);
            VSLogging loging = (VSLogging) logingField.get(original);
            
            // Create a wrapper that intercepts paint calls
            return new VSSimulatorVisualization(prefs, simulator, loging) {
            
            @Override
            public void paint() {
                // Do nothing - no painting in headless mode
            }
            
            @Override
            public void paint(java.awt.Graphics g) {
                // Do nothing
            }
            
            @Override
            public void sendMessage(VSMessage message) {
                // Delegate to engine instead of creating visual elements
                engine.sendMessage(message);
            }
            
            @Override
            public void repaint() {
                // Do nothing
            }
            
            @Override
            public java.awt.image.BufferStrategy getBufferStrategy() {
                return null; // Prevent buffer strategy creation
            }
            
            @Override
            public void createBufferStrategy(int numBuffers) {
                // Do nothing
            }
        };
        } catch (Exception e) {
            throw new RuntimeException("Failed to create headless wrapper", e);
        }
    }
}