Browse Source

Working on Asset Import

Josh Engebretson 10 years ago
parent
commit
b29b33b7a5
28 changed files with 1229 additions and 175 deletions
  1. 5 4
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/AtomicWork.d.ts
  2. 0 1
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/assets/AssetImport.ts
  3. 1 0
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/tsconfig.json
  4. 3 1
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/MainFrame.ts
  5. 49 146
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/ProjectFrame.ts
  6. 316 0
      Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/ProjectFrameOld.ts
  7. 12 0
      Source/Atomic/Resource/JSONValue.cpp
  8. 4 0
      Source/Atomic/Resource/JSONValue.h
  9. 10 2
      Source/AtomicJS/Packages/ToolCore/ToolCore.json
  10. 76 0
      Source/ToolCore/Assets/Asset.cpp
  11. 48 0
      Source/ToolCore/Assets/Asset.h
  12. 204 0
      Source/ToolCore/Assets/AssetDatabase.cpp
  13. 46 0
      Source/ToolCore/Assets/AssetDatabase.h
  14. 100 0
      Source/ToolCore/Assets/AssetImporter.cpp
  15. 49 0
      Source/ToolCore/Assets/AssetImporter.h
  16. 60 0
      Source/ToolCore/Assets/FolderImporter.cpp
  17. 29 0
      Source/ToolCore/Assets/FolderImporter.h
  18. 80 0
      Source/ToolCore/Assets/ModelImporter.cpp
  19. 29 0
      Source/ToolCore/Assets/ModelImporter.h
  20. 21 11
      Source/ToolCore/Import/OpenAssetImporter.cpp
  21. 1 0
      Source/ToolCore/JSBind/JSBClass.cpp
  22. 31 0
      Source/ToolCore/JSBind/JSBClass.h
  23. 1 3
      Source/ToolCore/JSBind/JSBDoc.cpp
  24. 2 2
      Source/ToolCore/JSBind/JSBModuleWriter.cpp
  25. 1 3
      Source/ToolCore/JSBind/JSBTypeScript.cpp
  26. 1 1
      Source/ToolCore/Project/Project.h
  27. 3 1
      Source/ToolCore/ToolSystem.cpp
  28. 47 0
      Source/ToolCoreJS/ToolCoreJS.cpp

+ 5 - 4
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/AtomicWork.d.ts

@@ -1,6 +1,6 @@
-/// <reference path="/Users/josh/Dev/thunderbeast/AtomicGameEngine/Bin/Atomic.d.ts" />
-/// <reference path="/Users/josh/Dev/thunderbeast/AtomicGameEngine/Bin/ToolCore.d.ts" />
-/// <reference path="/Users/josh/Dev/thunderbeast/AtomicGameEngine/Bin/Editor.d.ts" />
+/// <reference path="/Users/josh/Dev/atomic/AtomicGameEngine/Bin/Atomic.d.ts" />
+/// <reference path="/Users/josh/Dev/atomic/AtomicGameEngine/Bin/ToolCore.d.ts" />
+/// <reference path="/Users/josh/Dev/atomic/AtomicGameEngine/Bin/Editor.d.ts" />
 
 declare module Atomic {
 
@@ -9,7 +9,7 @@ declare module Atomic {
       pathName: string;
       fileName: string;
       ext: string;
-      
+
     }
 
     /*
@@ -67,4 +67,5 @@ declare module Atomic {
 declare module ToolCore {
     export function getToolEnvironment(): ToolEnvironment;
     export function getToolSystem(): ToolSystem;
+    export function getAssetDatabase(): AssetDatabase;
 }

+ 0 - 1
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/assets/AssetImport.ts

@@ -18,5 +18,4 @@ class AssetImport extends Atomic.ScriptObject {
 
 }
 
-
 export = AssetImport;

+ 1 - 0
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/tsconfig.json

@@ -19,6 +19,7 @@
         "./ui/MainFrame.ts",
         "./ui/MainFrameMenu.ts",
         "./ui/ProjectFrame.ts",
+        "./ui/ProjectFrameOld.ts",
         "./ui/ResourceFrame.ts",
         "./ui/ScriptWidget.ts",
         "./ui/UIEvents.ts",

+ 3 - 1
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/MainFrame.ts

@@ -33,7 +33,7 @@ class MainFrame extends ScriptWidget {
         this.projectframe = new ProjectFrame(this);
         this.resourceframe = new ResourceFrame(this);
 
-        this.showInspectorFrame(false);
+        this.showInspectorFrame(true);
 
         this.subscribeToEvent(UIEvents.ResourceEditorChanged, (data) => this.handleResourceEditorChanged(data));
 
@@ -41,6 +41,8 @@ class MainFrame extends ScriptWidget {
 
     showInspectorFrame(show: boolean) {
 
+        return;
+
         if (show) {
 
             this.inspectorlayout.visibility = UI.VISIBILITY_VISIBLE;

+ 49 - 146
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/ProjectFrame.ts

@@ -34,17 +34,12 @@ class ProjectFrame extends ScriptWidget {
 
     }
 
-
-    handleProjectLoaded(data) {
-
-        this.refresh();
-
-    }
-
     handleWidgetEvent(data): boolean {
 
         if (data.type == Atomic.UI.EVENT_TYPE_CLICK) {
 
+            var db = ToolCore.getAssetDatabase();
+
             var fs = Atomic.getFileSystem();
 
             if (data.target && data.target.id.length) {
@@ -57,30 +52,33 @@ class ProjectFrame extends ScriptWidget {
 
                     var selectedId = list.selectedItemID;
 
-                    if (fs.dirExists(selectedId)) {
-                        this.selectCurrentContentFolder(selectedId);
+                    // selectedId == 0 = root "Resources"
+
+                    if (selectedId != "0") {
+
+                        var asset = db.getAssetByGUID(selectedId);
+                        if (asset.isFolder)
+                            this.refreshContent(asset);
                     }
 
                     return true;
 
                 }
 
-                if (id == "..") {
-                    var parentPath = Atomic.getParentPath(this.currentContentFolder);
-                    this.selectCurrentContentFolder(parentPath);
-                    return true;
-                }
+                var asset = db.getAssetByGUID(id);
+                if (asset) {
 
-                if (fs.dirExists(id)) {
-                    this.selectCurrentContentFolder(id);
-                    return true;
-                }
+                  if (asset.isFolder()) {
+
+                    this.folderList.selectItemByID(id);
+                    this.refreshContent(asset);
+
+                  }
 
-                if (fs.fileExists(id)) {
-                    this.sendEvent("EditResource", { "path": id });
-                    return true;
                 }
 
+
+
             }
 
         }
@@ -90,83 +88,56 @@ class ProjectFrame extends ScriptWidget {
     }
 
 
-    refresh() {
+    handleProjectLoaded(data) {
 
-        var cfolder = this.currentContentFolder;
-        this.currentContentFolder = "";
-        this.refreshFolders();
+        this.refresh();
 
     }
 
-    private refreshContent(fullpath: string) {
-
-        var system = ToolCore.getToolSystem();
-        var project = system.project;
-
-        this.currentContentFolder = fullpath;
-
-        var folders = new Array<string>();
-        var content = new Array<string>();
+    private refreshContent(folder:ToolCore.Asset) {
 
-        this.scanContentDirForContent(folders, content, fullpath);
+        var db = ToolCore.getAssetDatabase();
 
         var container: Atomic.UILayout = <Atomic.UILayout> this.getWidget("contentcontainer");
-
         container.deleteAllChildren();
 
-        if (fullpath != project.resourcePath) {
-
-            var lp = new Atomic.UILayoutParams();
-            lp.height = 20;
-
-            var fd = new Atomic.UIFontDescription();
-            fd.id = "Vera";
-            fd.size = 11;
+        var assets = db.getFolderAssets(folder.path);
 
-            var button = new Atomic.UIButton();
-            button.gravity = UI.GRAVITY_LEFT;
-            button.text = "..                     ";
-            button.id = "..";
-            button.skinBg = "TBButton.flat";
-            button.layoutParams = lp;
-            button.fontDescription = fd;
+        for (var i in assets) {
 
-            container.addChild(button);
+            var asset = assets[i];
 
+            container.addChild(this.createButtonLayout(asset));
         }
 
-        for (var folder of folders) {
+    }
 
-            var contentID = Atomic.addTrailingSlash(fullpath + folder);
-            container.addChild(this.createButtonLayout(contentID, folder));
-        }
+    private recursiveAddFolder(parentItemID: number, folder: string) {
 
-        for (var c of content) {
+        var db = ToolCore.getAssetDatabase();
 
-            var contentID = Atomic.addTrailingSlash(fullpath) + c;
-            container.addChild(this.createButtonLayout(contentID, c));
-        }
+        var folderList = this.folderList;
 
+        var assets = db.getFolderAssets(folder);
 
-    }
+        for (var i in assets) {
 
-    private recursiveAddFolder(parentItemID: number, fullpath: string, folderName: string) {
+            var asset = assets[i];
 
-        var folderList = this.folderList;
+            if (asset.isFolder()) {
 
-        var childItemID = folderList.addChildItem(parentItemID, folderName, "Folder.icon", fullpath);
+                var childItemID = folderList.addChildItem(parentItemID, asset.name, "Folder.icon", asset.guid);
 
-        var dirs = new Array<string>();
+                this.recursiveAddFolder(childItemID, asset.path);
 
-        this.scanDirForFolders(dirs, fullpath);
+            }
 
-        for (var folder of dirs) {
-            this.recursiveAddFolder(childItemID, fullpath + folder + "/", folder);
         }
 
     }
 
-    private refreshFolders() {
+
+    refresh() {
 
         var system = ToolCore.getToolSystem();
         var project = system.project;
@@ -175,97 +146,33 @@ class ProjectFrame extends ScriptWidget {
 
         folderList.deleteAllItems();
 
-        var resourcesID = folderList.addRootItem("Resources", "Folder.icon", project.resourcePath);
+        var resourcesID = folderList.addRootItem("Resources", "Folder.icon", "0");
 
-        var dirs = new Array<string>();
-
-        this.scanDirForFolders(dirs, project.resourcePath);
-
-        for (var folder of dirs) {
-            this.recursiveAddFolder(resourcesID, project.resourcePath + folder + "/", folder);
-        }
+        this.recursiveAddFolder(resourcesID, project.resourcePath);
 
         folderList.setExpanded(resourcesID, true);
-        this.refreshContent(project.resourcePath);
+        // this.refreshContent(project.resourcePath);
         folderList.rootList.value = 0;
 
 
     }
 
-    private selectCurrentContentFolder(folder: string) {
-
-        this.folderList.selectItemByID(folder);
-        if (this.currentContentFolder != folder)
-            this.refreshContent(folder);
-    }
-
-    private endsWith(str: string, suffix: string): boolean {
-        return str && str.indexOf(suffix, str.length - suffix.length) !== -1;
-    }
-
-    private scanDirForFolders(dirs: Array<string>, fullpath: string) {
-
-        var fileSystem = Atomic.getFileSystem();
-
-        dirs.length = 0;
-
-        var folders = fileSystem.scanDir(fullpath, "", Atomic.SCAN_DIRS, false);
-
-        for (var folder of folders) {
-
-            if (folder == "." || folder == ".." || this.endsWith(folder, "/..") || this.endsWith(folder, "/."))
-                continue;
-
-            dirs.push(folder);
-
-        }
-
-    }
-
-
-    private scanContentDirForContent(folders: Array<string>, content: Array<string>, fullPath: string) {
-
-        var fileSystem = Atomic.getFileSystem();
-
-        folders.length = content.length = 0;
-
-        var _folders = fileSystem.scanDir(fullPath, "", Atomic.SCAN_DIRS, false);
-
-        for (var folder of _folders) {
-
-            if (folder == "." || folder == ".." || this.endsWith(folder, "/..") || this.endsWith(folder, "/."))
-                continue;
-
-            folders.push(folder);
-
-        }
-
-        var _content = fileSystem.scanDir(fullPath, "", Atomic.SCAN_FILES, false);
-
-        for (var c of _content) {
-
-            content.push(c);
-
-        }
-
-    }
-
-    private createButtonLayout(fullpath: string, text: string): Atomic.UILayout {
+    private createButtonLayout(asset:ToolCore.Asset): Atomic.UILayout {
 
         var system = ToolCore.getToolSystem();
         var project = system.project;
         var fs = Atomic.getFileSystem();
 
-        var pathinfo = Atomic.splitPath(fullpath);
+        var pathinfo = Atomic.splitPath(asset.path);
 
         var bitmapID = "Folder.icon";
 
-        if (fs.fileExists(fullpath)) {
+        if (fs.fileExists(asset.path)) {
             bitmapID = "FileBitmap";
         }
 
         if (pathinfo.ext == ".js") {
-            if (project.isComponentsDirOrFile(fullpath)) {
+            if (project.isComponentsDirOrFile(asset.path)) {
                 bitmapID = "ComponentBitmap";
             }
             else {
@@ -297,20 +204,16 @@ class ProjectFrame extends ScriptWidget {
         image.gravity = UI.GRAVITY_RIGHT;
         blayout.addChild(image);
 
-        button.id = fullpath;
+        button.id = asset.guid;
         button.layoutParams = lp;
         button.fontDescription = fd;
-        button.text = text;
+        button.text = asset.name;
         button.skinBg = "TBButton.flat";
         blayout.addChild(button);
 
         return blayout;
     }
 
-
-    private currentContentFolder: string;
-
-
 }
 
 export = ProjectFrame;

+ 316 - 0
Data/AtomicEditor/Resources/EditorData/AtomicEditor/typescript/ui/ProjectFrameOld.ts

@@ -0,0 +1,316 @@
+
+
+import ScriptWidget = require("./ScriptWidget");
+import Editor = require("../editor/Editor");
+
+var UI = Atomic.UI;
+
+class ProjectFrame extends ScriptWidget {
+
+    folderList: Atomic.UIListView;
+
+    constructor(parent: Atomic.UIWidget) {
+
+        super();
+
+        this.load("AtomicEditor/editor/ui/projectframe.tb.txt");
+
+        this.gravity = UI.GRAVITY_TOP_BOTTOM;
+
+        var projectviewcontainer = parent.getWidget("projectviewcontainer");
+
+        projectviewcontainer.addChild(this);
+
+        var foldercontainer = this.getWidget("foldercontainer");
+
+        var folderList = this.folderList = new Atomic.UIListView();
+
+        folderList.rootList.id = "folderList_";
+
+        foldercontainer.addChild(folderList);
+
+        // events
+        this.subscribeToEvent("ProjectLoaded", (data) => this.handleProjectLoaded(data));
+
+    }
+
+
+    handleProjectLoaded(data) {
+
+        this.refresh();
+
+    }
+
+    handleWidgetEvent(data): boolean {
+
+        if (data.type == Atomic.UI.EVENT_TYPE_CLICK) {
+
+            var fs = Atomic.getFileSystem();
+
+            if (data.target && data.target.id.length) {
+
+                var id = data.target.id;
+
+                if (id == "folderList_") {
+
+                    var list = <Atomic.UISelectList> data.target;
+
+                    var selectedId = list.selectedItemID;
+
+                    if (fs.dirExists(selectedId)) {
+                        this.selectCurrentContentFolder(selectedId);
+                    }
+
+                    return true;
+
+                }
+
+                if (id == "..") {
+                    var parentPath = Atomic.getParentPath(this.currentContentFolder);
+                    this.selectCurrentContentFolder(parentPath);
+                    return true;
+                }
+
+                if (fs.dirExists(id)) {
+                    this.selectCurrentContentFolder(id);
+                    return true;
+                }
+
+                if (fs.fileExists(id)) {
+                    this.sendEvent("EditResource", { "path": id });
+                    return true;
+                }
+
+            }
+
+        }
+
+        return false;
+
+    }
+
+
+    refresh() {
+
+        var cfolder = this.currentContentFolder;
+        this.currentContentFolder = "";
+        this.refreshFolders();
+
+    }
+
+    private refreshContent(fullpath: string) {
+
+        var system = ToolCore.getToolSystem();
+        var project = system.project;
+
+        this.currentContentFolder = fullpath;
+
+        var folders = new Array<string>();
+        var content = new Array<string>();
+
+        this.scanContentDirForContent(folders, content, fullpath);
+
+        var container: Atomic.UILayout = <Atomic.UILayout> this.getWidget("contentcontainer");
+
+        container.deleteAllChildren();
+
+        if (fullpath != project.resourcePath) {
+
+            var lp = new Atomic.UILayoutParams();
+            lp.height = 20;
+
+            var fd = new Atomic.UIFontDescription();
+            fd.id = "Vera";
+            fd.size = 11;
+
+            var button = new Atomic.UIButton();
+            button.gravity = UI.GRAVITY_LEFT;
+            button.text = "..                     ";
+            button.id = "..";
+            button.skinBg = "TBButton.flat";
+            button.layoutParams = lp;
+            button.fontDescription = fd;
+
+            container.addChild(button);
+
+        }
+
+        for (var folder of folders) {
+
+            var contentID = Atomic.addTrailingSlash(fullpath + folder);
+            container.addChild(this.createButtonLayout(contentID, folder));
+        }
+
+        for (var c of content) {
+
+            var contentID = Atomic.addTrailingSlash(fullpath) + c;
+            container.addChild(this.createButtonLayout(contentID, c));
+        }
+
+
+    }
+
+    private recursiveAddFolder(parentItemID: number, fullpath: string, folderName: string) {
+
+        var folderList = this.folderList;
+
+        var childItemID = folderList.addChildItem(parentItemID, folderName, "Folder.icon", fullpath);
+
+        var dirs = new Array<string>();
+
+        this.scanDirForFolders(dirs, fullpath);
+
+        for (var folder of dirs) {
+            this.recursiveAddFolder(childItemID, fullpath + folder + "/", folder);
+        }
+
+    }
+
+    private refreshFolders() {
+
+        var system = ToolCore.getToolSystem();
+        var project = system.project;
+
+        var folderList = this.folderList;
+
+        folderList.deleteAllItems();
+
+        var resourcesID = folderList.addRootItem("Resources", "Folder.icon", project.resourcePath);
+
+        var dirs = new Array<string>();
+
+        this.scanDirForFolders(dirs, project.resourcePath);
+
+        for (var folder of dirs) {
+            this.recursiveAddFolder(resourcesID, project.resourcePath + folder + "/", folder);
+        }
+
+        folderList.setExpanded(resourcesID, true);
+        this.refreshContent(project.resourcePath);
+        folderList.rootList.value = 0;
+
+
+    }
+
+    private selectCurrentContentFolder(folder: string) {
+
+        this.folderList.selectItemByID(folder);
+        if (this.currentContentFolder != folder)
+            this.refreshContent(folder);
+    }
+
+    private endsWith(str: string, suffix: string): boolean {
+        return str && str.indexOf(suffix, str.length - suffix.length) !== -1;
+    }
+
+    private scanDirForFolders(dirs: Array<string>, fullpath: string) {
+
+        var fileSystem = Atomic.getFileSystem();
+
+        dirs.length = 0;
+
+        var folders = fileSystem.scanDir(fullpath, "", Atomic.SCAN_DIRS, false);
+
+        for (var folder of folders) {
+
+            if (folder == "." || folder == ".." || this.endsWith(folder, "/..") || this.endsWith(folder, "/."))
+                continue;
+
+            dirs.push(folder);
+
+        }
+
+    }
+
+
+    private scanContentDirForContent(folders: Array<string>, content: Array<string>, fullPath: string) {
+
+        var fileSystem = Atomic.getFileSystem();
+
+        folders.length = content.length = 0;
+
+        var _folders = fileSystem.scanDir(fullPath, "", Atomic.SCAN_DIRS, false);
+
+        for (var folder of _folders) {
+
+            if (folder == "." || folder == ".." || this.endsWith(folder, "/..") || this.endsWith(folder, "/."))
+                continue;
+
+            folders.push(folder);
+
+        }
+
+        var _content = fileSystem.scanDir(fullPath, "", Atomic.SCAN_FILES, false);
+
+        for (var c of _content) {
+
+            content.push(c);
+
+        }
+
+    }
+
+    private createButtonLayout(fullpath: string, text: string): Atomic.UILayout {
+
+        var system = ToolCore.getToolSystem();
+        var project = system.project;
+        var fs = Atomic.getFileSystem();
+
+        var pathinfo = Atomic.splitPath(fullpath);
+
+        var bitmapID = "Folder.icon";
+
+        if (fs.fileExists(fullpath)) {
+            bitmapID = "FileBitmap";
+        }
+
+        if (pathinfo.ext == ".js") {
+            if (project.isComponentsDirOrFile(fullpath)) {
+                bitmapID = "ComponentBitmap";
+            }
+            else {
+                bitmapID = "JavascriptBitmap";
+            }
+        }
+
+        var blayout = new Atomic.UILayout();
+
+        blayout.gravity = UI.GRAVITY_LEFT;
+
+        var spacer = new Atomic.UIWidget();
+        spacer.rect = [0, 0, 8, 8];
+        blayout.addChild(spacer);
+
+        var button = new Atomic.UIButton();
+
+        var lp = new Atomic.UILayoutParams;
+        lp.height = 20;
+
+        var fd = new Atomic.UIFontDescription();
+        fd.id = "Vera";
+        fd.size = 11;
+
+        button.gravity = UI.GRAVITY_LEFT;
+
+        var image = new Atomic.UISkinImage(bitmapID);
+        image.rect = [0, 0, 12, 12];
+        image.gravity = UI.GRAVITY_RIGHT;
+        blayout.addChild(image);
+
+        button.id = fullpath;
+        button.layoutParams = lp;
+        button.fontDescription = fd;
+        button.text = text;
+        button.skinBg = "TBButton.flat";
+        blayout.addChild(button);
+
+        return blayout;
+    }
+
+
+    private currentContentFolder: string;
+
+
+}
+
+export = ProjectFrame;

+ 12 - 0
Source/Atomic/Resource/JSONValue.cpp

@@ -141,6 +141,13 @@ void JSONValue::SetFloat(const String& name, float value)
     AddMember(name, jsonValue);
 }
 
+void JSONValue::SetDouble(const String& name, double value)
+{
+    Value jsonValue;
+    jsonValue.SetDouble(value);
+    AddMember(name, jsonValue);
+}
+
 void JSONValue::SetVector2(const String& name, const Vector2& value)
 {
     SetString(name, value.ToString());
@@ -322,6 +329,11 @@ float JSONValue::GetFloat(const String& name) const
     return (float)GetMember(name).GetDouble();
 }
 
+double JSONValue::GetDouble(const String& name) const
+{
+    return GetMember(name).GetDouble();
+}
+
 Vector2 JSONValue::GetVector2(const String& name) const
 {
     return ToVector2(GetCString(name));

+ 4 - 0
Source/Atomic/Resource/JSONValue.h

@@ -86,6 +86,8 @@ public:
     void SetBool(const String& name, bool value);
     /// Set float.
     void SetFloat(const String& name, float value);
+    /// Set double.
+    void SetDouble(const String& name, double value);
     /// Set vector2.
     void SetVector2(const String& name, const Vector2& value);
     /// Set vector3.
@@ -135,6 +137,8 @@ public:
     bool GetBool(const String& name) const;
     /// Return float.
     float GetFloat(const String& name) const;
+    /// Return double.
+    double GetDouble(const String& name) const;
     /// Return vector2.
     Vector2 GetVector2(const String& name) const;
     /// Return vector3.

+ 10 - 2
Source/AtomicJS/Packages/ToolCore/ToolCore.json

@@ -1,8 +1,16 @@
 {
 	"name" : "ToolCore",
 	"sources" : ["Source/ToolCore", "Source/ToolCore/Project", "Source/ToolCore/Platform", "Source/ToolCore/Command",
-							 "Source/ToolCore/Import"],
+							 "Source/ToolCore/Import", "Source/ToolCore/Assets"],
 	"classes" : ["ToolEnvironment", "ToolSystem", "Project", "ProjectFile", "Platform", "PlatformMac", "PlatformWeb",
-							 "PlatformWindows", "Command", "PlayCmd", "OpenAssetImporter"]
+							 "PlatformWindows", "Command", "PlayCmd", "OpenAssetImporter",
+							 "Asset", "AssetDatabase"],
+	"typescript_decl" : {
+
+		"AssetDatabase" : [
+			"getFolderAssets(folder:string):ToolCore.Asset[];"
+		]
+	}
+
 
 }

+ 76 - 0
Source/ToolCore/Assets/Asset.cpp

@@ -0,0 +1,76 @@
+
+#include <Atomic/IO/FileSystem.h>
+
+#include "ModelImporter.h"
+#include "FolderImporter.h"
+#include "Asset.h"
+
+namespace ToolCore
+{
+
+Asset::Asset(Context* context, const String& guid, unsigned timestamp) :
+    Object(context),
+    guid_(guid),
+    dirty_(false),
+    isFolder_(false)
+{
+
+}
+
+Asset::~Asset()
+{
+
+}
+
+bool Asset::Import()
+{
+    if (importer_.Null())
+        return true;
+
+    return importer_->Import(guid_);
+}
+
+void Asset::SetPath(const String& path)
+{
+    FileSystem* fs = GetSubsystem<FileSystem>();
+
+    path_ = path;
+
+    if (importer_.Null())
+    {
+        if (fs->DirExists(path))
+        {
+            name_ = GetFileName(RemoveTrailingSlash(path));
+            isFolder_ = true;
+            importer_ = new FolderImporter(context_);
+        }
+        else
+        {
+            String ext = GetExtension(path);
+
+            // todo, externalize recognizers
+            if (ext == ".fbx")
+            {
+                name_ = GetFileName(path);
+                importer_ = new ModelImporter(context_);
+            }
+        }
+
+        String assetPath = path + ".asset";
+
+        if (fs->FileExists(assetPath))
+        {
+            importer_->Load(guid_);
+        }
+        else
+        {
+            importer_->Save(guid_);
+        }
+
+        SetDirty(importer_->IsDirty());
+
+    }
+
+}
+
+}

+ 48 - 0
Source/ToolCore/Assets/Asset.h

@@ -0,0 +1,48 @@
+
+#pragma once
+
+#include <Atomic/Core/Object.h>
+
+#include "AssetImporter.h"
+
+using namespace Atomic;
+
+namespace ToolCore
+{
+
+class Asset : public Object
+{
+    OBJECT(Asset);
+
+public:
+    /// Construct.
+    Asset(Context* context, const String& guid, unsigned timestamp);
+    virtual ~Asset();
+
+    bool Import();
+
+    const String& GetGUID() const { return guid_; }
+
+    const String& GetName() { return name_; }
+
+    const String& GetPath() const { return path_; }
+    void SetPath(const String& path);
+
+    void SetDirty(bool dirty) { dirty_ = dirty; }
+    bool IsDirty() const { return dirty_; }
+
+    bool IsFolder() const { return isFolder_; }
+
+private:
+
+    String guid_;
+    String path_;
+    String name_;
+
+    bool dirty_;
+    bool isFolder_;
+
+    SharedPtr<AssetImporter> importer_;
+};
+
+}

+ 204 - 0
Source/ToolCore/Assets/AssetDatabase.cpp

@@ -0,0 +1,204 @@
+
+#include <Poco/MD5Engine.h>
+
+#include <Atomic/IO/Log.h>
+#include <Atomic/IO/File.h>
+#include <Atomic/IO/FileSystem.h>
+
+#include "../ToolEvents.h"
+#include "../ToolSystem.h"
+#include "../Project/Project.h"
+#include "AssetDatabase.h"
+
+
+namespace ToolCore
+{
+
+AssetDatabase::AssetDatabase(Context* context) : Object(context)
+{
+    SubscribeToEvent(E_PROJECTLOADED, HANDLER(AssetDatabase, HandleProjectLoaded));
+}
+
+AssetDatabase::~AssetDatabase()
+{
+
+}
+
+String AssetDatabase::GetCachePath()
+{
+    if (project_.Null())
+        return String::EMPTY;
+
+    return project_->GetProjectPath() + "Cache/";
+
+}
+
+String AssetDatabase::GeneratePathGUID(const String &path)
+{
+    FileSystem* fs = GetSubsystem<FileSystem>();
+
+    Poco::MD5Engine md5;
+
+    if (fs->DirExists(path))
+    {
+        md5.update(path.CString(), path.Length());
+    }
+    else
+    {
+        SharedPtr<File> file(new File(context_, path));
+        PODVector<unsigned char> data;
+
+        if (!data.Size())
+        {
+            // zero length file uses path name instead of data
+            data.Resize(path.Length());
+            memcpy(&data[0], path.CString(), path.Length());
+        }
+        else
+        {
+            data.Resize(file->GetSize());
+            file->Read(&data[0], data.Size());
+        }
+
+        md5.update(&data[0], data.Size());
+    }
+
+    return Poco::MD5Engine::digestToHex(md5.digest()).c_str();
+}
+
+void AssetDatabase::Import(const String& path)
+{
+    FileSystem* fs = GetSubsystem<FileSystem>();
+
+    // nothing for now
+    if (fs->DirExists(path))
+        return;
+}
+
+Asset* AssetDatabase::GetAssetByGUID(const String& guid)
+{
+    List<SharedPtr<Asset>>::ConstIterator itr = assets_.Begin();
+
+    while (itr != assets_.End())
+    {
+        if (guid == (*itr)->GetGUID())
+            return *itr;
+
+        itr++;
+    }
+
+    return 0;
+
+}
+
+void AssetDatabase::Scan()
+{
+    FileSystem* fs = GetSubsystem<FileSystem>();
+    const String& resourcePath = project_->GetResourcePath();
+
+    Vector<String> allResults;
+
+    fs->ScanDir(allResults, resourcePath, "", SCAN_FILES | SCAN_DIRS, true);
+
+    Vector<String> filteredResults;
+
+    for (unsigned i = 0; i < allResults.Size(); i++)
+    {
+        allResults[i] = resourcePath + allResults[i];
+
+        const String& path = allResults[i];
+
+        if (path.StartsWith(".") || path.EndsWith("."))
+            continue;
+
+        String ext = GetExtension(path);
+
+        if (ext == ".asset")
+            continue;
+
+        filteredResults.Push(path);
+    }
+
+    Vector<String> importResults;
+
+    for (unsigned i = 0; i < filteredResults.Size(); i++)
+    {
+        const String& path = filteredResults[i];
+        importResults.Push(path);
+    }
+
+    for (unsigned i = 0; i < importResults.Size(); i++)
+    {
+        //Import(importResults[i]);
+
+        const String& path = importResults[i];
+
+        String md5 = GeneratePathGUID(path);
+
+        // get the current time stamp
+        unsigned ctimestamp = fs->GetLastModifiedTime(path);
+
+        SharedPtr<Asset> asset(new Asset(context_, md5, ctimestamp));
+        assets_.Push(asset);
+
+        asset->SetPath(path);
+
+    }
+
+    PODVector<Asset*> dirty;
+    GetDirtyAssets(dirty);
+
+    for (unsigned i = 0; i < dirty.Size(); i++)
+    {
+        dirty[i]->Import();
+    }
+}
+
+void AssetDatabase::GetFolderAssets(String folder, PODVector<Asset*>& assets) const
+{
+    if (project_.Null())
+        return;
+
+    List<SharedPtr<Asset>>::ConstIterator itr = assets_.Begin();
+
+    if (!folder.Length())
+    {
+        folder = project_->GetResourcePath();
+    }
+
+    folder = AddTrailingSlash(folder);
+
+    while (itr != assets_.End())
+    {
+        String path = GetPath((*itr)->GetPath());
+
+        if (path == folder)
+            assets.Push(*itr);
+
+        itr++;
+    }
+
+}
+
+void AssetDatabase::GetDirtyAssets(PODVector<Asset*>& assets)
+{
+    assets.Clear();
+
+    List<SharedPtr<Asset>>::ConstIterator itr = assets_.Begin();
+
+    while (itr != assets_.End())
+    {
+        if ((*itr)->IsDirty())
+            assets.Push(*itr);
+        itr++;
+    }
+}
+
+void AssetDatabase::HandleProjectLoaded(StringHash eventType, VariantMap& eventData)
+{
+    project_ = GetSubsystem<ToolSystem>()->GetProject();
+
+    Scan();
+}
+
+}

+ 46 - 0
Source/ToolCore/Assets/AssetDatabase.h

@@ -0,0 +1,46 @@
+
+#pragma once
+
+#include <Atomic/Core/Object.h>
+#include <Atomic/Container/List.h>
+#include "Asset.h"
+
+using namespace Atomic;
+
+namespace ToolCore
+{
+
+class Project;
+
+class AssetDatabase : public Object
+{
+    OBJECT(AssetDatabase);
+
+public:
+    /// Construct.
+    AssetDatabase(Context* context);
+    virtual ~AssetDatabase();
+
+    Asset* GetAssetByGUID(const String& guid);
+
+    String GetCachePath();
+
+    void Scan();
+
+    void GetFolderAssets(String folder, PODVector<Asset*>& assets) const;
+
+    void GetDirtyAssets(PODVector<Asset*>& assets);
+
+private:
+
+    void HandleProjectLoaded(StringHash eventType, VariantMap& eventData);
+
+    String GeneratePathGUID(const String& path);
+    void Import(const String& path);
+
+    SharedPtr<Project> project_;
+    List<SharedPtr<Asset>> assets_;
+
+};
+
+}

+ 100 - 0
Source/ToolCore/Assets/AssetImporter.cpp

@@ -0,0 +1,100 @@
+
+#include <Atomic/IO/File.h>
+#include <Atomic/IO/FileSystem.h>
+#include "AssetDatabase.h"
+#include "AssetImporter.h"
+
+namespace ToolCore
+{
+
+AssetImporter::AssetImporter(Context* context) : Object(context),
+    dirty_(true),
+    timestamp_(0)
+{
+    SetDefaults();
+}
+
+AssetImporter::~AssetImporter()
+{
+
+}
+
+void AssetImporter::SetDefaults()
+{
+
+}
+
+bool AssetImporter::Load(const String& guid)
+{
+    AssetDatabase* db = GetSubsystem<AssetDatabase>();
+    Asset* asset = db->GetAssetByGUID(guid);
+    assert(asset);
+
+    const String& path = asset->GetPath();
+    String assetPath = path + ".asset";
+
+    SharedPtr<File> file(new File(context_, assetPath));
+
+    json_ = new JSONFile(context_);
+    json_->Load(*file);
+    file->Close();
+
+    LoadInternal();
+
+    json_ = 0;
+
+
+    return true;
+}
+
+bool AssetImporter::LoadInternal()
+{
+    JSONValue root = json_->GetRoot();
+
+    assert(root.GetInt("version") == 1);
+    guid_ = root.GetString("guid");
+    timestamp_ = (unsigned) root.GetDouble("timestamp");
+
+    return true;
+}
+
+bool AssetImporter::Save(const String& guid)
+{
+
+    FileSystem* fs = GetSubsystem<FileSystem>();
+    AssetDatabase* db = GetSubsystem<AssetDatabase>();
+    Asset* asset = db->GetAssetByGUID(guid);
+    assert(asset);
+
+    const String& path = asset->GetPath();
+    String assetPath = path + ".asset";
+
+    timestamp_ = fs->GetLastModifiedTime(path);
+    guid_ = guid;
+
+    json_ = new JSONFile(context_);
+    json_->CreateRoot();
+    SaveInternal();
+
+    SharedPtr<File> file(new File(context_, assetPath, FILE_WRITE));
+    json_->Save(*file, String("   "));
+    file->Close();
+
+    json_ = 0;
+
+    return true;
+}
+
+bool AssetImporter::SaveInternal()
+{
+    JSONValue root = json_->GetRoot();
+
+    root.SetInt("version", ASSET_VERSION);
+    root.SetString("guid", guid_);
+    root.SetDouble("timestamp", (double) timestamp_);
+
+    return true;
+}
+
+
+}

+ 49 - 0
Source/ToolCore/Assets/AssetImporter.h

@@ -0,0 +1,49 @@
+
+#pragma once
+
+#include <Atomic/Core/Object.h>
+#include <Atomic/Resource/JSONFile.h>
+
+using namespace Atomic;
+
+namespace ToolCore
+{
+
+#define ASSET_VERSION 1
+
+/// deals with .asset files
+class AssetImporter : public Object
+{
+    OBJECT(AssetImporter);
+
+public:
+    /// Construct.
+    AssetImporter(Context* context);
+    virtual ~AssetImporter();
+
+    bool IsDirty() { return dirty_; }
+
+    // load .asset
+    bool Load(const String& guid);
+    // save .asset
+    bool Save(const String& guid);
+
+    virtual void SetDefaults();
+
+    /// Imports to cached data
+    virtual bool Import(const String& guid) = 0;
+
+protected:
+
+    SharedPtr<JSONFile> json_;
+    bool dirty_;
+
+    String guid_;
+    unsigned timestamp_;
+
+    virtual bool LoadInternal();
+    virtual bool SaveInternal();
+
+};
+
+}

+ 60 - 0
Source/ToolCore/Assets/FolderImporter.cpp

@@ -0,0 +1,60 @@
+
+#include "Asset.h"
+#include "AssetDatabase.h"
+#include "FolderImporter.h"
+
+namespace ToolCore
+{
+
+FolderImporter::FolderImporter(Context* context) : AssetImporter(context)
+{
+
+}
+
+FolderImporter::~FolderImporter()
+{
+
+}
+
+void FolderImporter::SetDefaults()
+{
+    AssetImporter::SetDefaults();
+}
+
+bool FolderImporter::Import(const String& guid)
+{
+    AssetDatabase* db = GetSubsystem<AssetDatabase>();
+    Asset* asset = db->GetAssetByGUID(guid);
+
+    if (!asset)
+        return false;
+
+    return true;
+}
+
+bool FolderImporter::LoadInternal()
+{
+    if (!AssetImporter::LoadInternal())
+        return false;
+
+    JSONValue root = json_->GetRoot();
+
+    JSONValue import = root.GetChild("FolderImporter", JSON_OBJECT);
+
+    return true;
+}
+
+bool FolderImporter::SaveInternal()
+{
+    if (!AssetImporter::SaveInternal())
+        return false;
+
+    JSONValue root = json_->GetRoot();
+
+    JSONValue import = root.CreateChild("FolderImporter");
+
+    return true;
+}
+
+
+}

+ 29 - 0
Source/ToolCore/Assets/FolderImporter.h

@@ -0,0 +1,29 @@
+
+#pragma once
+
+#include "AssetImporter.h"
+
+namespace ToolCore
+{
+
+class FolderImporter : public AssetImporter
+{
+    OBJECT(FolderImporter);
+
+public:
+    /// Construct.
+    FolderImporter(Context* context);
+    virtual ~FolderImporter();
+
+    virtual void SetDefaults();
+
+    bool Import(const String& guid);
+
+protected:
+
+    virtual bool LoadInternal();
+    virtual bool SaveInternal();
+
+};
+
+}

+ 80 - 0
Source/ToolCore/Assets/ModelImporter.cpp

@@ -0,0 +1,80 @@
+
+#include "../Import/OpenAssetImporter.h"
+
+#include "Asset.h"
+#include "AssetDatabase.h"
+#include "ModelImporter.h"
+
+namespace ToolCore
+{
+
+/// Node + Model (static or animated)
+ModelImporter::ModelImporter(Context* context) : AssetImporter(context)
+{
+
+}
+
+ModelImporter::~ModelImporter()
+{
+
+}
+
+void ModelImporter::SetDefaults()
+{
+    AssetImporter::SetDefaults();
+}
+
+bool ModelImporter::Import(const String& guid)
+{
+    AssetDatabase* db = GetSubsystem<AssetDatabase>();
+    Asset* asset = db->GetAssetByGUID(guid);
+
+    if (!asset)
+        return false;
+
+    SharedPtr<OpenAssetImporter> importer(new OpenAssetImporter(context_));
+
+    //importer->SetVerboseLog(true);
+
+    if (importer->Load(asset->GetPath()))
+    {
+        String cachePath = db->GetCachePath();
+
+        cachePath += guid;
+
+        importer->ExportModel(cachePath);
+    }
+    else
+    {
+        return false;
+    }
+
+    return true;
+}
+
+bool ModelImporter::LoadInternal()
+{
+    if (!AssetImporter::LoadInternal())
+        return false;
+
+    JSONValue root = json_->GetRoot();
+
+    JSONValue import = root.GetChild("ModelImporter", JSON_OBJECT);
+
+    return true;
+}
+
+bool ModelImporter::SaveInternal()
+{
+    if (!AssetImporter::SaveInternal())
+        return false;
+
+    JSONValue root = json_->GetRoot();
+
+    JSONValue import = root.CreateChild("ModelImporter");
+
+    return true;
+}
+
+
+}

+ 29 - 0
Source/ToolCore/Assets/ModelImporter.h

@@ -0,0 +1,29 @@
+
+#pragma once
+
+#include "AssetImporter.h"
+
+namespace ToolCore
+{
+
+class ModelImporter : public AssetImporter
+{
+    OBJECT(ModelImporter);
+
+public:
+    /// Construct.
+    ModelImporter(Context* context);
+    virtual ~ModelImporter();
+
+    virtual void SetDefaults();
+
+    bool Import(const String& guid);
+
+protected:
+
+    virtual bool LoadInternal();
+    virtual bool SaveInternal();
+
+};
+
+}

+ 21 - 11
Source/ToolCore/Import/OpenAssetImporter.cpp

@@ -95,7 +95,7 @@ bool OpenAssetImporter::Load(const String &assetPath)
     if (verboseLog_)
         Assimp::DefaultLogger::create("", Assimp::Logger::VERBOSE, aiDefaultLogStream_STDOUT);
 
-    PrintLine("Reading file " + assetPath);
+    //PrintLine("Reading file " + assetPath);
 
     scene_ = aiImportFile(GetNativePath(assetPath).CString(), aiCurrentFlags_);
 
@@ -144,7 +144,7 @@ void OpenAssetImporter::BuildAndSaveModel(OutModel& model)
     if (!model.meshes_.Size())
         ErrorExit("No geometries found starting from node " + rootNodeName);
 
-    PrintLine("Writing model " + rootNodeName);
+    //PrintLine("Writing model " + rootNodeName);
 
     SharedPtr<Model> outModel(new Model(context_));
     Vector<PODVector<unsigned> > allBoneMappings;
@@ -210,6 +210,9 @@ void OpenAssetImporter::BuildAndSaveModel(OutModel& model)
             vb = new VertexBuffer(context_);
             ib = new IndexBuffer(context_);
 
+            vb->SetShadowed(true);
+            ib->SetShadowed(true);
+
             if (combineBuffers)
             {
                 ib->SetSize(model.totalIndices_, largeIndices);
@@ -238,12 +241,15 @@ void OpenAssetImporter::BuildAndSaveModel(OutModel& model)
 
         SharedPtr<Geometry> geom(new Geometry(context_));
 
-        PrintLine("Writing geometry " + String(i) + " with " + String(mesh->mNumVertices) + " vertices " +
-            String(validFaces * 3) + " indices");
+        //PrintLine("Writing geometry " + String(i) + " with " + String(mesh->mNumVertices) + " vertices " +
+        //    String(validFaces * 3) + " indices");
 
         unsigned char* vertexData = vb->GetShadowData();
         unsigned char* indexData = ib->GetShadowData();
 
+        assert(vertexData);
+        assert(indexData);
+
         // Build the index data
         if (!largeIndices)
         {
@@ -311,8 +317,8 @@ void OpenAssetImporter::BuildAndSaveModel(OutModel& model)
     // Build skeleton if necessary
     if (model.bones_.Size() && model.rootBone_)
     {
-        PrintLine("Writing skeleton with " + String(model.bones_.Size()) + " bones, rootbone " +
-            FromAIString(model.rootBone_->mName));
+        //PrintLine("Writing skeleton with " + String(model.bones_.Size()) + " bones, rootbone " +
+        //    FromAIString(model.rootBone_->mName));
 
         Skeleton skeleton;
         Vector<Bone>& bones = skeleton.GetModifiableBones();
@@ -375,7 +381,9 @@ void OpenAssetImporter::BuildAndSaveModel(OutModel& model)
                 listFile.WriteLine(GetMeshMaterialName(model.meshes_[i]));
         }
         else
+        {
             PrintLine("Warning: could not write material list file " + materialListName);
+        }
     }
 }
 
@@ -457,7 +465,7 @@ void OpenAssetImporter::CollectSceneModels(OutScene& scene, aiNode* node)
             {
                 if (scene.models_[i].meshIndices_ == model.meshIndices_)
                 {
-                    PrintLine("Added node " + FromAIString(node->mName));
+                    //PrintLine("Added node " + FromAIString(node->mName));
                     scene.nodes_.Push(node);
                     scene.nodeModelIndices_.Push(i);
                     unique = false;
@@ -467,8 +475,8 @@ void OpenAssetImporter::CollectSceneModels(OutScene& scene, aiNode* node)
         }
         if (unique)
         {
-            PrintLine("Added model " + model.outName_);
-            PrintLine("Added node " + FromAIString(node->mName));
+//            PrintLine("Added model " + model.outName_);
+//            PrintLine("Added node " + FromAIString(node->mName));
             CollectBones(model);
             BuildBoneCollisionInfo(model);
             if (!noAnimations_)
@@ -586,7 +594,9 @@ void OpenAssetImporter::CollectBonesFinal(PODVector<aiNode*>& dest, const HashSe
         }
 
         if (includeBone)
-            PrintLine("Including non-skinning bone " + boneName);
+        {
+            //PrintLine("Including non-skinning bone " + boneName);
+        }
     }
 
     if (includeBone)
@@ -708,7 +718,7 @@ void OpenAssetImporter::BuildAndSaveAnimations(OutModel* model)
         outAnim->SetAnimationName(animName);
         outAnim->SetLength(duration * tickConversion);
 
-        PrintLine("Writing animation " + animName + " length " + String(outAnim->GetLength()));
+        //PrintLine("Writing animation " + animName + " length " + String(outAnim->GetLength()));
         Vector<AnimationTrack> tracks;
         for (unsigned j = 0; j < anim->mNumChannels; ++j)
         {

+ 1 - 0
Source/ToolCore/JSBind/JSBClass.cpp

@@ -349,6 +349,7 @@ void JSBClass::AddPropertyFunction(JSBFunction* function)
     if (!prop)
     {
         prop = new JSBProperty();
+        prop->name_ = function->GetPropertyName();
         properties_[function->GetPropertyName()] = prop;
     }
 

+ 31 - 0
Source/ToolCore/JSBind/JSBClass.h

@@ -36,6 +36,7 @@ public:
 
 class JSBProperty
 {
+
 public:
     String name_;
     JSBFunction* getter_;
@@ -46,6 +47,36 @@ public:
 
     }
 
+    // returns proper case for property name
+    // based on whether the Getter/Setter is all caps
+    // GetMyValue -> myValue;
+    // GetGUID -> guid
+    String GetCasePropertyName()
+    {
+        if (!name_.Length())
+            return name_;
+
+        bool allUpper = true;
+
+        for (unsigned k = 0; k < name_.Length(); k++)
+        {
+            if (!isupper(name_[k]))
+            {
+                allUpper = false;
+                break;
+            }
+        }
+
+        if (allUpper)
+        {
+            return name_.ToLower();
+        }
+
+        String name = name_;
+        name[0] = tolower(name[0]);
+        return name;
+    }
+
 };
 
 

+ 1 - 3
Source/ToolCore/JSBind/JSBDoc.cpp

@@ -159,9 +159,7 @@ void JSBDoc::ExportModuleClasses(JSBModule* module)
                 continue;
 
             String scriptType = GetScriptType(ftype);
-
-            String scriptName =  propertyNames[j];
-            scriptName[0] = tolower(scriptName[0]);
+            String scriptName = prop->GetCasePropertyName();
 
             if (desc.Length())
             {

+ 2 - 2
Source/ToolCore/JSBind/JSBModuleWriter.cpp

@@ -84,8 +84,8 @@ void JSBModuleWriter::WriteClassDeclaration(String& source)
                     source.Append("duk_put_prop_string(ctx, -2, \"set\");\n");
                 }
 
-                pnames[j][0] = tolower(pnames[j][0]);
-                source.AppendWithFormat("duk_put_prop_string(ctx, -2, \"%s\");\n", pnames[j].CString());
+                String propertyName = prop->GetCasePropertyName();
+                source.AppendWithFormat("duk_put_prop_string(ctx, -2, \"%s\");\n", propertyName.CString());
 
             }
 

+ 1 - 3
Source/ToolCore/JSBind/JSBTypeScript.cpp

@@ -171,9 +171,7 @@ void JSBTypeScript::ExportModuleClasses(JSBModule* module)
                 continue;
 
             String scriptType = GetScriptType(ftype);
-
-            String scriptName =  propertyNames[j];
-            scriptName[0] = tolower(scriptName[0]);
+            String scriptName = prop->GetCasePropertyName();
 
             source_ += "      " + scriptName + ": " + scriptType + ";\n";
 

+ 1 - 1
Source/ToolCore/Project/Project.h

@@ -55,7 +55,7 @@ public:
     ProjectBuildSettings* GetBuildSettings() { return buildSettings_; }
     ProjectUserPrefs* GetUserPrefs() { return userPrefs_; }
 
-    const String& GetProjectPath() { return projectPath_; }
+    const String& GetProjectPath() const { return projectPath_; }
     const String& GetProjectFilePath() { return projectFilePath_; }
     String GetUserPrefsFullPath();
     String GetBuildSettingsFullPath();

+ 3 - 1
Source/ToolCore/ToolSystem.cpp

@@ -6,10 +6,12 @@
 #include "Platform/PlatformWeb.h"
 #include "Platform/PlatformMac.h"
 #include "Platform/PlatformWindows.h"
+#include "Assets/AssetDatabase.h"
 #include "Net/CurlManager.h"
 #include "License/LicenseSystem.h"
 #include "Build/BuildSystem.h"
 
+
 #include "ToolSystem.h"
 #include "ToolEnvironment.h"
 
@@ -22,7 +24,7 @@ namespace ToolCore
 ToolSystem::ToolSystem(Context* context) : Object(context),
     cli_(false)
 {
-
+    context_->RegisterSubsystem(new AssetDatabase(context_));
     context_->RegisterSubsystem(new CurlManager(context_));
     context_->RegisterSubsystem(new LicenseSystem(context_));
     context_->RegisterSubsystem(new BuildSystem(context_));

+ 47 - 0
Source/ToolCoreJS/ToolCoreJS.cpp

@@ -2,6 +2,8 @@
 #include <AtomicJS/Javascript/JSVM.h>
 #include <ToolCore/ToolEnvironment.h>
 #include <ToolCore/ToolSystem.h>
+#include <ToolCore/Assets/AssetDatabase.h>
+#include <ToolCore/Project/Project.h>
 
 using namespace Atomic;
 
@@ -29,6 +31,40 @@ static int js_atomic_GetToolSystem(duk_context* ctx)
     return 1;
 }
 
+static int js_atomic_GetAssetDatabase(duk_context* ctx)
+{
+    JSVM* vm = JSVM::GetJSVM(ctx);
+    js_push_class_object_instance(ctx, vm->GetSubsystem<AssetDatabase>());
+    return 1;
+}
+
+
+static int AssetDatabase_GetFolderAssets(duk_context* ctx)
+{
+    JSVM* vm = JSVM::GetJSVM(ctx);
+    ToolSystem* ts = vm->GetSubsystem<ToolSystem>();
+    AssetDatabase* db = vm->GetSubsystem<AssetDatabase>();
+    Project* project = ts->GetProject();
+
+    String folder = duk_require_string(ctx, 0);
+
+    duk_push_array(ctx);
+
+    if (!project)
+        return 1;
+
+    PODVector<Asset*> assets;
+    db->GetFolderAssets(folder, assets);
+
+    for(unsigned i = 0; i < assets.Size(); i++)
+    {
+        js_push_class_object_instance(ctx, assets[i], 0);
+        duk_put_prop_index(ctx, -2, i);
+    }
+
+    return 1;
+}
+
 void jsapi_init_toolcore(JSVM* vm)
 {
     duk_context* ctx = vm->GetJSContext();
@@ -46,8 +82,19 @@ void jsapi_init_toolcore(JSVM* vm)
     duk_push_c_function(ctx, js_atomic_GetToolSystem, 0);
     duk_put_prop_string(ctx, -2, "getToolSystem");
 
+    duk_push_c_function(ctx, js_atomic_GetAssetDatabase, 0);
+    duk_put_prop_string(ctx, -2, "getAssetDatabase");
+
+
     duk_pop(ctx);
 
+
+    js_class_get_prototype(ctx, "ToolCore", "AssetDatabase");
+    duk_push_c_function(ctx, AssetDatabase_GetFolderAssets, 1);
+    duk_put_prop_string(ctx, -2, "getFolderAssets");
+    duk_pop(ctx);
+
+
 }
 
 }