Skip to content

Commit

Permalink
unmount & console.log work
Browse files Browse the repository at this point in the history
  • Loading branch information
karol-bisztyga committed Jan 25, 2021
1 parent 1a7df90 commit 6f7572f
Show file tree
Hide file tree
Showing 11 changed files with 98 additions and 35 deletions.
6 changes: 3 additions & 3 deletions Common/cpp/NativeModules/NativeReanimatedModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ NativeReanimatedModule::NativeReanimatedModule(std::shared_ptr<CallInvoker> jsIn
maybeRequestRender();
};

RuntimeDecorator::addNativeObjects(*runtime,
RuntimeDecorator::decorateUI(*runtime,
platformDepMethodsHolder.updaterFunction,
requestAnimationFrame,
platformDepMethodsHolder.scrollToFunction,
Expand Down Expand Up @@ -213,10 +213,10 @@ jsi::Value NativeReanimatedModule::spawnThread(jsi::Runtime &rt, const jsi::Valu
std::unique_ptr<jsi::Runtime> customRuntime = runtimeObtainer();
std::shared_ptr<Th> th = this->threads.at(threadId);
th->rt = std::move(customRuntime);
RuntimeDecorator::addLog(*th->rt);
RuntimeDecorator::decorateCustomThread(*th->rt);
jsi::Value result = jsi::Value::undefined();

jsi::Function func = workletShareable->getValue(*th->rt).asObject(*th->rt).asFunction(*th->rt);
jsi::Function func = workletShareable->getValue(*th->rt, threadId).asObject(*th->rt).asFunction(*th->rt);
std::shared_ptr<jsi::Function> funcPtr = std::make_shared<jsi::Function>(std::move(func));
try {
result = funcPtr->callWithThis(*th->rt, *funcPtr);
Expand Down
5 changes: 3 additions & 2 deletions Common/cpp/SharedItems/FrozenObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ FrozenObject::FrozenObject(jsi::Runtime &rt, const jsi::Object &object, NativeRe
}
}

jsi::Object FrozenObject::shallowClone(jsi::Runtime &rt) {
jsi::Object FrozenObject::shallowClone(jsi::Runtime &rt, const int customThreadId) {
this->customThreadId = (this->customThreadId == -1 && this->customThreadId != customThreadId) ? customThreadId : this->customThreadId;
jsi::Object object(rt);
for (auto prop : map) {
object.setProperty(rt, jsi::String::createFromUtf8(rt, prop.first), prop.second->getValue(rt));
object.setProperty(rt, jsi::String::createFromUtf8(rt, prop.first), prop.second->getValue(rt, customThreadId));
}
return object;
}
Expand Down
20 changes: 12 additions & 8 deletions Common/cpp/SharedItems/ShareableValue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ std::shared_ptr<ShareableValue> ShareableValue::adapt(jsi::Runtime &rt, const js
return sv;
}

jsi::Value ShareableValue::getValue(jsi::Runtime &rt) {
jsi::Value ShareableValue::getValue(jsi::Runtime &rt, const int customThreadId) {
// TODO: maybe we can cache toJSValue results on a per-runtime basis, need to avoid ref loops
if (module->isUIRuntime(rt) || customThreadId != -1) {
if (module->isUIRuntime(rt)) {
if (remoteValue.expired()) {
auto ref = getWeakRef(rt);
remoteValue = ref;
Expand All @@ -157,7 +157,11 @@ jsi::Value ShareableValue::getValue(jsi::Runtime &rt) {
}
return jsi::Value(rt, *remoteValue.lock());
} else {
if (hostValue.get() == nullptr) {
std::string s = hostValue.get() == nullptr ? "true" : "false";
if (hostValue.get() == nullptr || customThreadId != -1) {
// recreate objects for custom threads, because for every one of them
// there is a separate RT - we have to avoid errors caused by
// accessing the value created with a different RT
hostValue = std::make_unique<jsi::Value>(rt, toJSValue(rt));
}
return jsi::Value(rt, *hostValue);
Expand All @@ -168,9 +172,9 @@ jsi::Object ShareableValue::createHost(jsi::Runtime &rt, std::shared_ptr<jsi::Ho
return jsi::Object::createFromHostObject(rt, host);
}

jsi::Value createFrozenWrapper(jsi::Runtime &rt, std::shared_ptr<FrozenObject> frozenObject) {
jsi::Value createFrozenWrapper(jsi::Runtime &rt, std::shared_ptr<FrozenObject> frozenObject, const int customThreadId) {
jsi::Object __reanimatedHiddenHost = jsi::Object::createFromHostObject(rt, frozenObject);
jsi::Object obj = frozenObject->shallowClone(rt);
jsi::Object obj = frozenObject->shallowClone(rt, customThreadId);
jsi::Object globalObject = rt.global().getPropertyAsObject(rt, "Object");
jsi::Function freeze = globalObject.getPropertyAsFunction(rt, "freeze");
addHiddenProperty(rt, std::move(__reanimatedHiddenHost), obj, HIDDEN_HOST_OBJECT_PROP);
Expand All @@ -191,7 +195,7 @@ jsi::Value ShareableValue::toJSValue(jsi::Runtime &rt) {
case ValueType::StringType:
return jsi::Value(rt, jsi::String::createFromAscii(rt, stringValue));
case ValueType::ObjectType:
return createFrozenWrapper(rt, frozenObject);
return createFrozenWrapper(rt, frozenObject, customThreadId);
case ValueType::ArrayType: {
jsi::Array array(rt, frozenArray.size());
for (size_t i = 0; i < frozenArray.size(); i++) {
Expand Down Expand Up @@ -274,7 +278,7 @@ jsi::Value ShareableValue::toJSValue(jsi::Runtime &rt) {
// when running on UI thread we prep a function
// for the custom threads we also just want to prepare

auto jsThis = std::make_shared<jsi::Object>(frozenObject->shallowClone(rt));
auto jsThis = std::make_shared<jsi::Object>(frozenObject->shallowClone(rt, customThreadId));
// cache will not work for custom threads because for every thread we have a different RT
std::shared_ptr<jsi::Function> funPtr(module->workletsCache->getFunction(rt, frozenObject, customThreadId));
auto name = funPtr->getProperty(rt, "name").asString(rt).utf8(rt);
Expand Down Expand Up @@ -334,7 +338,7 @@ jsi::Value ShareableValue::toJSValue(jsi::Runtime &rt) {
retain_this->module->scheduler->scheduleOnUI([retain_this, params] {
NativeReanimatedModule *module = retain_this->module;
jsi::Runtime &rt = *module->runtime.get();
auto jsThis = createFrozenWrapper(rt, retain_this->frozenObject).getObject(rt);
auto jsThis = createFrozenWrapper(rt, retain_this->frozenObject, retain_this->customThreadId).getObject(rt);
auto code = jsThis.getProperty(rt, "asString").asString(rt).utf8(rt);
std::shared_ptr<jsi::Function> funPtr(retain_this->module->workletsCache->getFunction(rt, retain_this->frozenObject));

Expand Down
63 changes: 57 additions & 6 deletions Common/cpp/Tools/RuntimeDecorator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,25 @@

namespace reanimated {

void RuntimeDecorator::addLog(jsi::Runtime &rt) {
void RuntimeDecorator::decorateCustomThread(jsi::Runtime &rt) {
rt.global().setProperty(rt, "_WORKLET", jsi::Value(true));

jsi::Object dummyGlobal(rt);
auto dummyFunction = [](
jsi::Runtime &rt,
const jsi::Value &thisValue,
const jsi::Value *args,
size_t count
) -> jsi::Value {
return jsi::Value::undefined();
};
jsi::Function __reanimatedWorkletInit = jsi::Function::createFromHostFunction(rt, jsi::PropNameID::forAscii(rt, "__reanimatedWorkletInit"), 1, dummyFunction);

dummyGlobal.setProperty(rt, "__reanimatedWorkletInit", __reanimatedWorkletInit);
rt.global().setProperty(rt, "global", dummyGlobal);

rt.global().setProperty(rt, "jsThis", jsi::Value::undefined());

auto callback = [](
jsi::Runtime &rt,
const jsi::Value &thisValue,
Expand All @@ -25,11 +43,23 @@ void RuntimeDecorator::addLog(jsi::Runtime &rt) {
return jsi::Value::undefined();
};
jsi::Value log = jsi::Function::createFromHostFunction(rt, jsi::PropNameID::forAscii(rt, "_log"), 1, callback);
rt.global().setProperty(rt, "_log", log);
rt.global().setProperty(rt, "jsThis", jsi::Value::undefined());
rt.global().setProperty(rt, "_log", log);

auto clb5 = [](
jsi::Runtime &rt,
const jsi::Value &thisValue,
const jsi::Value *args,
size_t count
) -> jsi::Value {
rt.global().setProperty(rt, "console", args[0]);
return jsi::Value::undefined();
};
jsi::Value setGlobalConsole = jsi::Function::createFromHostFunction(rt, jsi::PropNameID::forAscii(rt, "_setGlobalConsole"), 1, clb5);
rt.global().setProperty(rt, "_setGlobalConsole", setGlobalConsole);
}

void RuntimeDecorator::addNativeObjects(jsi::Runtime &rt,

void RuntimeDecorator::decorateUI(jsi::Runtime &rt,
UpdaterFunction updater,
RequestFrameFunction requestFrame,
ScrollToFunction scrollTo,
Expand All @@ -38,7 +68,7 @@ void RuntimeDecorator::addNativeObjects(jsi::Runtime &rt,
rt.global().setProperty(rt, "_WORKLET", jsi::Value(true));

jsi::Object dummyGlobal(rt);
auto dummyFunction = [requestFrame](
auto dummyFunction = [](
jsi::Runtime &rt,
const jsi::Value &thisValue,
const jsi::Value *args,
Expand All @@ -53,6 +83,28 @@ void RuntimeDecorator::addNativeObjects(jsi::Runtime &rt,

rt.global().setProperty(rt, "jsThis", jsi::Value::undefined());

auto callback = [](
jsi::Runtime &rt,
const jsi::Value &thisValue,
const jsi::Value *args,
size_t count
) -> jsi::Value {
const jsi::Value *value = &args[0];
if (value->isString()) {
Logger::log(value->getString(rt).utf8(rt).c_str());
} else if (value->isNumber()) {
Logger::log(value->getNumber());
} else if (value->isUndefined()) {
Logger::log("undefined");
} else {
Logger::log("unsupported value type");
}
return jsi::Value::undefined();
};
jsi::Value log = jsi::Function::createFromHostFunction(rt, jsi::PropNameID::forAscii(rt, "_log"), 1, callback);
rt.global().setProperty(rt, "_log", log);


auto clb = [updater](
jsi::Runtime &rt,
const jsi::Value &thisValue,
Expand All @@ -68,7 +120,6 @@ void RuntimeDecorator::addNativeObjects(jsi::Runtime &rt,
jsi::Value updateProps = jsi::Function::createFromHostFunction(rt, jsi::PropNameID::forAscii(rt, "_updateProps"), 2, clb);
rt.global().setProperty(rt, "_updateProps", updateProps);

addLog(rt);

auto clb2 = [requestFrame](
jsi::Runtime &rt,
Expand Down
1 change: 0 additions & 1 deletion Common/cpp/headers/NativeModules/NativeReanimatedModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ class NativeReanimatedModule : public NativeReanimatedModuleSpec
struct Th {
std::unique_ptr<jsi::Runtime> rt;
std::shared_ptr<std::thread> thread;
std::shared_ptr<ShareableValue> worklet;
};
int currentThreadId = 0;
std::unordered_map<int, std::shared_ptr<Th>> threads;
Expand Down
4 changes: 2 additions & 2 deletions Common/cpp/headers/SharedItems/FrozenObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ class FrozenObject : public jsi::HostObject {

private:
std::unordered_map<std::string, std::shared_ptr<ShareableValue>> map;
const int customThreadId;
int customThreadId;

public:

FrozenObject(jsi::Runtime &rt, const jsi::Object &object, NativeReanimatedModule *module, const int customThreadId = -1);
jsi::Object shallowClone(jsi::Runtime &rt);
jsi::Object shallowClone(jsi::Runtime &rt, const int customThreadId = -1);
};

}
3 changes: 1 addition & 2 deletions Common/cpp/headers/SharedItems/ShareableValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,7 @@ friend void extractMutables(jsi::Runtime &rt,
ValueType type = ValueType::UndefinedType;
std::shared_ptr<MutableValue> mutableValue;
static std::shared_ptr<ShareableValue> adapt(jsi::Runtime &rt, const jsi::Value &value, NativeReanimatedModule *module, ValueType valueType = ValueType::UndefinedType, const int customThreadId = -1);
jsi::Value getValue(jsi::Runtime &rt);

jsi::Value getValue(jsi::Runtime &rt, const int customThreadId = -1);
};

}
4 changes: 2 additions & 2 deletions Common/cpp/headers/Tools/RuntimeDecorator.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ using RequestFrameFunction = std::function<void(std::function<void(double)>)>;

class RuntimeDecorator {
public:
static void addNativeObjects(jsi::Runtime &rt,
static void decorateCustomThread(jsi::Runtime &rt);
static void decorateUI(jsi::Runtime &rt,
UpdaterFunction updater,
RequestFrameFunction requestFrame,
ScrollToFunction scrollTo,
MeasuringFunction measure,
TimeProviderFunction getCurrentTime);
static void addLog(jsi::Runtime &rt);
};

}
6 changes: 1 addition & 5 deletions Example/src/AnimatedStyleUpdateExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default function App() {
/* * /
useAnimatedStyle(() => {
sv;
console.log('siema', _WORKLET)
console.log('here', _WORKLET)
return {};
})
/*
Expand All @@ -40,10 +40,6 @@ export default function App() {
'worklet';
_log('> spawn thread #1 start ' + vvv);
sv.value = 1;
// vvv;// nie ma krasha
// sv.value; // jest krasz
// po prostu shared value nie jest przystosowane do innych watkow niz js/ui najwyrazniej...
// vvv;
for (let i = 0; i < 3000000000; ++i) {}
sv.value = 2;
_log('> spawn thread #1 end');
Expand Down
4 changes: 0 additions & 4 deletions src/reanimated2/Hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,3 @@ export function useWorkletCallback(fun, deps) {
export function createWorklet(fun) {
return fun;
}

export function spawnThread(operations) {
return NativeReanimated.spawnThread(operations);
}
17 changes: 17 additions & 0 deletions src/reanimated2/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,3 +245,20 @@ runOnUI(() => {
};
_setGlobalConsole(console);
})();

export function spawnThread(operations) {
const target = () => {
'worklet';
const console = {
log: runOnJS(capturableConsole.log),
warn: runOnJS(capturableConsole.warn),
error: runOnJS(capturableConsole.error),
info: runOnJS(capturableConsole.info),
};
_setGlobalConsole(console);

operations();
};

return NativeReanimated.spawnThread(target);
}

0 comments on commit 6f7572f

Please sign in to comment.