feat! js_interop improvements
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.27)
|
||||
cmake_minimum_required(VERSION 3.22)
|
||||
|
||||
set(PROJECT_NAME "thermion_dart")
|
||||
project(${PROJECT_NAME})
|
||||
@@ -11,64 +11,79 @@ set(MODULE_NAME "thermion_dart")
|
||||
|
||||
set(EMCC_CFLAGS --bind)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sALLOW_TABLE_GROWTH=1)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sALLOW_MEMORY_GROWTH=1)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sALLOW_MEMORY_GROWTH=0)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORT_NAME=${MODULE_NAME})
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORT_ALL=1)
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sLINKABLE=1)
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sSIDE_MODULE)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sINITIAL_MEMORY=512mb)
|
||||
#set(EMCC_CFLAGS ${EMCC_CFLAGS} -sENVIRONMENT=shell,node,web)
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sENVIRONMENT=worker)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sMODULARIZE)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sERROR_ON_UNDEFINED_SYMBOLS=0 )
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORTED_RUNTIME_METHODS=wasmExports,wasmTable,addFunction,removeFunction,ccall,cwrap,allocate,intArrayFromString,intArrayToString,getValue,setValue,UTF8ToString,stringToUTF8,writeArrayToMemory)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORTED_FUNCTIONS=_malloc,stackAlloc,_free)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORTED_RUNTIME_METHODS=wasmExports,wasmTable,addFunction,removeFunction,ccall,cwrap,allocate,intArrayFromString,intArrayToString,getValue,setValue,UTF8ToString,stringToUTF8,writeArrayToMemory,lengthBytesUTF8,HEAPU8)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sEXPORTED_FUNCTIONS=_malloc,stackAlloc,_free,stackSave,stackRestore)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sFULL_ES3)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sASSERTIONS)
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sPTHREAD_POOL_SIZE=1)
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sALLOW_BLOCKING_ON_MAIN_THREAD=0)
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sOFFSCREEN_FRAMEBUFFER=1)
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sOFFSCREENCANVAS_SUPPORT=1)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
#add_compile_definitions(ENABLE_TRACING=1)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sASSERTIONS=2)
|
||||
endif()
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sPTHREAD_POOL_SIZE=1)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sALLOW_BLOCKING_ON_MAIN_THREAD=1)
|
||||
#set(EMCC_CFLAGS ${EMCC_CFLAGS} -sOFFSCREEN_FRAMEBUFFER=1)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sOFFSCREENCANVAS_SUPPORT=1)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sNO_DISABLE_EXCEPTION_CATCHING)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sASYNCIFY=1)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sSAFE_HEAP=1)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sASYNCIFY=0)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sMIN_WEBGL_VERSION=2)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sMAX_WEBGL_VERSION=2)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sFETCH=1)
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sUSE_PTHREADS)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sFETCH=0)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sUSE_PTHREADS)
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sGL_ASSERTIONS=1)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sGL_DEBUG=1)
|
||||
endif()
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sPROXY_TO_PTHREAD)
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -sPROXY_TO_WORKER=1)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sSHARED_MEMORY=0)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -lidbfs.js)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sSHARED_MEMORY=1)
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -lidbfs.js)
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -sFORCE_FILESYSTEM=1)
|
||||
|
||||
set(EMCC_CFLAGS ${EMCC_CFLAGS} -matomics -mbulk-memory)
|
||||
# set(EMCC_CFLAGS ${EMCC_CFLAGS} -pie)
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers -Wno-deprecated-literal-operator -stdlib=libc++ -std=c++17 -fPIC --no-entry")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pie")
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers -Wno-deprecated-literal-operator -stdlib=libc++ -std=c++17 -fPIC -O3 --no-entry ")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -pie")
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O1") #-fsanitize=undefined
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O1")
|
||||
endif()
|
||||
|
||||
add_link_options(${EMCC_CFLAGS})
|
||||
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O1") #-fsanitize=undefined
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O1")
|
||||
endif()
|
||||
|
||||
add_link_options(${EMCC_CFLAGS} -pthread -lGL)
|
||||
|
||||
link_directories("${CMAKE_CURRENT_SOURCE_DIR}/lib")
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY build/out)
|
||||
|
||||
add_executable(${MODULE_NAME}
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/SceneManager.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/FilamentViewer.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/ThermionDartApi.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/ThermionDartFFIApi.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/Gizmo.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/GridOverlay.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/StreamBufferAdapter.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/TimeIt.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/camutils/Manipulator.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/camutils/Bookmark.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/material/image.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/material/unlit_fixed_size.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/ThermionDartWebApi.cpp"
|
||||
)
|
||||
file(GLOB SOURCES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/*.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../src/**/*.cpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/resources/*.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/material/*.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/src/cpp/ThermionWebApi.cpp"
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/../src/rendering/EmscriptenTest.cpp"
|
||||
)
|
||||
|
||||
add_executable(${MODULE_NAME} ${SOURCES})
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES
|
||||
CXX_VISIBILITY_PRESET hidden)
|
||||
target_compile_definitions(${MODULE_NAME} PRIVATE FLUTTER_PLUGIN_IMPL)
|
||||
|
||||
target_compile_options(${MODULE_NAME} PRIVATE -matomics -mbulk-memory)
|
||||
target_compile_features(${MODULE_NAME} PRIVATE cxx_std_17)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
@@ -89,12 +104,12 @@ set_property(TARGET geometry PROPERTY IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT
|
||||
add_library(filament STATIC IMPORTED)
|
||||
set_property(TARGET filament PROPERTY IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/lib/debug/libfilament.a")
|
||||
set_property(TARGET filament PROPERTY IMPORTED_IMPLIB_PROFILE "${CMAKE_CURRENT_SOURCE_DIR}/lib/release/libfilament.a")
|
||||
set_property(TARGET filament PROPERTY IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/libfilament.a")
|
||||
set_property(TARGET filament PROPERTY IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lib/release/libfilament.a")
|
||||
|
||||
add_library(filameshio STATIC IMPORTED)
|
||||
set_property(TARGET filameshio PROPERTY IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/lib/debug/libfilameshio.a")
|
||||
set_property(TARGET filameshio PROPERTY IMPORTED_IMPLIB_PROFILE "${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/libfilameshio.a")
|
||||
set_property(TARGET filameshio PROPERTY IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lib/Release/libfilameshio.a")
|
||||
set_property(TARGET filameshio PROPERTY IMPORTED_IMPLIB_PROFILE "${CMAKE_CURRENT_SOURCE_DIR}/lib/release/libfilameshio.a")
|
||||
set_property(TARGET filameshio PROPERTY IMPORTED_LOCATION_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/lib/release/libfilameshio.a")
|
||||
|
||||
add_library(filamat STATIC IMPORTED)
|
||||
set_property(TARGET filamat PROPERTY IMPORTED_LOCATION_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/lib/debug/libfilamat.a")
|
||||
@@ -226,10 +241,3 @@ target_link_libraries(${MODULE_NAME}
|
||||
tinyexr
|
||||
)
|
||||
|
||||
# add_custom_command(TARGET ${MODULE_NAME} POST_BUILD
|
||||
# COMMAND dart --enable-experiment=native-assets run ffigen --config ffigen/web.yaml WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../
|
||||
# COMMAND ${CMAKE_COMMAND} -DINPUTFILE=${CMAKE_CURRENT_SOURCE_DIR}/../../lib/thermion_dart/compatibility/web/thermion_dart.g.dart -DOUTPUTFILE=${CMAKE_CURRENT_SOURCE_DIR}/../../lib/thermion_dart/compatibility/web/thermion_dart.g.dart "-DTO_REPLACE=symbol: '" "-DREPLACEMENT=symbol: '_" -P ${CMAKE_CURRENT_SOURCE_DIR}/replace_in_file.cmake
|
||||
# # COMMAND ${CMAKE_COMMAND} -DINPUTFILE=${CMAKE_CURRENT_SOURCE_DIR}/build/build/out/thermion_dart.js -DOUTPUTFILE=${CMAKE_CURRENT_SOURCE_DIR}/build/build/out/thermion_dart.js "-DTO_REPLACE=var moduleRtn" "-DREPLACEMENT=var moduleRtn\;GLctx=moduleArg.ctx" -P ${CMAKE_CURRENT_SOURCE_DIR}/replace_in_file.cmake
|
||||
# VERBATIM
|
||||
# )
|
||||
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
#ifndef _FLUTTER_FILAMENT_WEB_RESOURCE_LOADER_H
|
||||
#define _FLUTTER_FILAMENT_WEB_RESOURCE_LOADER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <emscripten/html5_webgl.h>
|
||||
|
||||
#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default")))
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_load_resource_callback(void* data, int32_t length, void* context);
|
||||
FLUTTER_PLUGIN_EXPORT char thermion_flutter_web_get(char* ptr, int32_t offset);
|
||||
FLUTTER_PLUGIN_EXPORT float thermion_flutter_web_get_float(float* ptr, int32_t offset);
|
||||
FLUTTER_PLUGIN_EXPORT double thermion_flutter_web_get_double(double* ptr, int32_t offset);
|
||||
FLUTTER_PLUGIN_EXPORT void* thermion_flutter_web_get_pointer(void** ptr, int32_t offset);
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_set(char* ptr, int32_t offset, int32_t val);
|
||||
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_set_float(float* ptr, int32_t offset, float val);
|
||||
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_set_double(double* ptr, int32_t offset, double val);
|
||||
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_set_pointer(void** ptr, int32_t offset, void* val);
|
||||
|
||||
FLUTTER_PLUGIN_EXPORT int32_t thermion_flutter_web_get_int32(int32_t* ptr, int32_t offset);
|
||||
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_set_int32(int32_t* ptr, int32_t offset, int32_t value);
|
||||
FLUTTER_PLUGIN_EXPORT long thermion_flutter_web_get_address(void** out);
|
||||
FLUTTER_PLUGIN_EXPORT void* thermion_flutter_web_allocate(int32_t size);
|
||||
FLUTTER_PLUGIN_EXPORT void thermion_flutter_web_free(void* ptr);
|
||||
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE thermion_dart_web_create_gl_context();
|
||||
FLUTTER_PLUGIN_EXPORT void* thermion_dart_web_get_resource_loader_wrapper();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
16
thermion_dart/native/web/include/ThermionWebApi.h
Normal file
16
thermion_dart/native/web/include/ThermionWebApi.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include <emscripten/html5_webgl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void Thermion_resizeCanvas(int width, int height);
|
||||
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE Thermion_createGLContext();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,225 +0,0 @@
|
||||
#include "ThermionFlutterWebApi.h"
|
||||
#include "ResourceBuffer.hpp"
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#include <emscripten/threading.h>
|
||||
#include <emscripten/val.h>
|
||||
#include <emscripten/fetch.h>
|
||||
|
||||
using emscripten::val;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
//
|
||||
// Since are using -sMAIN_MODULE with -sPTHREAD_POOL_SIZE=1, main will be called when the first worker is spawned
|
||||
//
|
||||
|
||||
// EMSCRIPTEN_KEEPALIVE int main() {
|
||||
// std::cout << "WEBAPI MAIN " << std::endl;
|
||||
// return 0;
|
||||
// }
|
||||
|
||||
std::string _assetPathPrefix;
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void thermion_dart_web_set_asset_path_prefix(const char* prefix) {
|
||||
_assetPathPrefix = std::string(prefix);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE EMSCRIPTEN_WEBGL_CONTEXT_HANDLE thermion_dart_web_create_gl_context() {
|
||||
|
||||
EM_ASM(
|
||||
FS.mkdir('/indexed');
|
||||
FS.mount(IDBFS, {}, '/indexed');
|
||||
FS.syncfs(true, function (err) {
|
||||
if (err) {
|
||||
console.error('Error mounting IDBFS:', err);
|
||||
} else {
|
||||
console.log('IDBFS mounted successfully');
|
||||
}
|
||||
});
|
||||
);
|
||||
|
||||
std::cout << "Creating WebGL context." << std::endl;
|
||||
|
||||
EmscriptenWebGLContextAttributes attr;
|
||||
|
||||
emscripten_webgl_init_context_attributes(&attr);
|
||||
attr.alpha = EM_TRUE;
|
||||
attr.depth = EM_TRUE;
|
||||
attr.stencil = EM_FALSE;
|
||||
attr.antialias = EM_FALSE;
|
||||
attr.explicitSwapControl = EM_FALSE;
|
||||
attr.preserveDrawingBuffer = EM_TRUE;
|
||||
attr.proxyContextToMainThread = EMSCRIPTEN_WEBGL_CONTEXT_PROXY_DISALLOW;
|
||||
attr.enableExtensionsByDefault = EM_TRUE;
|
||||
attr.renderViaOffscreenBackBuffer = EM_FALSE;
|
||||
attr.majorVersion = 2;
|
||||
|
||||
auto context = emscripten_webgl_create_context("#canvas", &attr);
|
||||
|
||||
std::cout << "Created WebGL context " << attr.majorVersion << "." << attr.minorVersion << std::endl;
|
||||
|
||||
auto success = emscripten_webgl_make_context_current((EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)context);
|
||||
if(success != EMSCRIPTEN_RESULT_SUCCESS) {
|
||||
std::cout << "Failed to make WebGL context current"<< std::endl;
|
||||
} else {
|
||||
std::cout << "Made WebGL context current"<< std::endl;
|
||||
// glClearColor(0.0, 0.0, 1.0, 1.0);
|
||||
// glClear(GL_COLOR_BUFFER_BIT);
|
||||
// emscripten_webgl_commit_frame();
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
int _lastResourceId = 0;
|
||||
|
||||
ResourceBuffer thermion_filament_web_load_resource(const char* path)
|
||||
{
|
||||
// ideally we should bounce the call to Flutter then wait for callback
|
||||
// this isn't working for large assets though - seems like it's deadlocked
|
||||
// will leave this here commented out so we can revisit later if needed
|
||||
// auto pendingCall = new PendingCall();
|
||||
// loadFlutterAsset(path, (void*)pendingCall);
|
||||
// pendingCall->Wait();
|
||||
// auto rb = ResourceBuffer { pendingCall->data, (int32_t) pendingCall->length, _lastResourceId } ;
|
||||
_lastResourceId++;
|
||||
// delete pendingCall;
|
||||
// std::cout << "Deleted pending call" << std::endl;
|
||||
|
||||
// emscripten_fetch_attr_t attr;
|
||||
// emscripten_fetch_attr_init(&attr);
|
||||
// attr.onsuccess = [](emscripten_fetch_t* fetch) {
|
||||
|
||||
// };
|
||||
// attr.onerror = [](emscripten_fetch_t* fetch) {
|
||||
// std::cout << "Error" << std::endl;
|
||||
// };
|
||||
// attr.onprogress = [](emscripten_fetch_t* fetch) {
|
||||
|
||||
// };
|
||||
// attr.onreadystatechange = [](emscripten_fetch_t* fetch) {
|
||||
|
||||
// };
|
||||
// attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY;
|
||||
|
||||
// const char* headers[] = {"Accept-Encoding", "gzip, deflate", NULL};
|
||||
// attr.requestHeaders = headers;
|
||||
|
||||
// auto pathString = std::string(path);
|
||||
// if(pathString.rfind("/",0) != 0) {
|
||||
// pathString = std::string("/") + pathString;
|
||||
// }
|
||||
|
||||
// std::cout << "Fetching from path " << pathString.c_str() << std::endl;
|
||||
|
||||
// auto request = emscripten_fetch(&attr, pathString.c_str());
|
||||
// if(!request) {
|
||||
// std::cout << "Request failed?" << std::endl;
|
||||
// return ResourceBuffer { nullptr, 0, -1 } ;
|
||||
// }
|
||||
// auto data = malloc(request->numBytes);
|
||||
// memcpy(data, request->data, request->numBytes);
|
||||
// emscripten_fetch_close(request);
|
||||
// return ResourceBuffer { data, (int32_t) request->numBytes, _lastResourceId } ;
|
||||
auto pathString = _assetPathPrefix + std::string(path);
|
||||
void* data = nullptr;
|
||||
int32_t numBytes = 0;
|
||||
|
||||
|
||||
// Check if the file exists in IndexedDB first
|
||||
bool fileExists = EM_ASM_INT({
|
||||
var filename = UTF8ToString($0);
|
||||
try {
|
||||
var stat = FS.stat('/indexed/' + filename);
|
||||
return stat.size > 0;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}, pathString.c_str());
|
||||
|
||||
if (fileExists) {
|
||||
// File exists in IndexedDB, read it
|
||||
EM_ASM({
|
||||
var filename = UTF8ToString($0);
|
||||
var content = FS.readFile('/indexed/' + filename);
|
||||
var numBytes = content.length;
|
||||
var ptr = _malloc(numBytes);
|
||||
HEAPU8.set(content, ptr);
|
||||
setValue($1, ptr, 'i32');
|
||||
setValue($2, numBytes, 'i32');
|
||||
}, pathString.c_str(), &data, &numBytes);
|
||||
} else {
|
||||
void** pBuffer = (void**)malloc(sizeof(void*));
|
||||
int* pNum = (int*) malloc(sizeof(int*));
|
||||
int* pError = (int*)malloc(sizeof(int*));
|
||||
emscripten_wget_data(pathString.c_str(), pBuffer, pNum, pError);
|
||||
data = *pBuffer;
|
||||
numBytes = *pNum;
|
||||
|
||||
// Save the file to IndexedDB filesystem
|
||||
EM_ASM({
|
||||
var filename = UTF8ToString($0);
|
||||
var data = new Uint8Array(HEAPU8.subarray($1, $1 + $2));
|
||||
|
||||
// Ensure the '/indexed' directory exists
|
||||
if (!FS.analyzePath('/indexed').exists) {
|
||||
FS.mkdir('/indexed');
|
||||
}
|
||||
|
||||
// Create all parent directories
|
||||
var parts = filename.split('/');
|
||||
var currentPath = '/indexed';
|
||||
for (var i = 0; i < parts.length - 1; i++) {
|
||||
currentPath += '/' + parts[i];
|
||||
if (!FS.analyzePath(currentPath).exists) {
|
||||
FS.mkdir(currentPath);
|
||||
}
|
||||
}
|
||||
// Write the file
|
||||
FS.writeFile('/indexed/' + filename, data);
|
||||
|
||||
FS.syncfs(false, function (err) {
|
||||
if (err) {
|
||||
console.error('Failed to save file to IndexedDB:', err);
|
||||
} else {
|
||||
console.log('File saved to IndexedDB successfully');
|
||||
}
|
||||
});
|
||||
}, pathString.c_str(), data, numBytes);
|
||||
|
||||
free(pBuffer);
|
||||
free(pNum);
|
||||
free(pError);
|
||||
}
|
||||
return ResourceBuffer { data, numBytes, _lastResourceId } ;
|
||||
}
|
||||
|
||||
void thermion_filament_web_free_resource(ResourceBuffer rb) {
|
||||
free((void*)rb.data);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void thermion_filament_web_free(void* ptr) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void* thermion_dart_web_get_resource_loader_wrapper() {
|
||||
ResourceLoaderWrapper *rlw = (ResourceLoaderWrapper *)malloc(sizeof(ResourceLoaderWrapper));
|
||||
rlw->loadResource = thermion_filament_web_load_resource;
|
||||
rlw->loadFromOwner = nullptr;
|
||||
rlw->freeResource = thermion_filament_web_free_resource;
|
||||
rlw->freeFromOwner = nullptr;
|
||||
rlw->loadToOut = nullptr;
|
||||
rlw->owner = nullptr;
|
||||
return rlw;
|
||||
}
|
||||
}
|
||||
123
thermion_dart/native/web/src/cpp/ThermionWebApi.cpp
Normal file
123
thermion_dart/native/web/src/cpp/ThermionWebApi.cpp
Normal file
@@ -0,0 +1,123 @@
|
||||
#include "ThermionWebApi.h"
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#include <emscripten/threading.h>
|
||||
#include <emscripten/val.h>
|
||||
#include <emscripten/fetch.h>
|
||||
#include <emscripten/console.h>
|
||||
#include <emscripten/bind.h>
|
||||
|
||||
using emscripten::val;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
EMSCRIPTEN_KEEPALIVE void Thermion_resizeCanvas(int width, int height) {
|
||||
emscripten_set_canvas_element_size("#thermion_canvas", width, height);
|
||||
}
|
||||
|
||||
EMSCRIPTEN_WEBGL_CONTEXT_HANDLE EMSCRIPTEN_KEEPALIVE Thermion_createGLContext() {
|
||||
|
||||
std::cout << "Creating WebGL context." << std::endl;
|
||||
|
||||
EmscriptenWebGLContextAttributes attr;
|
||||
|
||||
emscripten_webgl_init_context_attributes(&attr);
|
||||
attr.alpha = EM_TRUE;
|
||||
attr.depth = EM_TRUE;
|
||||
attr.stencil = EM_TRUE;
|
||||
attr.antialias = EM_FALSE;
|
||||
attr.explicitSwapControl = EM_FALSE;
|
||||
attr.preserveDrawingBuffer = EM_FALSE;
|
||||
attr.proxyContextToMainThread = EMSCRIPTEN_WEBGL_CONTEXT_PROXY_DISALLOW;
|
||||
attr.enableExtensionsByDefault = EM_TRUE;
|
||||
attr.renderViaOffscreenBackBuffer = EM_FALSE;
|
||||
attr.majorVersion = 2;
|
||||
|
||||
auto context = emscripten_webgl_create_context("#thermion_canvas", &attr);
|
||||
|
||||
std::cout << "Created WebGL context " << attr.majorVersion << "." << attr.minorVersion << std::endl;
|
||||
|
||||
auto success = emscripten_webgl_make_context_current((EMSCRIPTEN_WEBGL_CONTEXT_HANDLE)context);
|
||||
if(success != EMSCRIPTEN_RESULT_SUCCESS) {
|
||||
std::cout << "Failed to make WebGL context current"<< std::endl;
|
||||
} else {
|
||||
std::cout << "Made WebGL context current"<< std::endl;
|
||||
try {
|
||||
glClearColor(0.0, 0.0, 1.0, 1.0);
|
||||
} catch(...) {
|
||||
std::cout << "Caught err"<< std::endl;
|
||||
}
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
}
|
||||
std::cout << "Returning context" << std::endl;
|
||||
return context;
|
||||
}
|
||||
|
||||
emscripten::val emscripten_make_uint8_buffer(int ptr, int length) {
|
||||
uint8_t *buffer = (uint8_t*)ptr;
|
||||
auto v = emscripten::val(emscripten::typed_memory_view(length, buffer));
|
||||
emscripten_console_logf("offset %d", v["byteOffset"].as<int>());
|
||||
return v;
|
||||
}
|
||||
|
||||
emscripten::val emscripten_make_int16_buffer(int ptr, int length) {
|
||||
int16_t *buffer = (int16_t*)ptr;
|
||||
auto v = emscripten::val(emscripten::typed_memory_view(length, buffer));
|
||||
emscripten_console_logf("offset %d", v["byteOffset"].as<int>());
|
||||
return v;
|
||||
}
|
||||
|
||||
emscripten::val emscripten_make_uint16_buffer(int ptr, int length) {
|
||||
uint16_t *buffer = (uint16_t*)ptr;
|
||||
auto v = emscripten::val(emscripten::typed_memory_view(length, buffer));
|
||||
emscripten_console_logf("offset %d", v["byteOffset"].as<int>());
|
||||
return v;
|
||||
}
|
||||
|
||||
emscripten::val emscripten_make_int32_buffer(int ptr, int length) {
|
||||
int32_t *buffer = (int32_t*)ptr;
|
||||
auto v = emscripten::val(emscripten::typed_memory_view(length, buffer));
|
||||
emscripten_console_logf("offset %d", v["byteOffset"].as<int>());
|
||||
return v;
|
||||
}
|
||||
|
||||
emscripten::val emscripten_make_f32_buffer(int ptr, int length) {
|
||||
float *buffer = (float*)ptr;
|
||||
auto v = emscripten::val(emscripten::typed_memory_view(length, buffer));
|
||||
emscripten_console_logf("offset %d", v["byteOffset"].as<int>());
|
||||
return v;
|
||||
}
|
||||
|
||||
emscripten::val emscripten_make_f64_buffer(int ptr, int length) {
|
||||
double *buffer = (double*)ptr;
|
||||
auto v = emscripten::val(emscripten::typed_memory_view(length, buffer));
|
||||
emscripten_console_logf("offset %d", v["byteOffset"].as<int>());
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
intptr_t emscripten_get_byte_offset(emscripten::val v) {
|
||||
return v["byteOffset"].as<int>();
|
||||
}
|
||||
|
||||
EMSCRIPTEN_BINDINGS(module) {
|
||||
emscripten::function("_emscripten_make_uint8_buffer", &emscripten_make_uint8_buffer, emscripten::allow_raw_pointers());
|
||||
emscripten::function("_emscripten_make_uint16_buffer", &emscripten_make_uint16_buffer, emscripten::allow_raw_pointers());
|
||||
emscripten::function("_emscripten_make_int16_buffer", &emscripten_make_int16_buffer, emscripten::allow_raw_pointers());
|
||||
emscripten::function("_emscripten_make_int32_buffer", &emscripten_make_int32_buffer, emscripten::allow_raw_pointers());
|
||||
emscripten::function("_emscripten_make_f32_buffer", &emscripten_make_f32_buffer, emscripten::allow_raw_pointers());
|
||||
emscripten::function("_emscripten_make_f64_buffer", &emscripten_make_f64_buffer, emscripten::allow_raw_pointers());
|
||||
emscripten::function("_emscripten_get_byte_offset", &emscripten_get_byte_offset, emscripten::allow_raw_pointers());
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user