Browse Source

Merge pull request #1123 from LumaDigital/MB_BuildStandalonePlayer

Build command autologging, file stream wrapper, ResourceCache.Scan
JoshEngebretson 9 years ago
parent
commit
0f03d0684b

+ 112 - 1
Script/AtomicNET/AtomicNET/IO/File.cs

@@ -1,12 +1,123 @@
-
 using System;
+using System.IO;
 using System.Runtime.InteropServices;
 
 namespace AtomicEngine
 {
     public partial class File : AObject, Deserializer, Serializer
     {
+        private class Stream : System.IO.Stream
+        {
+            private File file;
+
+            public override bool CanRead
+            {
+                get
+                {
+                    return file.Mode == FileMode.FILE_READ || file.Mode == FileMode.FILE_READWRITE;
+                }
+            }
+
+            public override bool CanSeek
+            {
+                get
+                {
+                    return true;
+                }
+            }
+
+            public override bool CanWrite
+            {
+                get
+                {
+                    return file.Mode == FileMode.FILE_WRITE ||
+                        file.Mode == FileMode.FILE_READWRITE ||
+                        file.Mode == FileMode.FILE_APPEND;
+                }
+            }
+
+            public override long Length
+            {
+                get
+                {
+                    return file.GetSize();
+                }
+            }
+
+            public override long Position
+            {
+                get
+                {
+                    return file.GetPosition();
+                }
+
+                set
+                {
+                    file.Seek((uint)value);
+                }
+            }
 
+            public Stream(File file)
+            {
+                if (file == null)
+                    throw new ArgumentNullException(nameof(file));
+
+                this.file = file;
+            }
+
+            public override void Flush()
+            {
+                file.Flush();
+            }
+
+            public override int Read(byte[] buffer, int offset, int count)
+            {
+                if (buffer == null)
+                    throw new ArgumentNullException(nameof(buffer));
+                if (offset + count > buffer.Length)
+                    throw new IndexOutOfRangeException("buffer.Length");
+
+                byte[] readData = file.Read(count);
+                int limit = Math.Min(count, readData.Length);
+                Array.Copy(readData, 0, buffer, offset, limit);
+
+                return limit;
+            }
+
+            public override long Seek(long offset, SeekOrigin origin)
+            {
+                if (origin == SeekOrigin.Current)
+                {
+                    offset += Position;
+                }
+                else if (origin == SeekOrigin.End)
+                {
+                    offset += Length;
+                }
+
+                return file.Seek((uint)offset);
+            }
+
+            public override void SetLength(long value)
+            {
+                throw new InvalidOperationException();
+            }
+
+            public override void Write(byte[] buffer, int offset, int count)
+            {
+                if (buffer == null)
+                    throw new ArgumentNullException(nameof(buffer));
+                if (offset + count >= buffer.Length)
+                    throw new IndexOutOfRangeException("buffer.Length");
+
+                file.Write(buffer, offset, count);
+            }
+        }
+
+        public System.IO.Stream ToStream()
+        {
+            return new Stream(this);
+        }
 
         /// <summary>
         /// Read bytes from the file. Return array of bytes of the length actually read (can be 0 length)

+ 11 - 1
Script/AtomicNET/AtomicNET/Resource/ResourceCache.cs

@@ -14,6 +14,16 @@ namespace AtomicEngine
             return (T)GetResource(typeof(T).Name, path);
         }
 
-    }
+        public System.IO.Stream GetFileStream(string name, bool sendEventOnFailure = true)
+        {
+            File file = GetFile(name, sendEventOnFailure);
+            if (file != null &&
+                file.IsOpen())
+            {
+                return file.ToStream();
+            }
 
+            return null;
+        }
+    }
 }

+ 32 - 0
Script/AtomicNET/AtomicNET/Resource/ResourceNameIterator.cs

@@ -0,0 +1,32 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace AtomicEngine
+{
+
+    public partial class ResourceNameIterator : IEnumerator<string>, IEnumerable<string>
+    {
+        object IEnumerator.Current
+        {
+            get
+            {
+                return Current;
+            }
+        }
+
+        public IEnumerator<string> GetEnumerator()
+        {
+            return this;
+        }
+
+        void IDisposable.Dispose() { }
+
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            return this;
+        }
+    }
+
+
+}

+ 1 - 1
Script/Packages/Atomic/Resource.json

@@ -1,7 +1,7 @@
 {
 	"name" : "Resource",
 	"sources" : ["Source/Atomic/Resource"],
-	"classes" : ["Resource", "ResourceCache", "XMLFile", "PListFile", "JSONFile", "Image"],
+	"classes" : ["Resource", "ResourceCache", "XMLFile", "PListFile", "JSONFile", "Image", "ResourceNameIterator"],
 	"overloads": {
 		"Image": {
 			"GetPixel": ["int", "int"],

+ 29 - 0
Source/Atomic/IO/PackageFile.cpp

@@ -22,6 +22,7 @@
 
 #include "../Precompiled.h"
 
+#include "../IO/FileSystem.h"
 #include "../IO/File.h"
 #include "../IO/Log.h"
 #include "../IO/PackageFile.h"
@@ -155,4 +156,32 @@ const PackageEntry* PackageFile::GetEntry(const String& fileName) const
     return 0;
 }
 
+// ATOMIC BEGIN
+void PackageFile::Scan(Vector<String>& result, const String& pathName, const String& filter, bool recursive) const
+{
+    result.Clear();
+
+    String sanitizedPath = GetSanitizedPath(pathName);
+    String filterExtension = filter.Substring(filter.FindLast('.'));
+    if (filterExtension.Contains('*'))
+        filterExtension.Clear();
+
+    const StringVector& entryNames = GetEntryNames();
+    for (StringVector::ConstIterator i = entryNames.Begin(); i != entryNames.End(); ++i)
+    {
+        String entryName = GetSanitizedPath(*i);
+        if ((filterExtension.Empty() || entryName.EndsWith(filterExtension)) &&
+            entryName.StartsWith(sanitizedPath))
+        {
+            String fileName = entryName.Substring(sanitizedPath.Length());
+            if (fileName.StartsWith("\\") || fileName.StartsWith("/"))
+                fileName = fileName.Substring(1, fileName.Length() - 1);
+            if (!recursive && (fileName.Contains("\\") || fileName.Contains("/")))
+                continue;
+
+            result.Push(fileName);
+        }
+    }
+}
+// ATOMIC END
 }

+ 6 - 0
Source/Atomic/IO/PackageFile.h

@@ -85,6 +85,12 @@ public:
     /// Return list of file names in the package.
     const Vector<String> GetEntryNames() const { return entries_.Keys(); }
 
+    // ATOMIC BEGIN
+    
+    /// Scan package for specified files.
+    void Scan(Vector<String>& result, const String& pathName, const String& filter, bool recursive) const;
+    
+    // ATOMIC END
 private:
     /// File entries.
     HashMap<String, PackageEntry> entries_;

+ 50 - 0
Source/Atomic/Resource/ResourceCache.cpp

@@ -1196,4 +1196,54 @@ void RegisterResourceLibrary(Context* context)
     XMLFile::RegisterObject(context);
 }
 
+// ATOMIC BEGIN
+ResourceNameIterator::ResourceNameIterator()
+{
+    Reset();
+}
+
+const String& ResourceNameIterator::GetCurrent()
+{
+    return (index_ < filenames_.Size()) ?
+        filenames_[index_] :
+        String::EMPTY;
+}
+
+bool ResourceNameIterator::MoveNext()
+{
+    return ++index_ < filenames_.Size();
+}
+
+void ResourceNameIterator::Reset()
+{
+    index_ = -1;
+}
+
+void ResourceCache::Scan(Vector<String>& result, const String& pathName, const String& filter, unsigned flags, bool recursive) const
+{
+    Vector<String> interimResult;
+
+    for (unsigned i = 0; i < packages_.Size(); ++i)
+    {
+        packages_[i]->Scan(interimResult, pathName, filter, recursive);
+        result.Insert(result.End(), interimResult);
+    }
+
+    FileSystem* fileSystem = GetSubsystem<FileSystem>();
+    for (unsigned i = 0; i < resourceDirs_.Size(); ++i)
+    {
+        fileSystem->ScanDir(interimResult, resourceDirs_[i] + pathName, filter, flags, recursive);
+        result.Insert(result.End(), interimResult);
+    }
+}
+
+SharedPtr<ResourceNameIterator> ResourceCache::Scan(const String& pathName, const String& filter, unsigned flags, bool recursive) const
+{
+    SharedPtr<ResourceNameIterator> enumerator(new ResourceNameIterator());
+    Scan(enumerator->filenames_, pathName, filter, flags, recursive);
+
+    return enumerator;
+}
+// ATOMIC END
+
 }

+ 22 - 0
Source/Atomic/Resource/ResourceCache.h

@@ -79,6 +79,23 @@ public:
     /// Process the resource request and optionally modify the resource name string. Empty name string means the resource is not found or not allowed.
     virtual void Route(String& name, StringHash type, ResourceRequest requestType) = 0;
 };
+
+/// Helper class to expose resource iteration to script
+class ResourceNameIterator : public RefCounted
+{
+    ATOMIC_REFCOUNTED(ResourceNameIterator);
+public:
+    ResourceNameIterator();
+
+    const String& GetCurrent();
+    bool MoveNext();
+    void Reset();
+
+    Vector<String> filenames_;
+private:
+    unsigned index_;
+};
+
 // ATOMIC END
 
 /// %Resource cache subsystem. Loads resources on demand and stores them for later access.
@@ -222,6 +239,11 @@ public:
     unsigned GetNumResourceDirs() const { return resourceDirs_.Size(); }
     /// Get resource directory at a given index
     const String& GetResourceDir(unsigned index) const { return index < resourceDirs_.Size() ? resourceDirs_[index] : String::EMPTY; }
+    
+    /// Scan for specified files.
+    void Scan(Vector<String>& result, const String& pathName, const String& filter, unsigned flags, bool recursive) const;
+    /// Scan specified files, returning them as an iterator
+    SharedPtr<ResourceNameIterator> Scan(const String& pathName, const String& filter, unsigned flags, bool recursive) const;
 
     // ATOMIC END
 

+ 9 - 0
Source/ToolCore/Build/BuildBase.cpp

@@ -239,6 +239,9 @@ void BuildBase::BuildLog(const String& message, bool sendEvent)
 {
     buildLog_.Push(message);
 
+    if (autoLog_)
+        ATOMIC_LOGINFO(message);
+    
     if (sendEvent)
     {
         String colorMsg = ToString("<color #D4FB79>%s</color>\n", message.CString());
@@ -253,6 +256,9 @@ void BuildBase::BuildWarn(const String& warning, bool sendEvent)
 {
     buildWarnings_.Push(warning);
 
+    if (autoLog_)
+        ATOMIC_LOGWARNING(warning);
+
     if (sendEvent)
     {
         String colorMsg = ToString("<color #FFFF00>%s</color>\n", warning.CString());
@@ -267,6 +273,9 @@ void BuildBase::BuildError(const String& error, bool sendEvent)
 {
     buildErrors_.Push(error);
 
+    if (autoLog_)
+        ATOMIC_LOGERROR(error);
+
     if (sendEvent)
     {
         String colorMsg = ToString("<color #FF0000>%s</color>\n", error.CString());

+ 3 - 0
Source/ToolCore/Build/BuildBase.h

@@ -84,6 +84,8 @@ public:
     bool GetBuildFailed() const { return buildFailed_; }
     const Vector<String>& GetBuildErrors() const { return buildErrors_; }
 
+    void SetAutoLog(bool autoLog) { autoLog_ = autoLog; }
+
 protected:
 
     bool BuildClean(const String& path);
@@ -118,6 +120,7 @@ protected:
 
     bool resourcesOnly_;
     bool verbose_;
+    bool autoLog_;
 
 private:
     void BuildFilteredProjectResourceEntries();

+ 1 - 1
Source/ToolCore/Build/BuildWindows.cpp

@@ -113,7 +113,7 @@ bool BuildWindows::BuildManaged(const String& buildPath)
 
     if (!fileSystem->FileExists(managedExe))
     {
-        BuildError(ToString("Error building managed project, please compile the %s binary %s before building", config.CString(), managedExe.CString()));
+        FailBuild(ToString("Error building managed project, please compile the %s binary %s before building", config.CString(), managedExe.CString()));
         return false;
     }
 

+ 27 - 1
Source/ToolCore/Command/BuildCmd.cpp

@@ -50,7 +50,6 @@ bool BuildCmd::Parse(const Vector<String>& arguments, unsigned startIndex, Strin
 {
     String argument = arguments[startIndex].ToLower();
     String value = startIndex + 1 < arguments.Size() ? arguments[startIndex + 1] : String::EMPTY;
-    String tag = startIndex + 2 < arguments.Size() ? arguments[startIndex + 2] : String::EMPTY;
 
     if (argument != "build")
     {
@@ -65,6 +64,32 @@ bool BuildCmd::Parse(const Vector<String>& arguments, unsigned startIndex, Strin
     }
 
     buildPlatform_ = value.ToLower();
+
+    for (int i = startIndex + 2; i < arguments.Size(); ++i)
+    {
+        String option = arguments[i].ToLower();
+        
+        if (option == "-tag")
+        {
+            if (arguments.Size() == i + 1)
+            {
+                errorMsg = "Missing tag";
+                return false;
+            }
+        }
+        else if (option == "-autolog")
+        {
+            autoLog_ = true;
+        }
+        else
+        {
+            errorMsg = "Invalid option: " + option;
+            return false;
+        }
+    }
+
+    String tag = startIndex + 2 < arguments.Size() ? arguments[startIndex + 2] : String::EMPTY;
+
     assetsBuildTag_ = tag.ToLower();
 
     return true;
@@ -106,6 +131,7 @@ void BuildCmd::Run()
     {
         buildBase->SetAssetBuildTag(assetsBuildTag_);
     }
+    buildBase->SetAutoLog(autoLog_);
 
     // add it to the build system
     BuildSystem* buildSystem = GetSubsystem<BuildSystem>();

+ 1 - 0
Source/ToolCore/Command/BuildCmd.h

@@ -49,6 +49,7 @@ private:
 
     String buildPlatform_;
     String assetsBuildTag_;
+    bool autoLog_;
 
 };