Ticket #2241: 2241.patch

File 2241.patch, 10.9 KB (added by meddle, 15 years ago)

Design related code

  • modules/org.sophie2.main.app.commons/src/main/java/org/sophie2/main/app/commons/app/MainWindowLogic.java

    ### Eclipse Workspace Patch 1.0
    #P sophie2
     
    1111import org.sophie2.base.layout.model.MainWindowOptions; 
    1212import org.sophie2.base.layout.model.MainWindowOptions.ScreenMode; 
    1313import org.sophie2.base.layout.model.MainWindowOptions.WindowsState; 
    14 import org.sophie2.base.media.MediaUtil; 
     14import org.sophie2.base.natlib.NativeBridgeRegistry; 
    1515import org.sophie2.core.modularity.FakeModuleRegistry; 
    1616import org.sophie2.core.modularity.FileSearchUtil; 
    1717import org.sophie2.core.mvc.EventFilterBuilder; 
     
    117117                                } 
    118118                        } 
    119119                        if (mainWindow.documents().size() == 0) { 
    120                                 MediaUtil.getDefaultAudioOutput().stop(); 
     120                                //MediaUtil.getDefaultAudioOutput().stop(); 
     121                                NativeBridgeRegistry.get().unregisterAll(); 
    121122                                if (MainAppModule.get().getBundleContext() != null) { 
    122123                                        // In true. 
    123124                                        try { 
  • modules/org.sophie2.base.natlib/src/main/java/org/sophie2/base/natlib/NativeBridge.java

     
    5050                try { 
    5151                        SophieLog.debug(getExecutableString()); 
    5252                        this.nativeProcess = Runtime.getRuntime().exec(new String[] { getExecutableString() }); 
    53                         this.nativeStderr = new BufferedReader(new InputStreamReader(this.nativeProcess 
    54                                         .getErrorStream())); 
     53                        this.nativeStderr = new BufferedReader( 
     54                                        new InputStreamReader(this.nativeProcess.getErrorStream())); 
    5555                        // SophieLog.trace("sending start-command..."); 
    5656                        try { 
    5757                                int exit = this.nativeProcess.exitValue(); 
     
    7272                                } 
    7373                                this.nativeProcess = null; 
    7474                                this.nativeStderr = null; 
     75                                NativeBridgeRegistry.get().unregister(this); 
    7576                        } 
    7677                } 
    7778                SophieLog.debug("NativeBridge started = " + this.started); 
     
    8384                } catch (InterruptedException e) { 
    8485                        throw new RuntimeException(e); 
    8586                } 
     87 
     88                NativeBridgeRegistry.get().register(this); 
    8689                dumpError(); 
    8790 
    8891        } 
    8992 
     93        private Process getNativeProcess() { 
     94                if (!isRunning()) { 
     95                        start(); 
     96                } 
     97 
     98                return this.nativeProcess; 
     99        } 
     100 
    90101        /** 
    91102         * This method sends stop command to the native process and then destroys 
    92103         * it. The stop command is sent if there's any action that would be done 
     
    100111                } catch (RuntimeException e) { 
    101112                        SophieLog.info("Problem while stopping native process : ", e); 
    102113                } 
     114 
    103115                this.started = false; 
    104                 this.nativeProcess.destroy(); 
    105                 this.nativeProcess = null; 
     116                if (this.nativeProcess != null) { 
     117                        this.nativeProcess.destroy(); 
     118                        this.nativeProcess = null; 
     119                } 
    106120                this.nativeStderr = null; 
     121        } 
     122 
     123        private long lastCalled = System.currentTimeMillis(); 
    107124 
     125        /** 
     126         * Retrieves when the bridge was last called. In other words 
     127         * when a command was send for the last time. 
     128         *  
     129         * @return 
     130         *                      The time when the bridge was last called. 
     131         */ 
     132        public long getLastCalled() { 
     133                return this.lastCalled; 
    108134        } 
    109135 
    110136        /** 
     
    113139         * @return The native standard input 
    114140         */ 
    115141        protected OutputStream getNativeStdin() { 
    116                 return this.nativeProcess.getOutputStream(); 
     142                return getNativeProcess().getOutputStream(); 
    117143        } 
    118144 
    119145        /** 
     
    122148         * @return The native standard output 
    123149         */ 
    124150        protected InputStream getNativeStdout() { 
    125                 return this.nativeProcess.getInputStream(); 
     151                return getNativeProcess().getInputStream(); 
    126152        } 
    127153 
    128154        /** 
     
    170196                } 
    171197                return getNativeFile(prefix + getExecutableName() + suffix).getAbsolutePath(); 
    172198        } 
    173          
     199 
    174200        private File getNativeFile(String path) { 
    175 //              //TODO: development version 
    176 //              final String nativesFolder = "sophie2-native"; 
    177 //              File root = new File(".").getAbsoluteFile(); 
    178 //              while (!Arrays.asList(root.list()).contains(nativesFolder)) { 
    179 //                      root = root.getParentFile(); 
    180 //              } 
    181 //              return new File(root.getAbsolutePath() + "/sophie2-native/target/" + path); 
    182                  
     201                //              //TODO: development version 
     202                //              final String nativesFolder = "sophie2-native"; 
     203                //              File root = new File(".").getAbsoluteFile(); 
     204                //              while (!Arrays.asList(root.list()).contains(nativesFolder)) { 
     205                //                      root = root.getParentFile(); 
     206                //              } 
     207                //              return new File(root.getAbsolutePath() + "/sophie2-native/target/" + path); 
     208 
    183209                //Release version: 
    184210                File nativeFile = FileEntryManager.get().getWritableFileEntry("natives/" + path); 
    185211                String[] commands = new String[] {"chmod", "+x", nativeFile.getAbsolutePath()}; 
     
    192218                        } 
    193219                } 
    194220                return nativeFile; 
    195                  
     221 
    196222        } 
    197223 
    198224        /** 
     
    299325         * @return A {@link Response} for the sent {@link Command} 
    300326         */ 
    301327        public <T extends Response> T sendCommand(Command command, Class<T> expectedClass) { 
    302                 assert isRunning(); 
     328                long now = System.currentTimeMillis(); 
     329                this.lastCalled = now; 
     330 
    303331                writeCommand(command); 
    304332                // SophieLog.trace("Sent " + command); 
    305333                dumpError(); 
     
    316344         *            to be written to stdin of the process 
    317345         */ 
    318346        protected void writeCommand(Command command) { 
    319                 assert isRunning(); 
     347                //assert isRunning(); 
    320348                try { 
    321349                        int size = command.getData().getSize(); 
    322350                        // SophieLog.trace("command sending to native: ID = " 
     
    347375         * @return A {@link Response} read from the stdout of the process 
    348376         */ 
    349377        protected <T extends Response> T readResponse(Class<T> expectedClass) { 
    350                 assert isRunning(); 
     378                //assert isRunning(); 
    351379                try { 
    352380                        BinData data = Message.readData(getNativeStdout()); 
    353381                        dumpError(); 
  • modules/org.sophie2.base.natlib/src/main/java/org/sophie2/base/natlib/NativeBridgeRegistry.java

     
     1package org.sophie2.base.natlib; 
     2 
     3import java.util.Comparator; 
     4import java.util.Timer; 
     5import java.util.TimerTask; 
     6import java.util.TreeSet; 
     7 
     8/** 
     9 * Registry for the {@link NativeBridge}s. All the bridges when started are 
     10 * registered and if they are not used for some defined time, they are cleared 
     11 * from the registry and stopped. 
     12 *  
     13 * The registry is singleton for now... 
     14 *  
     15 * @author meddle 
     16 */ 
     17public class NativeBridgeRegistry { 
     18 
     19        /** 
     20         * The time period, the registry checks if there are native processes 
     21         * that are not active for too long. 
     22         */ 
     23        private final static long UPDATE_PERIOD = 5000; 
     24         
     25        /** 
     26         * The maximum time one process should be not active before it is stopped.  
     27         */ 
     28        private final static long TIME_OUT = 4000; 
     29 
     30        private static NativeBridgeRegistry instance = null; 
     31 
     32        /** 
     33         * Implementation of the {@link Comparator} interface to take in 
     34         * mind the {@link NativeBridge#getLastCalled()} when comparing. 
     35         *  
     36         * @author meddle 
     37         */ 
     38        protected static class BridgeComparator implements Comparator<NativeBridge> { 
     39 
     40                public int compare(NativeBridge bridge1, NativeBridge bridge2) { 
     41                        if (bridge1.getLastCalled() > bridge2.getLastCalled()) { 
     42                                return 1; 
     43                        } else if (bridge1.getLastCalled() < bridge2.getLastCalled()) { 
     44                                return -1; 
     45                        } 
     46 
     47                        return 0; 
     48                } 
     49 
     50        } 
     51 
     52        private final Timer timer; 
     53 
     54        private TreeSet<NativeBridge> bridges; 
     55 
     56        /** 
     57         * The {@link TimerTask} that stops the not active native processes. 
     58         *  
     59         * @author meddle 
     60         */ 
     61        protected class ActivityObserver extends TimerTask { 
     62                private final static float SUSPEND_PROCENT = 0.20f; 
     63 
     64                @Override 
     65                @SuppressWarnings("synthetic-access") 
     66                public void run() { 
     67                        synchronized (NativeBridgeRegistry.this.bridges) { 
     68                                TreeSet<NativeBridge> sortedBridges = new TreeSet<NativeBridge>(new BridgeComparator()); 
     69                                sortedBridges.addAll(NativeBridgeRegistry.this.bridges); 
     70 
     71                                NativeBridgeRegistry.this.bridges = sortedBridges; 
     72                                clearSuspended(); 
     73                        } 
     74                } 
     75 
     76                @SuppressWarnings("synthetic-access") 
     77                private void clearSuspended() { 
     78                        int size = NativeBridgeRegistry.this.bridges.size(); 
     79                        int index = (int) Math.ceil(size * SUSPEND_PROCENT); 
     80                        long now = System.currentTimeMillis(); 
     81                         
     82                        for (int i = 0; i < index; i++) { 
     83 
     84                                NativeBridge first = NativeBridgeRegistry.this.bridges.first(); 
     85 
     86                                long suspend = now - first.getLastCalled(); 
     87                                if (suspend >= TIME_OUT) { 
     88                                        NativeBridgeRegistry.this.unregister(); 
     89                                } else { 
     90                                        break; 
     91                                } 
     92                        } 
     93                } 
     94        } 
     95 
     96        private NativeBridgeRegistry() { 
     97                this.bridges = new TreeSet<NativeBridge>(new BridgeComparator()); 
     98                this.timer = new Timer(true); 
     99 
     100                this.timer.schedule(new ActivityObserver(), 0, UPDATE_PERIOD); 
     101        } 
     102 
     103        /** 
     104         * Getter for the {@link NativeBridge}s registered. 
     105         *  
     106         * @return 
     107         *                      The sorted set of the bridges. 
     108         */ 
     109        protected TreeSet<NativeBridge> getBridges() { 
     110                return this.bridges; 
     111        } 
     112         
     113        /** 
     114         * Getter of the instance of the singleton. 
     115         *  
     116         * @return 
     117         *                      The instance. 
     118         */ 
     119        public static NativeBridgeRegistry get() { 
     120                if (instance == null) { 
     121                        instance = new NativeBridgeRegistry(); 
     122                } 
     123 
     124                return instance; 
     125        } 
     126 
     127        /** 
     128         * Registers a {@link NativeBridge} in the registry. 
     129         *  
     130         * @param bridge 
     131         *                              The bridge to register. 
     132         */ 
     133        public void register(NativeBridge bridge) { 
     134                synchronized (this.bridges) { 
     135                        if (!this.bridges.contains(bridge)) { 
     136                                this.bridges.add(bridge); 
     137                        } 
     138                } 
     139        } 
     140 
     141        /** 
     142         * Unregisters and stops a bridge from the registry. 
     143         *  
     144         * @param bridge 
     145         *                              The bridge to unregister. 
     146         */ 
     147        public void unregister(NativeBridge bridge) { 
     148                synchronized (this.bridges) { 
     149                        if (this.bridges.contains(bridge)) { 
     150                                if (bridge.isRunning()) { 
     151                                        bridge.stop(); 
     152                                } 
     153 
     154                                this.bridges.remove(bridge); 
     155                        } 
     156                } 
     157        } 
     158 
     159        /** 
     160         * Unregisters and stops the first bridge in the registry. 
     161         */ 
     162        private void unregister() { 
     163                if (this.bridges.first().isRunning()) { 
     164                        this.bridges.first().stop(); 
     165                } 
     166 
     167                this.bridges.remove(this.bridges.first()); 
     168        } 
     169         
     170        /** 
     171         * Unregisters all the processes from the registry. 
     172         */ 
     173        public void unregisterAll() { 
     174                while (!this.bridges.isEmpty()) { 
     175                        unregister(); 
     176                } 
     177        } 
     178} 
  • modules/org.sophie2.main.media.natlib/src/main/java/org/sophie2/main/media/natlib/decoder/NativeMediaHandler.java

     
    161161         
    162162        private final AudioThread audioThread;  
    163163 
    164  
    165  
    166164        /** 
    167165         * Constructs by the file data. 
    168166         *