OSDN Git Service

[changed] Everything about files!
authornathan.sweet <nathan.sweet@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Wed, 17 Nov 2010 05:41:46 +0000 (05:41 +0000)
committernathan.sweet <nathan.sweet@6c4fd544-2939-11df-bb46-9574ba5d0bfa>
Wed, 17 Nov 2010 05:41:46 +0000 (05:41 +0000)
[changed] BitmapFontTest back to using y-up coords. There is a BitmapFontFlippedTest for a reason!

26 files changed:
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/AndroidAudio.java
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/AndroidFileHandle.java
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/AndroidFiles.java
backends/gdx-backend-android/src/com/badlogic/gdx/backends/android/AndroidGraphics.java
backends/gdx-backend-lwjgl/src/com/badlogic/gdx/backends/lwjgl/LwjglFileHandle.java
backends/gdx-backend-lwjgl/src/com/badlogic/gdx/backends/lwjgl/LwjglFiles.java
backends/gdx-backend-lwjgl/src/com/badlogic/gdx/backends/lwjgl/LwjglGraphics.java
backends/gdx-backend-lwjgl/src/com/badlogic/gdx/backends/lwjgl/LwjglMusic.java
backends/gdx-backend-lwjgl/src/com/badlogic/gdx/backends/lwjgl/LwjglSound.java
backends/gdx-backend-lwjgl/src/com/badlogic/gdx/backends/lwjgl/LwjglTexture.java
extensions/hiero/src/com/badlogic/gdx/hiero/BMFontUtil.java
extensions/hiero/src/com/badlogic/gdx/hiero/unicodefont/HieroSettings.java
extensions/hiero/src/com/badlogic/gdx/hiero/unicodefont/UnicodeFont.java
extensions/image-packer/.classpath
extensions/twl/gdx-twl/src/com/badlogic/gdx/twl/TWL.java
extensions/twl/gdx-twl/src/com/badlogic/gdx/twl/renderer/GdxRenderer.java
gdx/src/com/badlogic/gdx/Files.java
gdx/src/com/badlogic/gdx/files/FileHandle.java
gdx/src/com/badlogic/gdx/files/FileHandleStream.java [new file with mode: 0644]
gdx/src/com/badlogic/gdx/graphics/BitmapFont.java
gdx/src/com/badlogic/gdx/graphics/particles/ParticleEffect.java
tests/gdx-tests/src/com/badlogic/gdx/tests/BitmapFontTest.java
tests/gdx-tests/src/com/badlogic/gdx/tests/FilesTest.java
tests/gdx-tests/src/com/badlogic/gdx/tests/MD5Test.java
tests/gdx-tests/src/com/badlogic/gdx/tests/ObjTest.java
tests/gdx-tests/src/com/badlogic/gdx/tests/ParticleEmitterTest.java

index e02aa68..c40117b 100644 (file)
@@ -20,6 +20,7 @@ import android.media.AudioManager;
 import android.media.MediaPlayer;\r
 import android.media.SoundPool;\r
 import com.badlogic.gdx.Audio;\r
+import com.badlogic.gdx.Files.FileType;\r
 import com.badlogic.gdx.audio.AudioDevice;\r
 import com.badlogic.gdx.audio.AudioRecorder;\r
 import com.badlogic.gdx.audio.Music;\r
@@ -81,9 +82,9 @@ public final class AndroidAudio implements Audio {
 \r
                MediaPlayer mediaPlayer = new MediaPlayer();\r
 \r
-               if (aHandle.isAsset()) {\r
+               if (aHandle.type() == FileType.Internal) {\r
                        try {\r
-                               AssetFileDescriptor descriptor = aHandle.getAssetManager().openFd(aHandle.getPath());\r
+                               AssetFileDescriptor descriptor = aHandle.assets.openFd(aHandle.path());\r
                                mediaPlayer.setDataSource(descriptor.getFileDescriptor(), descriptor.getStartOffset(), descriptor.getLength());\r
                                descriptor.close();\r
                                mediaPlayer.prepare();\r
@@ -91,17 +92,18 @@ public final class AndroidAudio implements Audio {
                                musics.add(music);\r
                                return music;\r
                        } catch (Exception ex) {\r
-                               throw new GdxRuntimeException("Couldn't load Music from file '" + file + "'", ex);\r
+                               throw new GdxRuntimeException("Error loading audio file: " + file\r
+                                       + "\nNote: Internal audio files must be placed in the assets directory.", ex);\r
                        }\r
                } else {\r
                        try {\r
-                               mediaPlayer.setDataSource(aHandle.getPath());\r
+                               mediaPlayer.setDataSource(aHandle.path());\r
                                mediaPlayer.prepare();\r
                                AndroidMusic music = new AndroidMusic(this, mediaPlayer);\r
                                musics.add(music);\r
                                return music;\r
                        } catch (Exception ex) {\r
-                               throw new GdxRuntimeException("Couldn't load music from file '" + file + "'", ex);\r
+                               throw new GdxRuntimeException("Error loading audio file: " + file, ex);\r
                        }\r
                }\r
 \r
@@ -112,20 +114,21 @@ public final class AndroidAudio implements Audio {
         */\r
        @Override public Sound newSound (FileHandle file) {\r
                AndroidFileHandle aHandle = (AndroidFileHandle)file;\r
-               if (aHandle.isAsset()) {\r
+               if (aHandle.type() == FileType.Internal) {\r
                        try {\r
-                               AssetFileDescriptor descriptor = aHandle.getAssetManager().openFd(aHandle.getPath());\r
+                               AssetFileDescriptor descriptor = aHandle.assets.openFd(aHandle.path());\r
                                AndroidSound sound = new AndroidSound(soundPool, manager, soundPool.load(descriptor, 1));\r
                                descriptor.close();\r
                                return sound;\r
-                       } catch (IOException e) {\r
-                               throw new GdxRuntimeException("Couldn't load Sound from file '" + file + "'", e);\r
+                       } catch (IOException ex) {\r
+                               throw new GdxRuntimeException("Error loading audio file: " + file\r
+                                       + "\nNote: Internal audio files must be placed in the assets directory.", ex);\r
                        }\r
                } else {\r
                        try {\r
-                               return new AndroidSound(soundPool, manager, soundPool.load(aHandle.getPath(), 1));\r
-                       } catch (Exception e) {\r
-                               throw new GdxRuntimeException("Couldn't load Sound from file '" + file + "'", e);\r
+                               return new AndroidSound(soundPool, manager, soundPool.load(aHandle.path(), 1));\r
+                       } catch (Exception ex) {\r
+                               throw new GdxRuntimeException("Error loading audio file: " + file, ex);\r
                        }\r
                }\r
        }\r
index 3ccb16b..7b7de99 100644 (file)
 \r
 package com.badlogic.gdx.backends.android;\r
 \r
+import java.io.File;\r
 import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
 import java.io.IOException;\r
 import java.io.InputStream;\r
+import java.io.OutputStream;\r
 \r
 import android.content.res.AssetManager;\r
 \r
@@ -24,58 +28,82 @@ import com.badlogic.gdx.files.FileHandle;
 import com.badlogic.gdx.utils.GdxRuntimeException;\r
 \r
 /**\r
- * A {@link FileHandle} implementation for Android. Encapsulates assets and\r
- * files on the external storage device.\r
- * \r
  * @author mzechner\r
- * \r
+ * @author Nathan Sweet <misc@n4te.com>\r
  */\r
-public class AndroidFileHandle implements FileHandle {\r
-       /** the asset manager or null if this is an external file **/\r
-       private final AssetManager manager;\r
+public class AndroidFileHandle extends FileHandle {\r
+       // The asset manager, or null if this is an external file.\r
+       final AssetManager assets;\r
 \r
-       /** the filename **/\r
-       private final String filename;  \r
+       AndroidFileHandle (AssetManager manager, File file, FileType type) {\r
+               super(file, type);\r
+               this.assets = manager;\r
+       }\r
 \r
-       AndroidFileHandle(AssetManager manager, String filename) {\r
-               this.manager = manager;\r
-               this.filename = filename;               \r
+       public FileHandle child (String name) {\r
+               return new AndroidFileHandle(assets, new File(file, name), type);\r
        }\r
 \r
-       /**\r
-        * @return whether this is an asset file or an external file\r
-        */\r
-       public boolean isAsset() {\r
-               return manager != null;\r
+       public FileHandle parent () {\r
+               File parent = file.getParentFile();\r
+               if (parent == null) {\r
+                       if (type == FileType.Absolute)\r
+                               parent = new File("/");\r
+                       else\r
+                               parent = new File(".");\r
+               }\r
+               return new AndroidFileHandle(assets, parent, type);\r
        }\r
 \r
-       /**\r
-        * @return the {@link AssetManager} or null\r
-        */\r
-       public AssetManager getAssetManager() {\r
-               return manager;\r
+       public InputStream read () {\r
+               if (type == FileType.Internal) {\r
+                       InputStream input = FileHandle.class.getResourceAsStream("/" + file.getPath());\r
+                       if (input != null) return input;\r
+                       try {\r
+                               return assets.open(file.getPath());\r
+                       } catch (IOException ex) {\r
+                               throw new GdxRuntimeException("Error reading file: " + file + " (" + type + ")", ex);\r
+                       }\r
+               }\r
+               return super.read();\r
        }\r
 \r
-       /**\r
-        * @return the filename\r
-        */\r
-       public String getPath() {\r
-               return filename;\r
+       public FileHandle[] list () {\r
+               if (type == FileType.Internal) {\r
+                       try {\r
+                               String[] relativePaths = assets.list(file.getPath());\r
+                               FileHandle[] handles = new FileHandle[relativePaths.length];\r
+                               for (int i = 0, n = handles.length; i < n; i++)\r
+                                       handles[i] = new AndroidFileHandle(assets, new File(file, relativePaths[i]), type);\r
+                       } catch (Exception ex) {\r
+                               throw new GdxRuntimeException("Error listing children: " + file + " (" + type + ")", ex);\r
+                       }\r
+               }\r
+               return super.list();\r
        }\r
 \r
-       public InputStream readFile() {\r
-               try {\r
-                       if (manager!=null) {\r
-                               return manager.open(filename);\r
-                       } else {\r
-                               return new FileInputStream(filename);\r
+       public boolean isDirectory () {\r
+               if (type == FileType.Internal) {\r
+                       try {\r
+                               assets.list(file.getPath());\r
+                               return true;\r
+                       } catch (Exception ex) {\r
+                               return false;\r
                        }\r
-               } catch (IOException ex) {\r
-                       throw new GdxRuntimeException("Error reading file: " + filename);\r
                }\r
+               return super.isDirectory();\r
        }\r
 \r
-       public String toString() {\r
-               return filename;\r
+       public boolean exists () {\r
+               if (type == FileType.Internal) {\r
+                       try {\r
+                               InputStream in = assets.open(file.getPath());\r
+                               in.close();\r
+                               return true;\r
+                       } catch (Exception ex) {\r
+                               return false;\r
+                       }\r
+               }\r
+               return super.exists();\r
        }\r
 }\r
index 67ebae8..6f3c3cb 100644 (file)
 \r
 package com.badlogic.gdx.backends.android;\r
 \r
+import java.io.File;\r
+import java.io.InputStream;\r
+\r
 import android.content.res.AssetManager;\r
 import android.os.Environment;\r
+\r
 import com.badlogic.gdx.Files;\r
 import com.badlogic.gdx.files.FileHandle;\r
 import com.badlogic.gdx.utils.GdxRuntimeException;\r
 \r
-import java.io.*;\r
-\r
 /**\r
  * An implementation of the {@link Files} interface for Android. External files are stored and accessed relative to\r
  * Environment.getExternalStorageDirectory().getAbsolutePath(). Internal files are accessed relative to the assets directory.\r
@@ -29,178 +31,50 @@ import java.io.*;
  * \r
  */\r
 public class AndroidFiles implements Files {\r
-       /** external storage path **/\r
        protected final String sdcard = Environment.getExternalStorageDirectory().getAbsolutePath() + "/";\r
-\r
-       /** asset manager **/\r
        protected final AssetManager assets;\r
 \r
        public AndroidFiles (AssetManager assets) {\r
                this.assets = assets;\r
        }\r
 \r
-       /**\r
-        * @return the asset manager.\r
-        */\r
-       protected AssetManager getAssetManager () {\r
-               return assets;\r
-       }\r
-\r
-       private InputStream readExternalFile (String fileName) {\r
-               FileInputStream in = null;\r
-\r
-               try {\r
-                       in = new FileInputStream(sdcard + fileName);\r
-               } catch (FileNotFoundException ex) {\r
-                       throw new GdxRuntimeException("File not found: " + fileName + " (" + FileType.External + ")", ex);\r
-               }\r
-\r
-               return in;\r
-       }\r
-\r
-       private InputStream readInternalFile (String fileName) {\r
-               InputStream in = null;\r
-               try {\r
-                       in = assets.open(fileName);\r
-               } catch (Exception ex) {\r
-                       throw new GdxRuntimeException("Unable to read file: " + fileName + " (" + FileType.Internal + ")", ex);\r
-               }\r
-\r
-               return in;\r
-       }\r
-\r
-       private OutputStream writeExternalFile (String filename) {\r
-               FileOutputStream out = null;\r
-\r
-               try {\r
-                       out = new FileOutputStream(sdcard + filename);\r
-               } catch (FileNotFoundException ex) {\r
-                       throw new GdxRuntimeException("File not found: " + filename + " (" + FileType.External + ")", ex);\r
-               }\r
-\r
-               return out;\r
-       }\r
-\r
-       private InputStream readAbsoluteFile (String filename) {\r
-               FileInputStream in = null;\r
-\r
-               try {\r
-                       in = new FileInputStream(filename);\r
-               } catch (FileNotFoundException ex) {\r
-                       throw new GdxRuntimeException("File not found: " + filename + " (" + FileType.Absolute + ")", ex);\r
-               }\r
-\r
-               return in;\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public FileHandle getFileHandle (String filename, FileType type) {\r
+       @Override public FileHandle getFileHandle (String fileName, FileType type) {\r
+               File file;\r
                if (type == FileType.Internal) {\r
-                       boolean exists = true;\r
-\r
-                       try {\r
-                               InputStream in = assets.open(filename);\r
-                               in.close();\r
-                       } catch (Exception ex) {\r
-                               exists = false;\r
+                       file = new File(fileName);\r
+                       if (FileHandle.class.getResourceAsStream("/" + fileName) == null) {\r
+                               try {\r
+                                       InputStream in = assets.open(fileName);\r
+                                       in.close();\r
+                               } catch (Exception ignored) {\r
+                               }\r
                        }\r
-\r
-                       if (!exists)\r
-                               throw new GdxRuntimeException("File not found: " + filename + " (" + type + ")");\r
-                       else\r
-                               return new AndroidFileHandle(assets, filename);\r
-               }\r
-\r
-               if (type == FileType.External) {\r
-                       if (new File(sdcard + filename).exists() == false)\r
-                               throw new GdxRuntimeException("File not found: " + filename + " (" + type + ")");\r
-                       else\r
-                               return new AndroidFileHandle(null, sdcard + filename);\r
                } else {\r
-                       if (new File(filename).exists() == false)\r
-                               throw new GdxRuntimeException("File not found: " + filename + " (" + type + ")");\r
+                       if (type == FileType.External)\r
+                               file = new File(sdcard + fileName);\r
                        else\r
-                               return new AndroidFileHandle(null, filename);\r
+                               file = new File(fileName);\r
                }\r
+               return new AndroidFileHandle(assets, file, type);\r
        }\r
 \r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public String[] listDirectory (String directory, FileType type) {\r
-               if (type == FileType.Internal) {\r
-                       try {\r
-                               return assets.list(directory);\r
-                       } catch (Exception ex) {\r
-                               throw new GdxRuntimeException("Unable to open directory: " + directory);\r
-                       }\r
-               }\r
-\r
-               if (type == FileType.External) {\r
-                       if (new File(sdcard + directory).exists() == false)\r
-                               throw new GdxRuntimeException("Unable to open directory: " + directory);\r
-                       else\r
-                               return new File(sdcard + directory).list();\r
-               } else {\r
-                       if (new File(directory).exists() == false)\r
-                               throw new GdxRuntimeException("Unable to open directory: " + directory);\r
-                       else\r
-                               return new File(directory).list();\r
-               }\r
+       @Override public FileHandle internal (String path) {\r
+               return getFileHandle(path, FileType.Internal);\r
        }\r
 \r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public boolean makeDirectory (String directory, FileType type) {\r
-               if (type == FileType.Internal) return false;\r
-\r
-               if (type == FileType.External)\r
-                       return new File(sdcard + directory).mkdirs();\r
-               else\r
-                       return new File(directory).mkdirs();\r
+       @Override public FileHandle external (String path) {\r
+               return getFileHandle(path, FileType.External);\r
        }\r
 \r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public InputStream readFile (String fileName, FileType type) {\r
-               if (type == FileType.Internal) return readInternalFile(fileName);\r
-               if (type == FileType.External)\r
-                       return readExternalFile(fileName);\r
-               else\r
-                       return readAbsoluteFile(fileName);\r
-       }\r
-\r
-       /**\r
-        * {@inheritDoc}\r
-        */\r
-       @Override public OutputStream writeFile (String filename, FileType type) {\r
-               if (type == FileType.Internal) return null;\r
-               if (type == FileType.External)\r
-                       return writeExternalFile(filename);\r
-               else {\r
-                       FileOutputStream out = null;\r
-\r
-                       try {\r
-                               out = new FileOutputStream(filename);\r
-                       } catch (FileNotFoundException ex) {\r
-                               throw new GdxRuntimeException("File not found: " + filename + " (" + type + ")", ex);\r
-                       }\r
-\r
-                       return out;\r
-               }\r
+       @Override public FileHandle absolute (String path) {\r
+               return getFileHandle(path, FileType.Absolute);\r
        }\r
 \r
-       @Override\r
-       public String getExternalStoragePath() {\r
+       @Override public String getExternalStoragePath () {\r
                return sdcard;\r
        }\r
 \r
-       @Override\r
-       public boolean isExternalStorageAvailable() {\r
+       @Override public boolean isExternalStorageAvailable () {\r
                return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);\r
        }\r
 }\r
index 66bec18..46723cb 100644 (file)
@@ -222,7 +222,7 @@ public final class AndroidGraphics implements Graphics, Renderer {
         */\r
        @Override\r
        public Pixmap newPixmap(FileHandle file) {\r
-               return newPixmap(file.readFile());\r
+               return newPixmap(file.read());\r
        }\r
 \r
        /**\r
index 6447f67..564d1df 100644 (file)
@@ -16,52 +16,35 @@ package com.badlogic.gdx.backends.lwjgl;
 import java.io.File;\r
 import java.io.FileInputStream;\r
 import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
 import java.io.InputStream;\r
+import java.io.OutputStream;\r
 \r
 import com.badlogic.gdx.Files.FileType;\r
 import com.badlogic.gdx.files.FileHandle;\r
 import com.badlogic.gdx.utils.GdxRuntimeException;\r
 \r
 /**\r
- * A {@link FileHandle} implementation for the desktop.\r
- * \r
  * @author mzechner\r
- * \r
+ * @author Nathan Sweet <misc@n4te.com>\r
  */\r
-final class LwjglFileHandle implements FileHandle {\r
-       /** the file **/\r
-       private final File file;\r
-       private final FileType type;\r
-\r
+final class LwjglFileHandle extends FileHandle {\r
        LwjglFileHandle (File file, FileType type) {\r
-               this.file = file;\r
-               this.type = type;\r
+               super(file, type);\r
        }\r
 \r
-       /**\r
-        * @return the underlying {@link File}.\r
-        */\r
-       public File getFile () {\r
-               return file;\r
+       public FileHandle child (String name) {\r
+               return new LwjglFileHandle(new File(file, name), type);\r
        }\r
 \r
-       public InputStream readFile () {\r
-               if (type == FileType.Internal) {\r
-                       InputStream input = LwjglFileHandle.class.getResourceAsStream("/" + file);\r
-                       if (input != null) return input;\r
-               }\r
-               try {\r
-                       return new FileInputStream(file);\r
-               } catch (FileNotFoundException ex) {\r
-                       throw new GdxRuntimeException("Error reading file: " + file);\r
+       public FileHandle parent () {\r
+               File parent = file.getParentFile();\r
+               if (parent == null) {\r
+                       if (type == FileType.Absolute)\r
+                               parent = new File("/");\r
+                       else\r
+                               parent = new File(".");\r
                }\r
-       }\r
-\r
-       public String toString () {\r
-               return file.toString();\r
-       }\r
-       \r
-       @Override public String getPath() {\r
-               return file.toString();\r
+               return new LwjglFileHandle(parent, type);\r
        }\r
 }\r
index 37a9c88..deca2aa 100644 (file)
 package com.badlogic.gdx.backends.lwjgl;\r
 \r
 import java.io.File;\r
-import java.io.FileInputStream;\r
-import java.io.FileNotFoundException;\r
-import java.io.FileOutputStream;\r
-import java.io.InputStream;\r
-import java.io.OutputStream;\r
 \r
 import com.badlogic.gdx.Files;\r
-import com.badlogic.gdx.Files.FileType;\r
 import com.badlogic.gdx.files.FileHandle;\r
 import com.badlogic.gdx.utils.GdxRuntimeException;\r
 \r
 /**\r
- * Implementation for a desktop application of {@link Files}. Internal resources are relative to the application root directory,\r
- * external files are relative to the user's home directory.\r
- * \r
  * @author mzechner\r
- * \r
+ * @author Nathan Sweet <misc@n4te.com>\r
  */\r
 final class LwjglFiles implements Files {\r
        private final String externalPath = System.getProperty("user.home") + "/";\r
 \r
-       public FileHandle getFileHandle (String fileName, FileType type) {\r
-               if (type == FileType.External) fileName = this.externalPath + fileName;\r
-               File file = new File(fileName);\r
-\r
-               if (LwjglFileHandle.class.getResource("/" + fileName) == null && file.exists() == false)\r
-                       throw new GdxRuntimeException("File not found: " + fileName + " (" + type + ")");\r
-               else\r
-                       return new LwjglFileHandle(file, type);\r
-       }\r
-\r
-       public String[] listDirectory (String directory, FileType type) {\r
-               if (type == FileType.External) directory = this.externalPath + directory;\r
-               File file = new File(directory);\r
-\r
-               if (file.exists() == false) throw new GdxRuntimeException("Directory not found: " + directory + " (" + type + ")");\r
-\r
-               return file.list();\r
-       }\r
-\r
-       public boolean makeDirectory (String directory, FileType type) {\r
-               if (type == FileType.Internal) return false;\r
-\r
-               File file = null;\r
-               if (type == FileType.Absolute)\r
-                       file = new File(directory);\r
-               else\r
-                       file = new File(this.externalPath + directory);\r
-               return file.mkdirs();\r
-       }\r
-\r
-       public InputStream readFile (String fileName, FileType type) {\r
+       @Override public FileHandle getFileHandle (String fileName, FileType type) {\r
+               File file;\r
                if (type == FileType.External)\r
-                       fileName = this.externalPath + fileName;\r
+                       file = new File(this.externalPath + fileName);\r
                else if (type == FileType.Internal) {\r
-                       InputStream input = LwjglFileHandle.class.getResourceAsStream("/" + fileName);\r
-                       if (input != null) return input;\r
-               }\r
-\r
-               try {\r
-                       return new FileInputStream(fileName);\r
-               } catch (FileNotFoundException ex) {\r
-                       throw new GdxRuntimeException("Error reading file: " + fileName);\r
+                       file = new File(fileName);\r
+                       if (FileHandle.class.getResourceAsStream("/" + fileName) == null && !file.exists())\r
+                               throw new GdxRuntimeException("File not found: " + fileName + " (" + type + ")");\r
                }\r
+               return new LwjglFileHandle(new File(fileName), type);\r
        }\r
 \r
-       public OutputStream writeFile (String fileName, FileType type) {\r
-               if (type == FileType.Internal) return null;\r
+       @Override public FileHandle internal (String path) {\r
+               return getFileHandle(path, FileType.Internal);\r
+       }\r
 \r
-               File file = null;\r
-               if (type == FileType.Absolute)\r
-                       file = new File(fileName);\r
-               else\r
-                       file = new File(this.externalPath + fileName);\r
+       @Override public FileHandle external (String path) {\r
+               return getFileHandle(path, FileType.External);\r
+       }\r
 \r
-               try {\r
-                       return new FileOutputStream(file);\r
-               } catch (FileNotFoundException e) {\r
-                       throw new GdxRuntimeException("File not found: " + fileName + " (" + type + ")");\r
-               }\r
+       @Override public FileHandle absolute (String path) {\r
+               return getFileHandle(path, FileType.Absolute);\r
        }\r
 \r
-       @Override\r
-       public String getExternalStoragePath() {\r
+       @Override public String getExternalStoragePath () {\r
                return externalPath;\r
        }\r
 \r
-       @Override\r
-       public boolean isExternalStorageAvailable() {\r
+       @Override public boolean isExternalStorageAvailable () {\r
                return true;\r
        }\r
 }\r
index 2495ae1..124ae11 100644 (file)
@@ -125,7 +125,7 @@ final class LwjglGraphics implements Graphics {
        }\r
 \r
        public Pixmap newPixmap (FileHandle file) {\r
-               return newPixmap(file.readFile());\r
+               return newPixmap(file.read());\r
        }\r
 \r
        public Pixmap newPixmap (Object nativePixmap) {\r
index 365680e..d33f0ef 100644 (file)
@@ -61,7 +61,7 @@ final class LwjglMusic implements Music, Runnable {
        }\r
 \r
        private void openAudioInputStream () throws UnsupportedAudioFileException, IOException {\r
-               ain = AudioSystem.getAudioInputStream(new BufferedInputStream(handle.readFile()));\r
+               ain = AudioSystem.getAudioInputStream(new BufferedInputStream(handle.read()));\r
                AudioFormat baseFormat = ain.getFormat();\r
                AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16,\r
                        baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);\r
index dabfbc6..2cb795d 100644 (file)
@@ -50,7 +50,7 @@ final class LwjglSound implements Sound {
 \r
        public LwjglSound (LwjglAudio audio, LwjglFileHandle file) throws UnsupportedAudioFileException, IOException {\r
                this.audio = audio;\r
-               InputStream fin = new BufferedInputStream(file.readFile());\r
+               InputStream fin = new BufferedInputStream(file.read());\r
                AudioInputStream ain = AudioSystem.getAudioInputStream(fin);\r
                AudioFormat baseFormat = ain.getFormat();\r
                AudioFormat decodedFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16,\r
index 1cf59b8..0ff396d 100644 (file)
@@ -63,7 +63,7 @@ final class LwjglTexture implements Texture {
                this.isManaged = managed;\r
                this.isMipMapped = TextureFilter.isMipMap(minFilter);\r
 \r
-               if (!isMipMapped && file.getPath().endsWith(".png")) {\r
+               if (!isMipMapped && file.path().endsWith(".png")) {\r
                        // Fast path.\r
                        loadPNG(file);\r
                } else {\r
@@ -130,7 +130,7 @@ final class LwjglTexture implements Texture {
 \r
        private void loadPNG (FileHandle file) {\r
                try {\r
-                       pngDecoder.decodeHeader(file.readFile());\r
+                       pngDecoder.decodeHeader(file.read());\r
                        texWidth = pngDecoder.getWidth();\r
                        texHeight = pngDecoder.getHeight();\r
                        int stride = texWidth * 4;\r
index c488a1d..1a2cfc7 100644 (file)
@@ -111,7 +111,7 @@ public class BMFontUtil {
                else {\r
                        Kerning kerning = new Kerning();\r
                        try {\r
-                               kerning.load(Gdx.files.readFile(ttfFileRef, FileType.Internal), font.getSize());\r
+                               kerning.load(Gdx.files.internal(ttfFileRef).read(), font.getSize());\r
                        } catch (IOException ex) {\r
                                System.out.println("Unable to read kerning information from font: " + ttfFileRef);\r
                        }\r
index 90a9103..2b43339 100644 (file)
@@ -37,7 +37,7 @@ public class HieroSettings {
         */\r
        public HieroSettings (String hieroFileRef) {\r
                try {\r
-                       BufferedReader reader = new BufferedReader(new InputStreamReader(Gdx.files.readFile(hieroFileRef, FileType.Absolute)));\r
+                       BufferedReader reader = new BufferedReader(new InputStreamReader(Gdx.files.absolute(hieroFileRef).read()));\r
                        while (true) {\r
                                String line = reader.readLine();\r
                                if (line == null) break;\r
index 05435b9..c6c2a82 100644 (file)
@@ -772,7 +772,7 @@ public class UnicodeFont {
         */\r
        static private Font createFont (String ttfFileRef) {\r
                try {\r
-                       return Font.createFont(Font.TRUETYPE_FONT, Gdx.files.readFile(ttfFileRef, FileType.Absolute));\r
+                       return Font.createFont(Font.TRUETYPE_FONT, Gdx.files.absolute(ttfFileRef).read());\r
                } catch (FontFormatException ex) {\r
                        throw new GdxRuntimeException("Invalid font: " + ttfFileRef, ex);\r
                } catch (IOException ex) {\r
index 07ca123..ac8c860 100644 (file)
@@ -2,5 +2,6 @@
 <classpath>\r
        <classpathentry kind="src" path="src"/>\r
        <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>\r
+       <classpathentry combineaccessrules="false" kind="src" path="/gdx"/>\r
        <classpathentry kind="output" path="bin"/>\r
 </classpath>\r
index 8b949d5..95b0a54 100644 (file)
@@ -233,7 +233,7 @@ public class TWL implements InputProcessor {
 \r
                                        public InputStream getInputStream () {\r
                                                if (!path.endsWith(".xml")) return null; // Only theme files are loaded through the URL.\r
-                                               return fileHandle.readFile();\r
+                                               return fileHandle.read();\r
                                        }\r
                                };\r
                        }\r
index abd3f29..1104e13 100644 (file)
@@ -226,34 +226,4 @@ public class GdxRenderer implements Renderer {
                        return next;\r
                }\r
        }\r
-\r
-       public void applyTheme (GUI gui, String themeFile, final FileType fileType) {\r
-               File file = new File(themeFile);\r
-               final File themeRoot = file.getParentFile();\r
-               final String themeFileName = file.getName();\r
-               try {\r
-                       URL themeURL = new URL("gdx-twl", "local", 80, themeFileName, new URLStreamHandler() {\r
-                               protected URLConnection openConnection (URL url) throws IOException {\r
-                                       final String path = new File(themeRoot, url.getPath()).getPath();\r
-                                       final FileHandle fileHandle = Gdx.files.getFileHandle(path, fileType);\r
-                                       return new URLConnection(url) {\r
-                                               public void connect () {\r
-                                               }\r
-\r
-                                               public Object getContent () {\r
-                                                       return fileHandle;\r
-                                               }\r
-\r
-                                               public InputStream getInputStream () {\r
-                                                       if (!path.endsWith(".xml")) return null; // Only theme files are loaded through the URL.\r
-                                                       return fileHandle.readFile();\r
-                                               }\r
-                                       };\r
-                               }\r
-                       });\r
-                       gui.applyTheme(ThemeManager.createThemeManager(themeURL, this));\r
-               } catch (IOException ex) {\r
-                       throw new GdxRuntimeException("Error loading theme: " + themeFile, ex);\r
-               }\r
-       }\r
 }\r
index ffc7741..75c4a6c 100644 (file)
 \r
 package com.badlogic.gdx;\r
 \r
-import java.io.InputStream;\r
-import java.io.OutputStream;\r
-\r
-import com.badlogic.gdx.Files.FileType;\r
 import com.badlogic.gdx.files.FileHandle;\r
 import com.badlogic.gdx.utils.GdxRuntimeException;\r
 \r
 /**\r
- * <p>This interface encapsulates the access of internal, external and absolute\r
- * files.</p> \r
- * \r
- * <p>\r
- * Internal files are read-only and are bundled with the application. On\r
- * Android internal files map to assets. On the desktop the classpath is first\r
- * searched for the file. If this fails the root directory of the application\r
- * is searched.\r
- * </p>\r
- * \r
- * <p>\r
- * External files can be read and written to. On Android they are relative to\r
- * the SD-card, on the desktop they are relative to the user home directory.\r
- * </p>\r
- * \r
- * <p>\r
- * Absolute files are just that, fully qualified filenames. To ensure\r
- * portability across platforms use absolute files only when absolutely\r
- * necessary.\r
- * </p>\r
- * \r
+ * Provides standard access to the filesystem, classpath, Android SD card, and Android assets directory.\r
  * @author mzechner\r
- * \r
+ * @author Nathan Sweet <misc@n4te.com>\r
  */\r
 public interface Files {\r
        /**\r
-        * Enum describing the three file types, internal, external and absolute.\r
-        * Internal files are located in the asset directory on Android and are\r
-        * relative to the root of the classpath or application's root directory on\r
-        * the desktop. External files are relative to the SD-card on Android and\r
-        * relative to the home directory of the current user on the desktop.\r
-        * Absolute files are just that, absolute files that can point anywhere.\r
-        * \r
+        * Indicates how to resolve a path to a file.\r
         * @author mzechner\r
-        * \r
         */\r
        public enum FileType {\r
-               Internal, External, Absolute\r
+               /**\r
+                * Path relative to the root of the classpath, and if not found there, to the asset directory on Android or the\r
+                * application's root directory on the desktop. Internal files are always readonly.\r
+                */\r
+               Internal,\r
+\r
+               /**\r
+                * Path relative to the root of the SD card on Android and to the home directory of the current user on the desktop.\r
+                */\r
+               External,\r
+\r
+               /**\r
+                * Path that is a fully qualified, absolute filesystem path. To ensure portability across platforms use absolute files only\r
+                * when absolutely necessary.\r
+                */\r
+               Absolute\r
        }\r
 \r
        /**\r
-        * Returns an {@link InputStream} to the given file. If type is equal to\r
-        * {@link FileType#Internal} an internal file will be opened. On Android\r
-        * this is relative to the assets directory, on the desktop it is relative\r
-        * to the applications classpath or if that fails to the root directory. If \r
-        * type is equal to {@link FileType#External} an external file will be opened. On Android\r
-        * this is relative to the SD-card, on the desktop it is relative to the\r
-        * current user's home directory. If type is equal to\r
-        * {@link FileType#Absolute} the filename is interpreted as an absolute\r
-        * filename.\r
-        * \r
-        * @param fileName\r
-        *            the name of the file to open.\r
-        * @param type\r
-        *            the type of file to open.\r
-        * @return the InputStream\r
-        * @throws GdxRuntimeException\r
-        *             in case the file could not be opened.\r
+        * Returns a handle representing a file or directory.\r
+        * @param type Determines how the path is resolved.\r
+        * @throws GdxRuntimeException if the type is internal and the file does not exist.\r
+        * @see FileType\r
         */\r
-       public InputStream readFile(String fileName, FileType type);\r
+       public FileHandle getFileHandle (String path, FileType type);\r
 \r
        /**\r
-        * Returns and {@link OutputStream} to the given file. If the file does not\r
-        * exist it is created. If the file exists it will be overwritten. If type\r
-        * is equal to {@link FileType#Internal} an exception is thrown. If type is \r
-        * equal to {@link FileType#External} an external file will be opened. On Android this is relative to the\r
-        * SD-card, on the desktop it is relative to the current user's home\r
-        * directory. If type is equal to {@link FileType#Absolute} the filename is\r
-        * interpreted as an absolute filename.\r
-        * \r
-        * @param filename\r
-        *            the name of the file to open\r
-        * @param type\r
-        *            the type of the file to open\r
-        * @return the OutputStream\r
-        * @throws GdxRuntimeException\r
-        *             in case the file could not be opened or type equals {@link FileType#Internal}\r
+        * Convenience method that returns an {@link FileType#Internal} file handle.\r
         */\r
-       public OutputStream writeFile(String filename, FileType type);\r
+       public FileHandle internal (String path);\r
 \r
        /**\r
-        * Creates a new directory or directory hierarchy on the external storage.\r
-        * If the directory parameter contains sub folders and the parent folders\r
-        * don't exist yet they will be created. If type is equal to\r
-        * {@link FileType#Internal} false will be returned. If type is equal\r
-        * to {@link FileType#External} an external directory will be created. On\r
-        * Android this is relative to the SD-card, on the desktop it is relative to\r
-        * the current user's home directory. If type is equal to\r
-        * {@link FileType#Absolute} the directory is interpreted as an absolute\r
-        * directory name.\r
-        * \r
-        * @param directory\r
-        *            the directory\r
-        * @param type\r
-        *            the type of the directory\r
-        * @return true in case the directory could be created, false otherwise\r
+        * Convenience method that returns an {@link FileType#External} file handle.\r
         */\r
-       public boolean makeDirectory(String directory, FileType type);\r
+       public FileHandle external (String path);\r
 \r
        /**\r
-        * Lists the files and directories in the given directory. If type is equal\r
-        * to {@link FileType#Internal} an internal directory will be listed. On\r
-        * Android this is relative to the assets directory, on the desktop it is\r
-        * relative to the applications root directory. If type is equal to\r
-        * {@link FileType#External} an external directory will be listed. On\r
-        * Android this is relative to the SD-card, on the desktop it is relative to\r
-        * the current user's home directory. If type is equal to\r
-        * {@link FileType#Absolute} the filename is interpreted as an absolute\r
-        * directory.\r
-        * \r
-        * @param directory\r
-        *            the directory\r
-        * @param type\r
-        *            the type of the directory\r
-        * @return the files and directories in the given directory\r
-        * @throws GdxRuntimeException\r
-        *             if the directory does not exist\r
+        * Convenience method that returns an {@link FileType#Absolute} file handle.\r
         */\r
-       public String[] listDirectory(String directory, FileType type);\r
+       public FileHandle absolute (String path);\r
 \r
        /**\r
-        * Returns a {@link FileHandle} object for a file. If type is equal to\r
-        * {@link FileType#Internal} an internal file will be opened. On Android\r
-        * this is relative to the assets directory, on the desktop it is relative\r
-        * to the application's classpath or if that false to the root directory. If type is equal to\r
-        * {@link FileType#External} an external file will be opened. On Android\r
-        * this is relative to the SD-card, on the desktop it is relative to the\r
-        * current user's home directory. If type is equal to\r
-        * {@link FileType#Absolute} the filename is interpreted as an absolute\r
-        * filename.\r
-        * \r
-        * @param filename\r
-        *            the name of the file\r
-        * @param type\r
-        *            the type of the file\r
-        * @return the FileDescriptor or null if the descriptor could not be created\r
-        * @throws GdxRuntimeException\r
-        *             if the file does not exist\r
+        * Returns the external storage path directory. This is the SD card on Android or the home directory of the current user on the\r
+        * desktop.\r
         */\r
-       public FileHandle getFileHandle(String filename, FileType type);\r
-       \r
-       /**\r
-        * @return the external storage path directory, e.g. /sdcard/ on Android or /home/mzechner/ on the desktop.\r
-        */\r
-       public String getExternalStoragePath();\r
-       \r
+       public String getExternalStoragePath ();\r
+\r
        /**\r
-        * @return whether the external storage is available for file i/o\r
+        * Returns true if the external storage is ready for file i/o.\r
         */\r
-       public boolean isExternalStorageAvailable();\r
+       public boolean isExternalStorageAvailable ();\r
 }\r
index 22de0ad..c069dd5 100644 (file)
 \r
 package com.badlogic.gdx.files;\r
 \r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
 import java.io.InputStream;\r
+import java.io.OutputStream;\r
 \r
 import com.badlogic.gdx.Files;\r
 import com.badlogic.gdx.Files.FileType;\r
+import com.badlogic.gdx.utils.GdxRuntimeException;\r
 \r
 /**\r
- * A file handle represents a system dependent representation of an internal or\r
- * external file. FileHandles can only be created via a {@link Files} instance.\r
- * \r
+ * Represents a file or directory on the filesystem, classpath, Android SD card, or Android assets directory. FileHandles are\r
+ * created via a {@link Files} instance.\r
  * @author mzechner\r
- * \r
+ * @author Nathan Sweet <misc@n4te.com>\r
  */\r
-public interface FileHandle {\r
+public abstract class FileHandle {\r
+       protected final File file;\r
+       protected final FileType type;\r
+\r
+       protected FileHandle (File file, FileType type) {\r
+               this.file = file;\r
+               this.type = type;\r
+       }\r
+\r
+       public String path () {\r
+               return file.getPath();\r
+       }\r
+\r
+       public String name () {\r
+               return file.getName();\r
+       }\r
+\r
+       public String extension () {\r
+               String name = file.getName();\r
+               int dotIndex = name.lastIndexOf('.');\r
+               if (dotIndex == -1) return "";\r
+               return name.substring(dotIndex + 1);\r
+       }\r
+\r
+       public String nameWithoutExtension () {\r
+               String name = file.getName();\r
+               int dotIndex = name.lastIndexOf('.');\r
+               if (dotIndex == -1) return name;\r
+               return name.substring(0, dotIndex);\r
+       }\r
+\r
+       public FileType type () {\r
+               return type;\r
+       }\r
+\r
        /**\r
-        * @return a new {@link InputStream} to the underlying file.\r
+        * Returns a stream for reading this file.\r
+        * @throw GdxRuntimeException if this file handle represents a directory or if it could not be read.\r
         */\r
-       public InputStream readFile();\r
+       public InputStream read () {\r
+               if (type == FileType.Internal) {\r
+                       InputStream input = FileHandle.class.getResourceAsStream("/" + file.getPath());\r
+                       if (input != null) return input;\r
+               }\r
+               try {\r
+                       return new FileInputStream(file);\r
+               } catch (FileNotFoundException ex) {\r
+                       throw new GdxRuntimeException("Error reading file: " + file + " (" + type + ")", ex);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Returns a stream for writing to this file.\r
+        * @param append If false, this file will be overwritten if it exists, otherwise it is appended.\r
+        * @throw GdxRuntimeException if this file handle represents a directory, if it is an {@link FileType#Internal} file, or if it\r
+        *        could not be written.\r
+        */\r
+       public OutputStream write (boolean append) {\r
+               if (type == FileType.Internal) throw new GdxRuntimeException("Cannot write to an internal file: " + file);\r
+               try {\r
+                       return new FileOutputStream(file, append);\r
+               } catch (FileNotFoundException ex) {\r
+                       throw new GdxRuntimeException("Error writing file: " + file + " (" + type + ")", ex);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Returns the paths to the children of this directory. Returns an empty list if this file handle represents a file and not a\r
+        * directory.\r
+        * @throw GdxRuntimeException if this file is an {@link FileType#Internal} file.\r
+        */\r
+       public FileHandle[] list () {\r
+               String[] relativePaths = file.list();\r
+               if (relativePaths == null) return new FileHandle[0];\r
+               FileHandle[] handles = new FileHandle[relativePaths.length];\r
+               for (int i = 0, n = relativePaths.length; i < n; i++)\r
+                       handles[i] = child(relativePaths[i]);\r
+               return handles;\r
+       }\r
+\r
+       public boolean isDirectory () {\r
+               if (type == FileType.Internal) return false; // BOZO - This works on Android, where internal is assets dir.\r
+               return file.isDirectory();\r
+\r
+       }\r
+\r
+       abstract public FileHandle child (String name);\r
+\r
+       abstract public FileHandle parent ();\r
 \r
        /**\r
-        * @return the path to the file.\r
+        * @throw GdxRuntimeException if this file handle is an {@link FileType#Internal} file.\r
         */\r
-       public String getPath();\r
+       public void mkdirs () {\r
+               if (type == FileType.Internal) throw new GdxRuntimeException("Cannot mkdirs with an internal file: " + file);\r
+               file.mkdirs();\r
+       }\r
+\r
+       public boolean exists () {\r
+               return file.exists();\r
+       }\r
+\r
+       /**\r
+        * Deletes this file or empty directory and returns success. Will not delete a directory that has children.\r
+        * @throw GdxRuntimeException if this file handle is an {@link FileType#Internal} file.\r
+        */\r
+       public boolean delete () {\r
+               if (type == FileType.Internal) throw new GdxRuntimeException("Cannot delete an internal file: " + file);\r
+               return file.delete();\r
+       }\r
+\r
+       /**\r
+        * Deletes this file or directory and all children, recursively.\r
+        * @throw GdxRuntimeException if this file handle is an {@link FileType#Internal} file.\r
+        */\r
+       public boolean deleteDirectory () {\r
+               if (type == FileType.Internal) throw new GdxRuntimeException("Cannot delete an internal file: " + file);\r
+               return deleteDirectory(file);\r
+       }\r
+\r
+       /**\r
+        * Copies this file to the specified file, overwriting the file if it already exists.\r
+        * @throw GdxRuntimeException if the destination file handle is an {@link FileType#Internal} file.\r
+        */\r
+       public void copyTo (FileHandle dest) {\r
+               InputStream input = null;\r
+               OutputStream output = null;\r
+               try {\r
+                       input = read();\r
+                       output = dest.write(false);\r
+                       byte[] buffer = new byte[4096];\r
+                       while (true) {\r
+                               int length = input.read(buffer);\r
+                               if (length == -1) break;\r
+                               output.write(buffer, 0, length);\r
+                       }\r
+               } catch (Exception ex) {\r
+                       throw new GdxRuntimeException("Error copying source file: " + file + " (" + type + ")\n" //\r
+                               + "To destination: " + dest.file + " (" + dest.type + ")", ex);\r
+               } finally {\r
+                       try {\r
+                               if (input != null) input.close();\r
+                       } catch (Exception ignored) {\r
+                       }\r
+                       try {\r
+                               if (output != null) output.close();\r
+                       } catch (Exception ignored) {\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Moves this file to the specified file, overwriting the file if it already exists.\r
+        * @throw GdxRuntimeException if the destination file handle is an {@link FileType#Internal} file.\r
+        */\r
+       public void moveTo (FileHandle dest) {\r
+               copyTo(dest);\r
+               delete();\r
+       }\r
+\r
+       /**\r
+        * Returns the length in bytes of this file, or 0 if this file is a directory or does not exist.\r
+        */\r
+       public long length () {\r
+               if (type == FileType.Internal) {\r
+                       try {\r
+                               InputStream input = read();\r
+                               long length = input.available();\r
+                               try {\r
+                                       input.close();\r
+                               } catch (Exception ignored) {\r
+                               }\r
+                               return length;\r
+                       } catch (Exception ignored) {\r
+                       }\r
+                       return 0;\r
+               }\r
+               return file.length();\r
+       }\r
+\r
+       public String toString () {\r
+               return file.getPath();\r
+       }\r
+\r
+       static private boolean deleteDirectory (File file) {\r
+               if (file.exists()) {\r
+                       File[] files = file.listFiles();\r
+                       for (int i = 0, n = files.length; i < n; i++) {\r
+                               if (files[i].isDirectory())\r
+                                       deleteDirectory(files[i]);\r
+                               else\r
+                                       files[i].delete();\r
+                       }\r
+               }\r
+               return file.delete();\r
+       }\r
 }\r
diff --git a/gdx/src/com/badlogic/gdx/files/FileHandleStream.java b/gdx/src/com/badlogic/gdx/files/FileHandleStream.java
new file mode 100644 (file)
index 0000000..122d846
--- /dev/null
@@ -0,0 +1,100 @@
+\r
+package com.badlogic.gdx.files;\r
+\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
+import java.io.FileNotFoundException;\r
+import java.io.FileOutputStream;\r
+import java.io.InputStream;\r
+import java.io.OutputStream;\r
+\r
+import com.badlogic.gdx.Files.FileType;\r
+import com.badlogic.gdx.utils.GdxRuntimeException;\r
+\r
+/**\r
+ * A FileHandle intended to be subclassed for the purpose of implemented {@link #read()} and/or {@link #write(boolean)}. Methods\r
+ * that would modify a file instead throw UnsupportedOperationException.\r
+ */\r
+public abstract class FileHandleStream extends FileHandle {\r
+       public FileHandleStream (String path) {\r
+               super(new File(path), FileType.Absolute);\r
+       }\r
+\r
+       public FileHandle child (String name) {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+\r
+       public FileHandle parent () {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+\r
+       public String path () {\r
+               return file.getPath();\r
+       }\r
+\r
+       public String name () {\r
+               return file.getName();\r
+       }\r
+\r
+       public String extension () {\r
+               String name = file.getName();\r
+               int dotIndex = name.lastIndexOf('.');\r
+               if (dotIndex == -1) return "";\r
+               return name.substring(dotIndex + 1);\r
+       }\r
+\r
+       public String nameWithoutExtension () {\r
+               String name = file.getName();\r
+               int dotIndex = name.lastIndexOf('.');\r
+               if (dotIndex == -1) return name;\r
+               return name.substring(0, dotIndex);\r
+       }\r
+\r
+       public FileType type () {\r
+               return type;\r
+       }\r
+\r
+       public boolean isDirectory () {\r
+               return false;\r
+       }\r
+\r
+       public long length () {\r
+               return 0;\r
+       }\r
+\r
+       public boolean exists () {\r
+               return true;\r
+       }\r
+\r
+       public InputStream read () {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+\r
+       public OutputStream write (boolean overwrite) {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+\r
+       public FileHandle[] list () {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+\r
+       public void mkdirs () {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+\r
+       public boolean delete () {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+\r
+       public boolean deleteDirectory () {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+\r
+       public void copyTo (FileHandle dest) {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+\r
+       public void moveTo (FileHandle dest) {\r
+               throw new UnsupportedOperationException();\r
+       }\r
+}\r
index 47c0524..7c8813a 100644 (file)
@@ -23,7 +23,9 @@
 package com.badlogic.gdx.graphics;\r
 \r
 import com.badlogic.gdx.Gdx;\r
+import com.badlogic.gdx.Files.FileType;\r
 import com.badlogic.gdx.files.FileHandle;\r
+import com.badlogic.gdx.files.FileHandleStream;\r
 import com.badlogic.gdx.graphics.Texture.TextureFilter;\r
 import com.badlogic.gdx.graphics.Texture.TextureWrap;\r
 import com.badlogic.gdx.utils.GdxRuntimeException;\r
@@ -75,32 +77,12 @@ public class BitmapFont {
     private int capHeight;\r
 \r
     /**\r
-     * Creates a new BitmapFont using the default 14pt Arial font included in\r
+     * Creates a new BitmapFont using the default 15pt Arial font included in\r
      * the gdx jar file. This is here to get you up and running quickly.\r
      */\r
     public BitmapFont() {\r
-\r
-        this(new FileHandle() {\r
-            @Override\r
-            public String getPath() {\r
-                return "/com/badlogic/gdx/utils/arial-15.fnt";\r
-            }\r
-\r
-            @Override\r
-            public InputStream readFile() {\r
-                return BitmapFont.class.getResourceAsStream(getPath());\r
-            }\r
-        }, new FileHandle() {\r
-            @Override\r
-            public String getPath() {\r
-                return "/com/badlogic/gdx/utils/arial-15.png";\r
-            }\r
-\r
-            @Override\r
-            public InputStream readFile() {\r
-                return BitmapFont.class.getResourceAsStream(getPath());\r
-            }\r
-        }, false);\r
+               this(Gdx.files.internal("com/badlogic/gdx/utils/arial-15.fnt"),\r
+                       Gdx.files.internal("com/badlogic/gdx/utils/arial-15.png"), false);\r
     }\r
 \r
     public BitmapFont(FileHandle fontFile, Texture texture, boolean flip) {\r
@@ -131,7 +113,7 @@ public class BitmapFont {
         float invTexWidth = 1.0f / texture.getWidth();\r
         float invTexHeight = 1.0f / texture.getHeight();\r
 \r
-        BufferedReader reader = new BufferedReader(new InputStreamReader(fontFile.readFile()), 512);\r
+        BufferedReader reader = new BufferedReader(new InputStreamReader(fontFile.read()), 512);\r
         try {\r
             reader.readLine(); // info\r
 \r
index ce6436a..b5071ec 100644 (file)
@@ -89,14 +89,13 @@ public class ParticleEffect {
                }\r
        }\r
 \r
-       public void load (FileHandle effectFile, String imagesDir, FileType fileType) {\r
+       public void load (FileHandle effectFile, FileHandle imagesDir) {\r
                loadEmitters(effectFile);\r
-               loadEmitterImages(imagesDir, fileType);\r
+               loadEmitterImages(imagesDir);\r
        }\r
 \r
        void loadEmitters (FileHandle file) {\r
-               InputStream input = file.readFile();\r
-               if (input == null) throw new GdxRuntimeException("Effect file not found: " + file);\r
+               InputStream input = file.read();\r
                emitters.clear();\r
                BufferedReader reader = null;\r
                try {\r
@@ -119,16 +118,13 @@ public class ParticleEffect {
                }\r
        }\r
 \r
-       private void loadEmitterImages (String imagesDir, FileType fileType) {\r
-               imagesDir = imagesDir.replace('\\', '/');\r
-               if (!imagesDir.endsWith("/")) imagesDir += '/';\r
+       private void loadEmitterImages (FileHandle imagesDir) {\r
                for (int i = 0, n = emitters.size(); i < n; i++) {\r
                        ParticleEmitter emitter = emitters.get(i);\r
                        String imagePath = emitter.getImagePath();\r
                        if (imagePath == null) continue;\r
-                       imagePath = imagePath.replace('\\', '/');\r
-                       imagePath = imagesDir + new File(imagePath).getName();\r
-                       emitter.setTexture(loadTexture(Gdx.files.getFileHandle(imagePath, fileType)));\r
+                       String imageName = new File(imagePath).getName();\r
+                       emitter.setTexture(loadTexture(imagesDir.child(imageName)));\r
                }\r
        }\r
 \r
index e9533ef..c5b5ed6 100644 (file)
@@ -27,23 +27,16 @@ public class BitmapFontTest extends GdxTest {
        private float alpha;\r
        InputProcessor inputProcessor;\r
 \r
-       @Override\r
-       public void create () {\r
+       @Override public void create () {\r
                if (spriteBatch != null) return;\r
                spriteBatch = new SpriteBatch();\r
 \r
-               Matrix4 transform = new Matrix4();              \r
-               transform.setToTranslation(0, Gdx.graphics.getHeight(), 0);\r
-               transform.mul(new Matrix4().setToScaling(1,-1,1));\r
-               spriteBatch.setTransformMatrix(transform);              \r
-               \r
                logoSprite = new Sprite(Gdx.graphics.newTexture(Gdx.files.getFileHandle("data/badlogic.jpg", FileType.Internal),\r
                        TextureFilter.Linear, TextureFilter.Linear, TextureWrap.ClampToEdge, TextureWrap.ClampToEdge));\r
-               logoSprite.flip(false, true); \r
                logoSprite.setColor(1, 1, 1, 0.5f);\r
 \r
                font = new BitmapFont(Gdx.files.getFileHandle("data/verdana39.fnt", FileType.Internal), Gdx.files.getFileHandle(\r
-                       "data/verdana39.png", FileType.Internal), true);\r
+                       "data/verdana39.png", FileType.Internal), false);\r
 \r
                inputProcessor = new InputAdapter() {\r
                        public boolean touchDown (int x, int y, int pointer) {\r
@@ -51,7 +44,7 @@ public class BitmapFontTest extends GdxTest {
                                return false;\r
                        }\r
                };\r
-               \r
+\r
                Gdx.input.setInputProcessor(inputProcessor);\r
 \r
                cache1 = new BitmapFontCache(font);\r
@@ -75,8 +68,7 @@ public class BitmapFontTest extends GdxTest {
                cache5.setWrappedText(text, 0, 270, red, 480, HAlignment.CENTER);\r
        }\r
 \r
-       @Override\r
-       public void render () {\r
+       @Override public void render () {\r
                alpha = (alpha + Gdx.graphics.getDeltaTime() * 0.1f) % 1;\r
 \r
                GL10 gl = Gdx.graphics.getGL10();\r
index 5f152f2..649c8c6 100644 (file)
@@ -1,3 +1,4 @@
+\r
 package com.badlogic.gdx.tests;\r
 \r
 import java.io.BufferedReader;\r
@@ -10,6 +11,7 @@ import java.io.OutputStreamWriter;
 \r
 import com.badlogic.gdx.Files.FileType;\r
 import com.badlogic.gdx.Gdx;\r
+import com.badlogic.gdx.files.FileHandle;\r
 import com.badlogic.gdx.graphics.BitmapFont;\r
 import com.badlogic.gdx.graphics.Color;\r
 import com.badlogic.gdx.graphics.GL10;\r
@@ -22,81 +24,123 @@ public class FilesTest extends GdxTest {
        boolean success;\r
        BitmapFont font;\r
        SpriteBatch batch;\r
-       \r
-       @Override\r
-       public void create() {\r
+\r
+       @Override public void create () {\r
                font = new BitmapFont();\r
                batch = new SpriteBatch();\r
-               \r
-               if(Gdx.files.isExternalStorageAvailable()) {\r
-                       message += "external storage available\n";\r
-                       message += "external storage path: " + Gdx.files.getExternalStoragePath() + "\n";\r
-                       \r
+\r
+               if (Gdx.files.isExternalStorageAvailable()) {\r
+                       message += "External storage available\n";\r
+                       message += "External storage path: " + Gdx.files.getExternalStoragePath() + "\n";\r
+\r
                        try {\r
-                               InputStream in = Gdx.files.readFile( "data/cube.obj", FileType.Internal);\r
-                               try { in.close(); } catch (IOException e) {     }\r
-                               message += "open internal success\n";\r
-                       } catch(Throwable e) {\r
+                               InputStream in = Gdx.files.internal("data/cube.obj").read();\r
+                               try {\r
+                                       in.close();\r
+                               } catch (IOException e) {\r
+                               }\r
+                               message += "Open internal success\n";\r
+                       } catch (Throwable e) {\r
                                message += "Couldn't open internal data/cube.obj\n" + e.getMessage() + "\n";\r
                        }\r
-                       \r
+\r
                        BufferedWriter out = null;\r
-                       try {                           \r
-                               out = new BufferedWriter(new OutputStreamWriter(Gdx.files.writeFile("test.txt", FileType.External)));\r
-                               out.write("test");              \r
-                               message += "write external success\n";\r
-                       } catch(GdxRuntimeException ex) {\r
-                               message +="Couldn't open externalstorage/test.txt\n";\r
+                       try {\r
+                               out = new BufferedWriter(new OutputStreamWriter(Gdx.files.external("test.txt").write(false)));\r
+                               out.write("test");\r
+                               message += "Write external success\n";\r
+                       } catch (GdxRuntimeException ex) {\r
+                               message += "Couldn't open externalstorage/test.txt\n";\r
                        } catch (IOException e) {\r
-                               message +="Couldn't write externalstorage/test.txt\n";\r
+                               message += "Couldn't write externalstorage/test.txt\n";\r
                        } finally {\r
-                               if(out != null) {\r
-                                       try { out.close(); } catch (IOException e) {    }\r
+                               if (out != null) {\r
+                                       try {\r
+                                               out.close();\r
+                                       } catch (IOException e) {\r
+                                       }\r
                                }\r
                        }\r
-                       \r
+\r
                        try {\r
-                               InputStream in = Gdx.files.readFile( "test.txt", FileType.External);\r
-                               try { in.close(); } catch (IOException e) {     }\r
-                               message +="Open external success\n";\r
-                       } catch(Throwable e) {\r
+                               InputStream in = Gdx.files.external("test.txt").read();\r
+                               try {\r
+                                       in.close();\r
+                               } catch (IOException e) {\r
+                               }\r
+                               message += "Open external success\n";\r
+                       } catch (Throwable e) {\r
                                message += "Couldn't open internal externalstorage/test.txt\n" + e.getMessage() + "\n";\r
                        }\r
-                       \r
-                       BufferedReader in = null;                       \r
-                       try {                           \r
-                               in = new BufferedReader(new InputStreamReader(Gdx.files.readFile("test.txt", FileType.External)));\r
-                               if(!in.readLine().equals("test"))\r
+\r
+                       BufferedReader in = null;\r
+                       try {\r
+                               in = new BufferedReader(new InputStreamReader(Gdx.files.external("test.txt").read()));\r
+                               if (!in.readLine().equals("test"))\r
                                        message += "Read result wrong\n";\r
                                else\r
-                                       message +="Read external success\n";\r
-                       } catch(GdxRuntimeException ex) {\r
-                               message +="Couldn't open externalstorage/test.txt\n";\r
+                                       message += "Read external success\n";\r
+                       } catch (GdxRuntimeException ex) {\r
+                               message += "Couldn't open externalstorage/test.txt\n";\r
                        } catch (IOException e) {\r
-                               message +="Couldn't read externalstorage/test.txt\n";\r
+                               message += "Couldn't read externalstorage/test.txt\n";\r
                        } finally {\r
-                               if(out != null) {\r
-                                       try { out.close(); } catch (IOException e) {    }\r
+                               if (in != null) {\r
+                                       try {\r
+                                               in.close();\r
+                                       } catch (IOException e) {\r
+                                       }\r
                                }\r
                        }\r
-                       \r
-                       if(!new File(Gdx.files.getExternalStoragePath() + "test.txt").delete())\r
-                               message += "couldn't delete externalstorage/test.txt";\r
+\r
+                       if (!Gdx.files.external("test.txt").delete()) message += "Couldn't delete externalstorage/test.txt";\r
                } else {\r
                        message += "External storage not available";\r
                }\r
+\r
+               // Can only really test external with this, since internal you can't create files, and absolute on Android you don't have\r
+               // permissions to create files.\r
+               testWriteRead("meow", FileType.External);\r
+       }\r
+\r
+       private void testWriteRead (String path, FileType type) {\r
+               FileHandle handle = Gdx.files.getFileHandle(path, type);\r
+               if (handle.exists()) fail();\r
+               if (handle.isDirectory()) fail();\r
+               if (handle.delete()) fail();\r
+               if (handle.list().length != 0) fail();\r
+               if (handle.child("meow").exists()) fail();\r
+               if (!handle.parent().exists()) fail();\r
+               try {\r
+                       handle.read();\r
+                       fail();\r
+               } catch (Exception ignored) {\r
+               }\r
+               handle.mkdirs();\r
+               if (!handle.exists()) fail();\r
+               if (!handle.isDirectory()) fail();\r
+               if (handle.list().length != 0) fail();\r
+               handle.child("meow").mkdirs();\r
+               if (handle.list().length != 1) fail();\r
+               FileHandle child = handle.list()[0];\r
+               if (!child.name().equals("meow")) fail();\r
+               if (!child.parent().exists()) fail();\r
+               if (!handle.deleteDirectory()) fail();\r
+               if (handle.exists()) fail();\r
+       }\r
+\r
+       private void fail () {\r
+               throw new RuntimeException();\r
        }\r
-       \r
-       @Override\r
-       public void render() {\r
+\r
+       @Override public void render () {\r
                Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);\r
                batch.begin();\r
-               font.drawMultiLineText(batch, message, 20, Gdx.graphics.getHeight() - 20, Color.WHITE );\r
+               font.drawMultiLineText(batch, message, 20, Gdx.graphics.getHeight() - 20, Color.WHITE);\r
                batch.end();\r
        }\r
-       \r
-       @Override\r
-       public boolean needsGL20() {\r
+\r
+       @Override public boolean needsGL20 () {\r
                return false;\r
        }\r
 \r
index be21a14..1116121 100644 (file)
@@ -29,10 +29,8 @@ public class MD5Test extends GdxTest implements InputProcessor {
        @Override\r
        public void create() {\r
                Gdx.app.log("MD5 Test", "created");\r
-               model = MD5Loader.loadModel(Gdx.files.readFile("data/zfat.md5mesh",\r
-                               FileType.Internal));\r
-               anim = MD5Loader.loadAnimation(Gdx.files.readFile("data/walk1.md5anim",\r
-                               FileType.Internal));\r
+               model = MD5Loader.loadModel(Gdx.files.internal("data/zfat.md5mesh").read());\r
+               anim = MD5Loader.loadAnimation(Gdx.files.internal("data/walk1.md5anim").read());\r
                skeleton = new MD5Joints();\r
                skeleton.joints = new float[anim.frames[0].joints.length];\r
                animInfo = new MD5AnimationInfo(anim.frames.length,\r
index f5e5ee0..b3f117e 100644 (file)
@@ -37,7 +37,7 @@ public class ObjTest extends GdxTest implements InputProcessor {
        float touchStartY = 0;  \r
 \r
        @Override public void create () {\r
-               mesh = ModelLoader.loadObj(Gdx.files.readFile("data/cube.obj", FileType.Internal));\r
+               mesh = ModelLoader.loadObj(Gdx.files.internal("data/cube.obj").read());\r
                texture = Gdx.graphics.newTexture(Gdx.files.getFileHandle("data/badlogic.jpg", FileType.Internal), TextureFilter.MipMap,\r
                        TextureFilter.Linear, TextureWrap.ClampToEdge, TextureWrap.ClampToEdge);\r
 \r
index 760649b..672a10d 100644 (file)
@@ -36,7 +36,7 @@ public class ParticleEmitterTest extends GdxTest {
                spriteBatch = new SpriteBatch();\r
 \r
                effect = new ParticleEffect();\r
-               effect.load(Gdx.files.getFileHandle("data/test.p", FileType.Internal), "data", FileType.Internal);\r
+               effect.load(Gdx.files.internal("data/test.p"), Gdx.files.internal("data"));\r
                effect.setPosition(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2);\r
                // Of course, a ParticleEffect is normally just used, without messing around with its emitters.\r
                emitters = new ArrayList(effect.getEmitters());\r