-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: implemented base class for HostObjects
- Loading branch information
Maciej Makowski
committed
Dec 12, 2024
1 parent
0a7feb0
commit 4a8d3dd
Showing
2 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
87 changes: 87 additions & 0 deletions
87
packages/react-native-audio-api/common/cpp/utils/JsiHostObject.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
#include "JsiHostObject.h" | ||
|
||
namespace audioapi { | ||
JsiHostObject::JsiHostObject() { | ||
propertyGetters_ = std::make_unique<std::unordered_map< | ||
std::string, | ||
jsi::Value (JsiHostObject::*)(jsi::Runtime &)>>(); | ||
propertyFunctions_ = std::make_unique<std::unordered_map< | ||
std::string, | ||
jsi::Value (JsiHostObject::*)( | ||
jsi::Runtime &, const jsi::Value &, const jsi::Value *, size_t)>>(); | ||
propertySetters_ = std::make_unique<std::unordered_map< | ||
std::string, | ||
void (JsiHostObject::*)(jsi::Runtime &, const jsi::Value &)>>(); | ||
|
||
propertyGetters_->insert(JSI_EXPORT_PROPERTY_GETTER(JsiHostObject, then)); | ||
} | ||
|
||
std::vector<jsi::PropNameID> JsiHostObject::getPropertyNames(jsi::Runtime &rt) { | ||
std::vector<jsi::PropNameID> propertyNames; | ||
propertyNames.reserve( | ||
propertyGetters_->size() + propertyFunctions_->size() + | ||
propertySetters_->size()); | ||
|
||
for (const auto &it : *propertyGetters_) { | ||
propertyNames.push_back(jsi::PropNameID::forUtf8(rt, it.first)); | ||
} | ||
|
||
for (const auto &it : *propertyFunctions_) { | ||
propertyNames.push_back(jsi::PropNameID::forAscii(rt, it.first)); | ||
} | ||
|
||
for (const auto &it : *propertySetters_) { | ||
propertyNames.push_back(jsi::PropNameID::forAscii(rt, it.first)); | ||
} | ||
|
||
return propertyNames; | ||
} | ||
|
||
jsi::Value JsiHostObject::get( | ||
jsi::Runtime &runtime, | ||
const jsi::PropNameID &name) { | ||
auto nameAsString = name.utf8(runtime); | ||
|
||
auto propertyGetter = propertyGetters_->find(nameAsString); | ||
if (propertyGetter != propertyGetters_->end()) { | ||
auto dispatcher = [this, &propertyGetter](jsi::Runtime &runtime) { | ||
return (this->*(propertyGetter->second))(runtime); | ||
}; | ||
|
||
return dispatcher(runtime); | ||
} | ||
|
||
auto propertyFunction = propertyFunctions_->find(nameAsString); | ||
if (propertyFunction != propertyFunctions_->end()) { | ||
auto dispatcher = [this, &propertyFunction]( | ||
jsi::Runtime &runtime, | ||
const jsi::Value &thisVal, | ||
const jsi::Value *args, | ||
size_t count) -> jsi::Value { | ||
return (this->*(propertyFunction->second))(runtime, thisVal, args, count); | ||
}; | ||
|
||
return jsi::Function::createFromHostFunction(runtime, name, 0, dispatcher); | ||
} | ||
|
||
return jsi::Value::undefined(); | ||
} | ||
|
||
void JsiHostObject::set( | ||
jsi::Runtime &runtime, | ||
const jsi::PropNameID &name, | ||
const jsi::Value &value) { | ||
auto nameAsString = name.utf8(runtime); | ||
|
||
auto propertySetter = propertySetters_->find(nameAsString); | ||
|
||
if (propertySetter != propertySetters_->end()) { | ||
auto dispatcher = [this, &propertySetter]( | ||
jsi::Runtime &runtime, const jsi::Value &value) { | ||
return (this->*(propertySetter->second))(runtime, value); | ||
}; | ||
|
||
return dispatcher(runtime, value); | ||
} | ||
} | ||
} // namespace audioapi |
98 changes: 98 additions & 0 deletions
98
packages/react-native-audio-api/common/cpp/utils/JsiHostObject.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
#pragma once | ||
|
||
#include <jsi/jsi.h> | ||
#include <memory> | ||
#include <set> | ||
#include <unordered_map> | ||
#include <utility> | ||
#include <vector> | ||
|
||
#define JSI_HOST_FUNCTION(NAME) \ | ||
jsi::Value NAME( \ | ||
jsi::Runtime &runtime, \ | ||
const jsi::Value &thisVal, \ | ||
const jsi::Value *args, \ | ||
size_t count) | ||
|
||
#define JSI_EXPORT_FUNCTION(CLASS, FUNCTION) \ | ||
std::make_pair( \ | ||
std::string(#FUNCTION), \ | ||
static_cast<jsi::Value (JsiHostObject::*)( \ | ||
jsi::Runtime &, const jsi::Value &, const jsi::Value *, size_t)>( \ | ||
&CLASS::FUNCTION)) | ||
|
||
#define JSI_PROPERTY_GETTER(name) jsi::Value name(jsi::Runtime &runtime) | ||
|
||
#define JSI_EXPORT_PROPERTY_GETTER(CLASS, FUNCTION) \ | ||
std::make_pair( \ | ||
std::string(#FUNCTION), \ | ||
static_cast<jsi::Value (JsiHostObject::*)(jsi::Runtime &)>( \ | ||
&CLASS::FUNCTION)) | ||
|
||
#define JSI_PROPERTY_SETTER(name) \ | ||
void name(jsi::Runtime &runtime, const jsi::Value &value) | ||
|
||
#define JSI_EXPORT_PROPERTY_SETTER(CLASS, FUNCTION) \ | ||
std::make_pair( \ | ||
std::string(#FUNCTION), \ | ||
static_cast<void (JsiHostObject::*)( \ | ||
jsi::Runtime &, const jsi::Value &)>(&CLASS::FUNCTION)) | ||
|
||
namespace audioapi { | ||
|
||
using namespace facebook; | ||
|
||
class JsiHostObject : public jsi::HostObject { | ||
public: | ||
JsiHostObject(); | ||
|
||
std::vector<jsi::PropNameID> getPropertyNames(jsi::Runtime &rt) override; | ||
|
||
jsi::Value get(jsi::Runtime &runtime, const jsi::PropNameID &name) override; | ||
|
||
void set( | ||
jsi::Runtime &runtime, | ||
const jsi::PropNameID &name, | ||
const jsi::Value &value) override; | ||
|
||
template <typename... Args> | ||
void addGetters(Args... args) { | ||
(propertyGetters_->insert(args), ...); | ||
} | ||
|
||
template <typename... Args> | ||
void addSetters(Args... args) { | ||
(propertySetters_->insert(args), ...); | ||
} | ||
|
||
template <typename... Args> | ||
void addFunctions(Args... args) { | ||
(propertyFunctions_->insert(args), ...); | ||
} | ||
|
||
JSI_PROPERTY_GETTER(then) { | ||
return jsi::Value::undefined(); | ||
} | ||
|
||
protected: | ||
std::unique_ptr<std::unordered_map< | ||
std::string, | ||
jsi::Value (JsiHostObject::*)(jsi::Runtime &)>> | ||
propertyGetters_; | ||
|
||
std::unique_ptr<std::unordered_map< | ||
std::string, | ||
jsi::Value (JsiHostObject::*)( | ||
jsi::Runtime &, | ||
const jsi::Value &, | ||
const jsi::Value *, | ||
size_t)>> | ||
propertyFunctions_; | ||
|
||
std::unique_ptr<std::unordered_map< | ||
std::string, | ||
void (JsiHostObject::*)(jsi::Runtime &, const jsi::Value &)>> | ||
propertySetters_; | ||
}; | ||
|
||
} // namespace audioapi |