diff --git a/.gitignore b/.gitignore
index 3e93eb9..e8bfdaa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -45,3 +45,8 @@ bindings/java/crnd/messages/
bindings/go/crnd.go
bindings/rust/src/protos/*.rs
bindings/rust/src/bindings.rs
+*.js
+*.wasm
+*.html
+conaninfo.txt
+conanmanifest.txt
diff --git a/bindings/CMakeLists.txt b/bindings/CMakeLists.txt
index bbd6311..52f87e5 100644
--- a/bindings/CMakeLists.txt
+++ b/bindings/CMakeLists.txt
@@ -1,6 +1,17 @@
cmake_minimum_required(VERSION 3.8.0)
-add_subdirectory(cpp)
-add_subdirectory(java)
-add_subdirectory(go)
-add_subdirectory(rust)
+if(${BINDINGS_CPP})
+ add_subdirectory(cpp)
+endif()
+
+if(${BINDINGS_JAVA})
+ add_subdirectory(java)
+endif()
+
+if (${BINDINGS_GO})
+ add_subdirectory(go)
+endif()
+
+if (${BINDINGS_RUST})
+ add_subdirectory(rust)
+endif()
diff --git a/conanfile.py b/conanfile.py
index 9de4188..3957783 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -9,7 +9,7 @@ class CppInside(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "cmake"
- options = {#"cpp": [True, False], # It is always generated
+ options = {"cpp": [True, False], # It is always generated
"csharp": [True, False],
"java": [True, False],
"js": [True, False],
@@ -19,7 +19,7 @@ class CppInside(ConanFile):
"ruby": [True, False],
"go": [True, False],
}
- default_options = {#"cpp": True,
+ default_options = {"cpp": True,
"csharp": True,
"java": True,
"js": True,
@@ -37,7 +37,7 @@ def build_requirements(self):
def requirements(self):
self.requires("protobuf/3.6.1@bincrafters/stable")
- self.requires("boost/1.70.0@conan/stable")
+ #self.requires("boost/1.70.0@conan/stable")
self.requires("spdlog/1.3.1@bincrafters/stable")
def source(self):
@@ -61,13 +61,22 @@ def source(self):
else:
binding_folder = os.path.join(self.source_folder, "bindings", it, "messages")
os.makedirs(binding_folder, exist_ok=True)
- command += " --{}_out={}".format(it, binding_folder)
+
+ if it == 'js':
+ command += " --js_out=import_style=commonjs,binary:{}".format(binding_folder)
+ else:
+ command += " --{}_out={}".format(it, binding_folder)
command += " {}".format(" ".join(messages))
with tools.environment_append(env):
self.run(command)
def _cmake(self):
cmake = CMake(self)
+ for it in ["cpp", "csharp", "java", "js", "objc", "php", "python", "ruby", "go"]:
+ cmake.definitions["bindings_{}".format(it).upper()] = bool(getattr(self.options, it))
+ cmake.definitions["example_{}".format(it).upper()] = bool(getattr(self.options, it))
+
+ cmake.definitions["EMSCRIPTEN"] = bool(self.settings.os == "Emscripten")
cmake.configure()
return cmake
diff --git a/emscripten/bin/index.html b/emscripten/bin/index.html
new file mode 100644
index 0000000..3412a8c
--- /dev/null
+++ b/emscripten/bin/index.html
@@ -0,0 +1,104 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/emscripten/build.sh b/emscripten/build.sh
new file mode 100755
index 0000000..11a5ad7
--- /dev/null
+++ b/emscripten/build.sh
@@ -0,0 +1,11 @@
+rm -fr _build
+mkdir _build
+
+pushd _build
+conan install ../../conanfile.py -g virtualenv --profile ../profile --build=missing -o csharp=False -o java=False -o objc=False -o php=False -o python=False -o ruby=False -o go=False -o cpp=False
+conan source ../../conanfile.py --install-folder=. --source-folder=../../
+conan build ../../conanfile.py
+conan package ../../conanfile.py --package-folder=../
+popd
+
+browserify main.js --standalone crnd -o bin/bundle.js
diff --git a/emscripten/main.js b/emscripten/main.js
new file mode 100644
index 0000000..b1f2d7e
--- /dev/null
+++ b/emscripten/main.js
@@ -0,0 +1,49 @@
+
+var help_pb = require('/Users/jgsogo/dev/projects/cpp-inside/bindings/js/messages/help_pb.js');
+var sample_pb = require('/Users/jgsogo/dev/projects/cpp-inside/bindings/js/messages/sample_pb.js');
+var model_pb = require('/Users/jgsogo/dev/projects/cpp-inside/bindings/js/messages/model_pb.js');
+var sample_request_pb = require('/Users/jgsogo/dev/projects/cpp-inside/bindings/js/messages/sample_request_pb.js');
+
+parse_help = function (data) {
+ json = JSON.parse(UTF8ToString(data));
+ var message = new help_pb.Help();
+ message.setName(json["name"]);
+ message.setDescription(json["description"]);
+ message.setVersion(json["version"]);
+ return message;
+}
+
+parse_sample = function (data) {
+ json = JSON.parse(UTF8ToString(data));
+
+ var model = new model_pb.Model();
+ model.setId(json["model"]["id"]);
+ model.getParamsMap()["mean"] = json["model"]["mean"];
+ model.getParamsMap()["stddev"] = json["model"]["stddev"];
+
+ var message = new sample_pb.Sample();
+ message.setModel(model);
+ message.setSeed(json["seed"]);
+ message.setSamplesList(json["samples"]);
+
+ return message;
+}
+
+serialize_sample_request = function(sample_request) {
+ var model = sample_request.getModel();
+ var params = model.getParamsMap();
+ return JSON.stringify({
+ "model": {
+ "id": "LOGNORMAL",
+ "params": {
+ "mean": params["mean"],
+ "stddev": params["stddev"]
+ }
+ },
+ "seed": sample_request.getSeed(),
+ "nSamples": sample_request.getNSamples()
+ });
+}
+
+
+module.exports = {parse_help: parse_help, parse_sample: parse_sample, serialize_sample_request: serialize_sample_request, sample_request_pb: sample_request_pb, model_pb: model_pb};
diff --git a/emscripten/profile b/emscripten/profile
new file mode 100644
index 0000000..6f9e60e
--- /dev/null
+++ b/emscripten/profile
@@ -0,0 +1,12 @@
+include(default)
+[settings]
+os=Emscripten
+arch=wasm
+compiler=clang
+compiler.version=6.0
+compiler.libcxx=libc++
+[options]
+[build_requires]
+emsdk_installer/1.38.29@bincrafters/stable
+[env]
+
diff --git a/emscripten/run.sh b/emscripten/run.sh
new file mode 100755
index 0000000..bc4170d
--- /dev/null
+++ b/emscripten/run.sh
@@ -0,0 +1,3 @@
+
+source _build/activate.sh
+emrun ./bin/index.html
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index a68811a..0c37d63 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -1,6 +1,20 @@
-add_subdirectory(cpp)
-add_subdirectory(python)
-add_subdirectory(java)
-add_subdirectory(go)
-add_subdirectory(rust)
+if (${EXAMPLE_CPP})
+ add_subdirectory(cpp)
+endif()
+
+if (${EXAMPLE_PYTHON})
+ add_subdirectory(python)
+endif()
+
+if (${EXAMPLE_JAVA})
+ add_subdirectory(java)
+endif()
+
+if (${EXAMPLE_GO})
+ add_subdirectory(go)
+endif()
+
+if (${EXAMPLE_RUST})
+ add_subdirectory(rust)
+endif()
diff --git a/library/crnd/CMakeLists.txt b/library/crnd/CMakeLists.txt
index efb5a12..93c8192 100644
--- a/library/crnd/CMakeLists.txt
+++ b/library/crnd/CMakeLists.txt
@@ -23,4 +23,30 @@ target_compile_definitions(crnd PRIVATE SPDLOG_ACTIVE_LEVEL=0)
#define SPDLOG_LEVEL_WARN 3
#define SPDLOG_LEVEL_ERROR 4
#define SPDLOG_LEVEL_CRITICAL 5
-#define SPDLOG_LEVEL_OFF 6
\ No newline at end of file
+#define SPDLOG_LEVEL_OFF 6
+
+if (${EMSCRIPTEN})
+ message("CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}")
+ message("CMAKE_CPP_COMPILER: ${CMAKE_CPP_COMPILER}")
+
+ set(EXPORTED_FUNCTIONS
+ _help
+ _sample
+ )
+
+ # process exported functions
+ set(EXPORTED_FUNCTIONS_STR "")
+ list(JOIN EXPORTED_FUNCTIONS "," EXPORTED_FUNCTIONS_STR)
+
+ set(CMAKE_CXX_FLAGS "-s EXPORTED_FUNCTIONS=\"[${EXPORTED_FUNCTIONS_STR}]\" -s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\", \"addFunction\", \"removeFunction\", \"UTF8ToString\", \"stringToUTF8\"]' -s RESERVED_FUNCTION_POINTERS=10")
+
+ set_target_properties(crnd PROPERTIES
+ SUFFIX ".js"
+ LINK_FLAGS "--emrun")
+
+ install(FILES
+ ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libcrnd.js
+ ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/libcrnd.wasm
+ DESTINATION bin)
+endif()
+
diff --git a/library/crnd/include/api_c.h b/library/crnd/include/api_c.h
index 78b92c6..495cb6b 100644
--- a/library/crnd/include/api_c.h
+++ b/library/crnd/include/api_c.h
@@ -8,7 +8,7 @@ extern "C" {
typedef void (*callback_t)(void* state, const void* data, const void* status);
CRND_EXPORT void help(void* state, callback_t help_callback);
- CRND_EXPORT void sample(void* state, const void* sample_request_in, callback_t sample_callback);
+ CRND_EXPORT void sample(void* state, char* sample_request_in, callback_t sample_callback);
#ifdef __cplusplus
}
#endif
diff --git a/library/crnd/src/api_c.cpp b/library/crnd/src/api_c.cpp
index f64ac03..9090c85 100644
--- a/library/crnd/src/api_c.cpp
+++ b/library/crnd/src/api_c.cpp
@@ -4,6 +4,7 @@
#include "../include/api_cpp.h"
#include "serialization.h"
+#include
extern "C" {
@@ -15,20 +16,36 @@ extern "C" {
auto status = help(help_message);
SPDLOG_TRACE("C::help::before callback");
- help_callback(state, Serialized(help_message), Serialized(*status));
+ //help_callback(state, Serialized(help_message), Serialized(*status));
+ std::string data;
+ google::protobuf::util::MessageToJsonString(help_message, &data);
+
+ std::string status_str;
+ google::protobuf::util::MessageToJsonString(*status, &status_str);
+
+ help_callback(state, (void*)data.c_str(), (void*)status_str.c_str());
SPDLOG_TRACE("C::help::after callback");
SPDLOG_DEBUG("< C::help");
}
- void sample(void* state, const void* sample_request_in, callback_t sample_callback) {
+ void sample(void* state, char* sample_request_in, callback_t sample_callback) {
SPDLOG_DEBUG("> C::sample");
- crnd::SampleRequest request_message = Serialized::parse(sample_request_in);
+ std::string sp(sample_request_in);
+ crnd::SampleRequest request_message;
+ google::protobuf::util::JsonStringToMessage(sp, &request_message);
+
crnd::Sample sample_message;
auto status = sample(request_message, sample_message);
SPDLOG_TRACE("C::sample::before callback");
- sample_callback(state, Serialized(sample_message), Serialized(*status));
+ std::string data;
+ google::protobuf::util::MessageToJsonString(sample_message, &data);
+
+ std::string status_str;
+ google::protobuf::util::MessageToJsonString(*status, &status_str);
+
+ sample_callback(state, (void*)data.c_str(), (void*)status_str.c_str());
SPDLOG_TRACE("C::sample::after callback");
SPDLOG_DEBUG("< C::sample");