1 #include "MutableValue.h" 2 #include "RuntimeDecorator.h" 3 #include "RuntimeManager.h" 4 #include "ShareableValue.h" 5 #include "SharedParent.h" 6 7 #include <string> 8 9 namespace ABI47_0_0reanimated { 10 11 void MutableValue::setValue(jsi::Runtime &rt, const jsi::Value &newValue) { 12 std::lock_guard<std::mutex> lock(readWriteMutex); 13 value = ShareableValue::adapt(rt, newValue, runtimeManager); 14 15 std::shared_ptr<MutableValue> thiz = shared_from_this(); 16 auto notifyListeners = [thiz]() { 17 for (auto listener : thiz->listeners) { 18 listener.second(); 19 } 20 }; 21 if (RuntimeDecorator::isUIRuntime(rt)) { 22 notifyListeners(); 23 } else { 24 runtimeManager->scheduler->scheduleOnUI( 25 [notifyListeners] { notifyListeners(); }); 26 } 27 } 28 29 jsi::Value MutableValue::getValue(jsi::Runtime &rt) { 30 std::lock_guard<std::mutex> lock(readWriteMutex); 31 return value->getValue(rt); 32 } 33 34 void MutableValue::set( 35 jsi::Runtime &rt, 36 const jsi::PropNameID &name, 37 const jsi::Value &newValue) { 38 auto propName = name.utf8(rt); 39 if (!runtimeManager->valueSetter) { 40 throw jsi::JSError( 41 rt, 42 "Value-Setter is not yet configured! Make sure the core-functions are installed."); 43 } 44 45 if (RuntimeDecorator::isUIRuntime(rt)) { 46 // UI thread 47 if (propName == "value") { 48 auto setterProxy = jsi::Object::createFromHostObject( 49 rt, std::make_shared<MutableValueSetterProxy>(shared_from_this())); 50 runtimeManager->valueSetter->getValue(rt) 51 .asObject(rt) 52 .asFunction(rt) 53 .callWithThis(rt, setterProxy, newValue); 54 } else if (propName == "_animation") { 55 // TODO: assert to allow animation to be set from UI only 56 if (animation.expired()) { 57 animation = getWeakRef(rt); 58 } 59 *animation.lock() = jsi::Value(rt, newValue); 60 } else if (propName == "_value") { 61 auto setter = 62 std::make_shared<MutableValueSetterProxy>(shared_from_this()); 63 setter->set(rt, jsi::PropNameID::forAscii(rt, "_value"), newValue); 64 } 65 } else { 66 // ABI47_0_0React-JS Thread or another threaded Runtime. 67 if (propName == "value") { 68 auto shareable = ShareableValue::adapt(rt, newValue, runtimeManager); 69 runtimeManager->scheduler->scheduleOnUI([this, shareable] { 70 jsi::Runtime &rt = *this->runtimeManager->runtime.get(); 71 auto setterProxy = jsi::Object::createFromHostObject( 72 rt, std::make_shared<MutableValueSetterProxy>(shared_from_this())); 73 jsi::Value newValue = shareable->getValue(rt); 74 runtimeManager->valueSetter->getValue(rt) 75 .asObject(rt) 76 .asFunction(rt) 77 .callWithThis(rt, setterProxy, newValue); 78 }); 79 } 80 } 81 } 82 83 jsi::Value MutableValue::get(jsi::Runtime &rt, const jsi::PropNameID &name) { 84 auto propName = name.utf8(rt); 85 86 if (propName == "value") { 87 return getValue(rt); 88 } 89 90 if (RuntimeDecorator::isUIRuntime(rt)) { 91 // _value and _animation should be accessed from UI only 92 if (propName == "_value") { 93 return getValue(rt); 94 } else if (propName == "_animation") { 95 // TODO: assert to allow animation to be read from UI only 96 if (animation.expired()) { 97 animation = getWeakRef(rt); 98 } 99 return jsi::Value(rt, *(animation.lock())); 100 } 101 } 102 103 return jsi::Value::undefined(); 104 } 105 106 std::vector<jsi::PropNameID> MutableValue::getPropertyNames(jsi::Runtime &rt) { 107 std::vector<jsi::PropNameID> result; 108 result.push_back(jsi::PropNameID::forUtf8(rt, std::string("value"))); 109 return result; 110 } 111 112 MutableValue::MutableValue( 113 jsi::Runtime &rt, 114 const jsi::Value &initial, 115 RuntimeManager *runtimeManager, 116 std::shared_ptr<Scheduler> s) 117 : StoreUser(s, *runtimeManager), 118 runtimeManager(runtimeManager), 119 value(ShareableValue::adapt(rt, initial, runtimeManager)) {} 120 121 unsigned long int MutableValue::addListener( 122 unsigned long id, 123 std::function<void()> listener) { 124 listeners[id] = listener; 125 return id; 126 } 127 128 void MutableValue::removeListener(unsigned long listenerId) { 129 if (listeners.count(listenerId) > 0) { 130 listeners.erase(listenerId); 131 } 132 } 133 134 } // namespace reanimated 135