emscripten Humble Cloud interface
Edward Rudd
2014-09-15 ebbe7d4d87d56060e3f8b3ac1dda3e43f4ff8711

add in initial humble_fetch_asset_data method to replace emscripten_async_wget_data. (default implementation does the SAME exact thing)

5 files modified
109 ■■■■ changed files
client/CMakeLists.txt 2 ●●● patch | view | raw | blame | history
client/library/humble_api.h 4 ●●● patch | view | raw | blame | history
client/library/library_humble.js 69 ●●●●● patch | view | raw | blame | history
client/test/main.cpp 25 ●●●● patch | view | raw | blame | history
client/test/shell.html 9 ●●●● patch | view | raw | blame | history
client/CMakeLists.txt
@@ -19,7 +19,7 @@
    ../humble_cloud/urkle_cloud.js
ASM_FLAG
    NO_EXIT_RUNTIME=1
    EXPORTED_FUNCTIONS="['_main','_test_list_files']"
    EXPORTED_FUNCTIONS="['_main','_test_list_files','_test_async_fetch']"
JS_LIBS
    library/library_cloudfs.js
    library/library_humble.js
client/library/humble_api.h
@@ -1,6 +1,8 @@
#ifndef __HUMBLE_CLOUD_H__
#define __HUMBLE_CLOUD_H__
#include <emscripten/emscripten.h>
#ifdef __cplusplus
extern "C" {
#endif
@@ -9,7 +11,7 @@
    void humble_sync();
    char *humble_get_url_for_asset(const char* assetPath);
    void humble_fetch_asset_data(const char* url, void *arg, em_async_wget_onload_func onload, em_arg_callback_func onerror);
#ifdef __cplusplus
};
client/library/library_humble.js
@@ -1,21 +1,78 @@
var LibraryHUMBLE = {
    $HUMBLE_API: {
        file_cache: {},
        options: {
            locateAsset: null,
            buildCacheKey: null
        },
        configure: function(options) {
            mergeInto(HUMBLE_API.options, options);
        },
        locateAsset: function(path) {
            if (HUMBLE_API.options.locateAsset) {
                return HUMBLE_API.options.locateAsset.call(HUMBLE_API, path);
            } else {
                return path;
            }
        },
        buildCacheKey: function(path) {
            if (HUMBLE_API.options.buildCacheKey) {
                return HUMBLE_API.options.buildCacheKey.call(HUMBLE_API, path);
            } else {
                return path;
            }
        },
        storeToCache: function(path, byteArray, ondone) {
            HUMBLE_API.file_cache[path] = byteArray;
            ondone(null);
        },
        fetchFromCache: function(path, ondone, onfail) {
            if (path in HUMBLE_API.file_cache) {
                ondone(HUMBLE_API.file_cache[path]);
            } else {
                // NULL for file not cached.  Error object otherwise
                onfail(null);
            }
        }
    },
    humble_init__deps: ['$CLOUDFS'],
    humble_init: function() {
        // Dummy function to pull in the rest of the functions
    },
    humble_sync__deps: ['$FS'],
    humble_sync__deps: ['$FS', '$CLOUDFS'],
    humble_sync: function() {
        FS.syncfs(function (err) {
            console.log('File Sync');
        });
    },
    humble_get_url_for_asset: function(assetPath) {
    humble_fetch_asset_data__deps: ['$BROWSER', '$HUMBLE_API'],
    humble_fetch_asset_data: function(assetPath, arg, onload, onerror) {
        var path = Pointer_stringify(assetPath);
        var url = 'http://localhost/test/' + path;
        var ret = allocate(intArrayFromString(url), 'i8', ALLOC_NORMAL);
        var cacheKey = HUMBLE_API.buildCacheKey(path);
        return ret;
        HUMBLE_API.fetchFromCache(cacheKey, function(byteArray) {
            var buffer = _malloc(byteArray.length);
            HEAPU8.set(byteArray, buffer);
            Runtime.dynCall('viii', onload, [arg, buffer, byteArray.length]);
            _free(buffer);
        }, function(err) {
            var url = HUMBLE_API.locateAsset(path);
            Browser.asyncLoad(url, function(byteArray) {
                HUMBLE_API.storeToCache(cacheKey, byteArray, function(err) {
                    var buffer = _malloc(byteArray.length);
                    HEAPU8.set(byteArray, buffer);
                    Runtime.dynCall('viii', onload, [arg, buffer, byteArray.length]);
                    _free(buffer);
                });
            }, function() {
                if (onerror) Runtime.dynCall('vi', onerror, [arg]);
            }, true /* NO run dependency */);
        });
    }
};
autoAddDeps(LibraryHUMBLE, '$CLOUDFS');
mergeInto(LibraryManager.library, LibraryHUMBLE);
client/test/main.cpp
@@ -8,6 +8,7 @@
extern "C" {
    void test_list_files();
    void test_async_fetch(const char* url);
}
std::string userDataPath = "/user_data";
@@ -44,17 +45,29 @@
    list_folder(userDataPath);
}
void on_get_file(void* arg, void* data, int data_size)
{
    std::cout << "File fetch succeeded: " << data_size << "\n";
    std::string tdata((char *)data, data_size);
    std::cout << "  " << tdata << "\n";
}
void on_fail_file(void *arg)
{
    std::cout << "File fetch failed\n";
}
void test_async_fetch(const char* url)
{
    std::cout << "Fetch file: " << url << "\n";
    humble_fetch_asset_data(url, NULL, on_get_file, on_fail_file);
}
int main(int argc, char * argv[])
{
    std::cout << "Welcome Main\n";
    // call dummy function to init cloud
    humble_init();
    // Test humble_get_url_for_asset
    char * path = humble_get_url_for_asset("textures/icon1.png");
    std::cout << "humble_get_url_for_asset returned " << path << "\n";
    free(path);
    return 0;
}
client/test/shell.html
@@ -1213,6 +1213,7 @@
         <span><input type="button" value="Fetch from Cloud" onclick="fetch_from_cloud()"></span>
         <span><input type="button" value="Push to Cloud" onclick="push_to_cloud()"></span>
         <span><input type="button" value="Populate local data" onclick="populate_user_data()"></span>
         <span><input type="button" value="Async Fetch" onclick="call_test_function('test_async_fetch', 'test_file.txt')"></span>
      </span>
      <canvas class="emscripten" id="canvas" oncontextmenu="event.preventDefault()"></canvas>
    </div>
@@ -1334,14 +1335,18 @@
          });
      });
      var test_functions = {};
      var test_function_args = {
          'test_async_fetch': ['string']
      };
      function call_test_function(func)
      {
          if (!(func in test_functions))
          {
              var f = Module.cwrap(func,'void', []);
              var f = Module.cwrap(func, 'void', test_function_args[func] || []);
              test_functions[func] = f;
          }
          test_functions[func]();
          var args = Array.prototype.slice.call(arguments, 1)
          test_functions[func].apply(test_functions, args);
      }
      function fetch_from_cloud()
      {