Skip to content

Commit

Permalink
Holy shit I did it?
Browse files Browse the repository at this point in the history
  • Loading branch information
mrousavy committed Feb 21, 2024
1 parent f92dfec commit 8042658
Show file tree
Hide file tree
Showing 7 changed files with 201 additions and 1 deletion.
2 changes: 2 additions & 0 deletions package/android/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ add_library(
../cpp/Surface.cpp
../cpp/SurfaceProvider.cpp
../cpp/Listener.cpp
../cpp/jsi/JsiTypeTraits.cpp
../cpp/jsi/HybridObject.cpp
../cpp/jsi/Promise.cpp
../cpp/core/EngineWrapper.cpp
# Java JNI
Expand Down
18 changes: 18 additions & 0 deletions package/cpp/core/EngineWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,24 @@ EngineWrapper::~EngineWrapper() {
_engine->destroy(&_engine);
}

int EngineWrapper::testHybrid(bool parameter) {
return 5;
}

void EngineWrapper::loadMethods() {
auto what = &EngineWrapper::testHybrid;

registerHybridMethod("test", &EngineWrapper::testHybrid, this);
registerHybridMethod("testHybrid", []() {

});
registerHybridMethod("testHybrid", std::bind(&EngineWrapper::testHybrid, this));

registerHybridMethod("setSurfaceProvider", [this](std::shared_ptr<SurfaceProvider> surfaceProvider) {
this->setSurfaceProvider(surfaceProvider);
});
}

void EngineWrapper::setSurfaceProvider(std::shared_ptr<SurfaceProvider> surfaceProvider) {
_surfaceProvider = surfaceProvider;
std::shared_ptr<Surface> surface = surfaceProvider->getSurfaceOrNull();
Expand Down
7 changes: 6 additions & 1 deletion package/cpp/core/EngineWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,21 @@
#include "Surface.h"
#include "SurfaceProvider.h"

#include "jsi/HybridObject.h"

namespace margelo {

using namespace filament;

class EngineWrapper {
class EngineWrapper: public HybridObject {
public:
explicit EngineWrapper(filament::Engine::Backend backend);
~EngineWrapper();

void setSurfaceProvider(std::shared_ptr<SurfaceProvider> surfaceProvider);
int testHybrid(bool parameter);

void loadMethods() override;

private:
void setSurface(std::shared_ptr<Surface> surface);
Expand Down
47 changes: 47 additions & 0 deletions package/cpp/jsi/HybridObject.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// Created by Marc Rousavy on 21.02.24.
//

#include "HybridObject.h"

namespace margelo {

HybridObject::~HybridObject() {
_functionCache.clear();
}



jsi::Value HybridObject::get(facebook::jsi::Runtime& runtime, const facebook::jsi::PropNameID& propName) {
std::string name = propName.utf8(runtime);
auto& functionCache = _functionCache[&runtime];

if (functionCache.count(name) > 0) {
// cache hit
return jsi::Value(runtime, *functionCache[name]);
}

if (_methods.count(name) > 0) {
// cache miss - create jsi::Function and cache it.
jsi::HostFunctionType hostFunction = _methods.at(name);
jsi::Function function = jsi::Function::createFromHostFunction(runtime,
jsi::PropNameID::forUtf8(runtime, name),
// TODO(marc): Also add parameter count here
1,
hostFunction);
functionCache[name] = std::make_shared<jsi::Function>(std::move(function));
return jsi::Value(runtime, *functionCache[name]);
}

return jsi::HostObject::get(runtime, propName);
}

std::vector<jsi::PropNameID> HybridObject::getPropertyNames(facebook::jsi::Runtime& runtime) {
std::vector<jsi::PropNameID> result;
for (const auto& item: _methods) {
result.push_back(jsi::PropNameID::forUtf8(runtime, item.first));
}
return result;
}

} // margelo
71 changes: 71 additions & 0 deletions package/cpp/jsi/HybridObject.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//
// Created by Marc Rousavy on 21.02.24.
//

#pragma once

#include <functional>
#include <memory>
#include <unordered_map>
#include <jsi/jsi.h>

#include "JsiTypeTraits.h"

namespace margelo {

using namespace facebook;

class HybridObject: public jsi::HostObject {
struct HybridFunction {
jsi::HostFunctionType function;
size_t parameterCount;
};

private:
std::unordered_map<std::string, HybridFunction> _methods;
std::unordered_map<jsi::Runtime*, std::unordered_map<std::string, std::shared_ptr<jsi::Function>>> _functionCache;

public:
~HybridObject();

jsi::Value get(facebook::jsi::Runtime& runtime, const facebook::jsi::PropNameID& propName) override;
std::vector<jsi::PropNameID> getPropertyNames(facebook::jsi::Runtime& runtime) override;

virtual void loadMethods() = 0;


private:
template<typename ArgType>
ArgType convertArgument(jsi::Runtime& runtime, const jsi::Value& arg) {
// Implement conversion from jsi::Value to ArgType
// This is a placeholder; actual implementation depends on ArgType
return 5;
}

template<typename ClassType, typename ReturnType, typename... Args, size_t... Is>
ReturnType callMethod(ClassType* obj, ReturnType(ClassType::*method)(Args...), jsi::Runtime& runtime, const jsi::Value* args, std::index_sequence<Is...>) {
return (obj->*method)(convertArgument<Args>(runtime, args[Is])...);
}



protected:
template<typename Derived, typename ReturnType, typename... Args>
void registerHybridMethod(std::string name, ReturnType(Derived::*method)(Args...), Derived* derivedInstance) {
auto func = [this, derivedInstance, method](jsi::Runtime &runtime,
const jsi::Value &thisVal,
const jsi::Value *args,
size_t count) -> jsi::Value {
if constexpr (std::is_same_v<ReturnType, void>) {
callMethod(derivedInstance, method, runtime, args, std::index_sequence_for<Args...>{});
return jsi::Value::undefined();
} else {
ReturnType result = callMethod(derivedInstance, method, runtime, args, std::index_sequence_for<Args...>{});
return jsi::Value(result);
}
};
}
};

} // margelo

8 changes: 8 additions & 0 deletions package/cpp/jsi/JsiTypeTraits.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//
// Created by Marc Rousavy on 21.02.24.
//

#include "JsiTypeTraits.h"

namespace margelo {
} // margelo
49 changes: 49 additions & 0 deletions package/cpp/jsi/JsiTypeTraits.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// Created by Marc Rousavy on 21.02.24.
//

#pragma once

#include <jsi/jsi.h>

namespace margelo {

using namespace facebook;

// Type conversion templates to and from jsi::Values
template<typename T>
struct JsiTypeTraits {
};

template<>
struct JsiTypeTraits<int> {
static int fromJsi(jsi::Runtime& runtime, const jsi::Value& value) {
return value.asNumber();
}
static jsi::Value toJsi(jsi::Runtime& runtime, int value) {
return jsi::Value(value);
}
};

template<>
struct JsiTypeTraits<bool> {
static bool fromJsi(jsi::Runtime& runtime, const jsi::Value& value) {
return value.asNumber();
}
static jsi::Value toJsi(jsi::Runtime& runtime, bool value) {
return jsi::Value(value);
}
};

template<>
struct JsiTypeTraits<std::string> {
static std::string fromJsi(jsi::Runtime& runtime, const jsi::Value& value) {
return value.asString(runtime).utf8(runtime);
}
static jsi::Value toJsi(jsi::Runtime& runtime, std::string value) {
return jsi::String::createFromUtf8(runtime, value);
}
};

} // margelo

0 comments on commit 8042658

Please sign in to comment.