- App.tsx: full navigation (Auth stack + Main tabs with 5 screens) - Auth: LoginScreen, RegisterScreen, ForgotPasswordScreen - HomeScreen: dashboard with IoT metrics, weather widget, alerts, quick actions, sensors - MapScreen: interactive map with layer toggles (6 layers) - MarketplaceScreen: categories (6), products (5), search - ChatScreen: AI chat with quick prompts (4), bot responses - ProfileScreen: user info, stats, menu (9 items), logout - AlertsScreen: alert list with severity, acknowledge - SensorsScreen: sensor list with type filters (6 types), search - ZonesScreen: zone cards with stats - SettingsScreen: language picker (FR/EN/ES/DE), privacy, about - Stores: iotStore (sensors, zones, alerts), notificationStore, uiStore + i18n - Hooks: useSensors, useAlerts, useNotifications, useLocation - Components: Card, Button, LoadingSpinner, ErrorBoundary, Header - Services: iotService, notificationService (with axios API client) - Utils: formatters (temp, AQI, noise, dates), validators (email, password, IBAN) - Theme: colors.ts with full design system (Blue Ocean palette) - Ditto: fixed MongoDB connection, new JWT secrets, official gateway image
150 lines
5.5 KiB
C++
150 lines
5.5 KiB
C++
#pragma once
|
|
|
|
// JS_RUNTIME_HERMES is only set on Android so we have to check __has_include
|
|
// on iOS.
|
|
#if __APPLE__ && \
|
|
(__has_include( \
|
|
<reacthermes/HermesExecutorFactory.h>) || __has_include(<hermes/hermes.h>))
|
|
#define JS_RUNTIME_HERMES 1
|
|
#endif
|
|
|
|
// Only include this file in Hermes-enabled builds as some platforms (like tvOS)
|
|
// don't support hermes and it causes the compilation to fail.
|
|
#if JS_RUNTIME_HERMES
|
|
|
|
#include <cxxreact/MessageQueueThread.h>
|
|
#include <jsi/decorator.h>
|
|
#include <jsi/jsi.h>
|
|
|
|
#include <atomic>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <thread>
|
|
|
|
#if __has_include(<reacthermes/HermesExecutorFactory.h>)
|
|
#include <reacthermes/HermesExecutorFactory.h>
|
|
#else // __has_include(<hermes/hermes.h>) || ANDROID
|
|
#include <hermes/hermes.h>
|
|
#endif
|
|
|
|
#if HERMES_ENABLE_DEBUGGER
|
|
#if REACT_NATIVE_MINOR_VERSION >= 73
|
|
#include <hermes/inspector-modern/chrome/Registration.h>
|
|
#else
|
|
#include <hermes/inspector/RuntimeAdapter.h>
|
|
#include <hermes/inspector/chrome/Registration.h>
|
|
#endif
|
|
#endif // HERMES_ENABLE_DEBUGGER
|
|
|
|
namespace reanimated {
|
|
|
|
using namespace facebook;
|
|
using namespace react;
|
|
#if HERMES_ENABLE_DEBUGGER
|
|
#if REACT_NATIVE_MINOR_VERSION >= 73
|
|
using namespace facebook::hermes::inspector_modern;
|
|
#else
|
|
using namespace facebook::hermes::inspector;
|
|
#endif
|
|
#endif // HERMES_ENABLE_DEBUGGER
|
|
|
|
// ReentrancyCheck is copied from React Native
|
|
// from ReactCommon/hermes/executor/HermesExecutorFactory.cpp
|
|
// https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/hermes/executor/HermesExecutorFactory.cpp
|
|
struct ReanimatedReentrancyCheck {
|
|
// This is effectively a very subtle and complex assert, so only
|
|
// include it in builds which would include asserts.
|
|
#ifndef NDEBUG
|
|
ReanimatedReentrancyCheck() : tid(std::thread::id()), depth(0) {}
|
|
|
|
void before() {
|
|
std::thread::id this_id = std::this_thread::get_id();
|
|
std::thread::id expected = std::thread::id();
|
|
|
|
// A note on memory ordering: the main purpose of these checks is
|
|
// to observe a before/before race, without an intervening after.
|
|
// This will be detected by the compare_exchange_strong atomicity
|
|
// properties, regardless of memory order.
|
|
//
|
|
// For everything else, it is easiest to think of 'depth' as a
|
|
// proxy for any access made inside the VM. If access to depth
|
|
// are reordered incorrectly, the same could be true of any other
|
|
// operation made by the VM. In fact, using acquire/release
|
|
// memory ordering could create barriers which mask a programmer
|
|
// error. So, we use relaxed memory order, to avoid masking
|
|
// actual ordering errors. Although, in practice, ordering errors
|
|
// of this sort would be surprising, because the decorator would
|
|
// need to call after() without before().
|
|
|
|
if (tid.compare_exchange_strong(
|
|
expected, this_id, std::memory_order_relaxed)) {
|
|
// Returns true if tid and expected were the same. If they
|
|
// were, then the stored tid referred to no thread, and we
|
|
// atomically saved this thread's tid. Now increment depth.
|
|
assert(depth == 0 && "[Reanimated] No thread id, but depth != 0");
|
|
++depth;
|
|
} else if (expected == this_id) {
|
|
// If the stored tid referred to a thread, expected was set to
|
|
// that value. If that value is this thread's tid, that's ok,
|
|
// just increment depth again.
|
|
assert(depth != 0 && "[Reanimated] Thread id was set, but depth == 0");
|
|
++depth;
|
|
} else {
|
|
// The stored tid was some other thread. This indicates a bad
|
|
// programmer error, where VM methods were called on two
|
|
// different threads unsafely. Fail fast (and hard) so the
|
|
// crash can be analyzed.
|
|
__builtin_trap();
|
|
}
|
|
}
|
|
|
|
void after() {
|
|
assert(
|
|
tid.load(std::memory_order_relaxed) == std::this_thread::get_id() &&
|
|
"[Reanimated] No thread id in after()");
|
|
if (--depth == 0) {
|
|
// If we decremented depth to zero, store no-thread into tid.
|
|
std::thread::id expected = std::this_thread::get_id();
|
|
bool didWrite = tid.compare_exchange_strong(
|
|
expected, std::thread::id(), std::memory_order_relaxed);
|
|
assert(didWrite && "[Reanimated] Decremented to zero, but no tid write");
|
|
}
|
|
}
|
|
|
|
std::atomic<std::thread::id> tid;
|
|
// This is not atomic, as it is only written or read from the owning
|
|
// thread.
|
|
unsigned int depth;
|
|
#endif // NDEBUG
|
|
};
|
|
|
|
// This is in fact a subclass of jsi::Runtime! WithRuntimeDecorator is a
|
|
// template class that is a subclass of DecoratedRuntime which is also a
|
|
// template class that then inherits its template, which in this case is
|
|
// jsi::Runtime. So the inheritance is: ReanimatedHermesRuntime ->
|
|
// WithRuntimeDecorator -> DecoratedRuntime -> jsi::Runtime You can find out
|
|
// more about this in ReactCommon/jsi/jsi/Decorator.h or by following this link:
|
|
// https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/jsi/jsi/decorator.h
|
|
class ReanimatedHermesRuntime
|
|
: public jsi::WithRuntimeDecorator<ReanimatedReentrancyCheck> {
|
|
public:
|
|
ReanimatedHermesRuntime(
|
|
std::unique_ptr<facebook::hermes::HermesRuntime> runtime,
|
|
const std::shared_ptr<MessageQueueThread> &jsQueue,
|
|
const std::string &name);
|
|
~ReanimatedHermesRuntime();
|
|
|
|
private:
|
|
std::unique_ptr<facebook::hermes::HermesRuntime> runtime_;
|
|
ReanimatedReentrancyCheck reentrancyCheck_;
|
|
#if HERMES_ENABLE_DEBUGGER
|
|
#if REACT_NATIVE_MINOR_VERSION >= 71
|
|
chrome::DebugSessionToken debugToken_;
|
|
#endif // REACT_NATIVE_MINOR_VERSION >= 71
|
|
#endif // HERMES_ENABLE_DEBUGGER
|
|
};
|
|
|
|
} // namespace reanimated
|
|
|
|
#endif // JS_RUNTIME_HERMES
|