Skip to content

Commit

Permalink
Scaffolding for the PerformanceObserver TurboModule
Browse files Browse the repository at this point in the history
Summary: Changelog: [Internal]

Differential Revision: D41028555

fbshipit-source-id: 082e80e0ccbde9633e30e5de19129f85e11dc373
  • Loading branch information
christophpurrer authored and facebook-github-bot committed Nov 6, 2022
1 parent f0b7cbe commit e100c9f
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 17 deletions.
28 changes: 28 additions & 0 deletions BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ load(
)
load(
"//tools/build_defs/oss:rn_defs.bzl",
"ANDROID",
"APPLE",
"CXX",
"HERMES_BYTECODE_VERSION",
"IOS",
"RCT_IMAGE_DATA_DECODER_SOCKET",
Expand Down Expand Up @@ -1453,3 +1456,28 @@ rn_xplat_cxx_library2(
"//fbobjc/VendorLib/react-native-maps:react-native-maps",
],
)

rn_xplat_cxx_library2(
name = "RCTWebPerformance",
srcs = glob([
"Libraries/WebPerformance/**/*.cpp",
]),
header_namespace = "",
exported_headers = subdir_glob(
[("Libraries/WebPerformance", "*.h")],
prefix = "RCTWebPerformance",
),
fbandroid_compiler_flags = [
"-fexceptions",
"-frtti",
],
labels = [
"depslint_never_remove",
"pfh:ReactNative_CommonInfrastructurePlaceholder",
],
platforms = (ANDROID, APPLE, CXX),
visibility = ["PUBLIC"],
deps = [
":FBReactNativeSpecJSI",
],
)
41 changes: 41 additions & 0 deletions Libraries/WebPerformance/NativePerformanceObserver.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#include "NativePerformanceObserver.h"

namespace facebook::react {

void NativePerformanceObserver::startReporting(
jsi::Runtime &rt,
std::string entryType) {}

void NativePerformanceObserver::stopReporting(
jsi::Runtime &rt,
std::string entryType) {}

std::vector<RawPerformanceEntry> NativePerformanceObserver::getPendingEntries(
jsi::Runtime &rt) {
return std::vector<RawPerformanceEntry>{};
}

std::function<void()> NativePerformanceObserver::setOnPerformanceEntryCallback(
jsi::Runtime &rt,
std::optional<AsyncCallback<>> callback) {
callback_ = callback;
// Invoke function
// if (callback) {
// callback.value()();
// }
// return cleanup function
return [weakThis = weak_from_this()]() {
if (auto strongThis = weakThis.lock()) {
strongThis->callback_ = std::nullopt;
}
};
}

} // namespace facebook::react
40 changes: 40 additions & 0 deletions Libraries/WebPerformance/NativePerformanceObserver.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include <FBReactNativeSpec/FBReactNativeSpecJSI.h>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "NativePerformanceObserver_RawPerformanceEntry.h"

namespace facebook::react {

class NativePerformanceObserver
: public NativePerformanceObserverCxxSpec<NativePerformanceObserver>,
std::enable_shared_from_this<NativePerformanceObserver> {
public:
NativePerformanceObserver(std::shared_ptr<CallInvoker> jsInvoker);

void startReporting(jsi::Runtime &rt, std::string entryType);

void stopReporting(jsi::Runtime &rt, std::string entryType);

std::vector<RawPerformanceEntry> getPendingEntries(jsi::Runtime &rt);

std::function<void()> setOnPerformanceEntryCallback(
jsi::Runtime &rt,
std::optional<AsyncCallback<>> callback);

private:
std::optional<AsyncCallback<>> callback_;
};

} // namespace facebook::react
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
* @format
*/

import type {TurboModule} from '../../TurboModule/RCTExport';
import type {TurboModule} from '../TurboModule/RCTExport';

import * as TurboModuleRegistry from '../../TurboModule/TurboModuleRegistry';

export type RawTimeStamp = number;
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';

export const RawPerformanceEntryTypeValues = {
UNDEFINED: 0,
Expand All @@ -23,22 +21,25 @@ export type RawPerformanceEntryType = number;
export type RawPerformanceEntry = $ReadOnly<{
name: string,
entryType: RawPerformanceEntryType,
startTime: RawTimeStamp,
startTime: number,
duration: number,

// For "event" entries only:
processingStart?: RawTimeStamp,
processingEnd?: RawTimeStamp,
interactionId?: RawTimeStamp,
processingStart?: number,
processingEnd?: number,
interactionId?: number,
}>;

export type RawPerformanceEntryList = $ReadOnlyArray<RawPerformanceEntry>;
export type OnPerformanceEntryCallbackUnsubscribe = () => void;

export interface Spec extends TurboModule {
+startReporting: (entryType: string) => void;
+stopReporting: (entryType: string) => void;
+getPendingEntries: () => RawPerformanceEntryList;
+setOnPerformanceEntryCallback: (callback?: () => void) => void;
+getPendingEntries: () => $ReadOnlyArray<RawPerformanceEntry>;
+setOnPerformanceEntryCallback: (
callback?: () => void,
) => OnPerformanceEntryCallbackUnsubscribe;
}

export default (TurboModuleRegistry.get<Spec>('PerformanceObserver'): ?Spec);
export default (TurboModuleRegistry.get<Spec>(
'NativePerformanceObserverCxx',
): ?Spec);
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include <react/bridging/Bridging.h>
#include <optional>
#include <string>

namespace facebook::react {

struct RawPerformanceEntry {
std::string name;
int32_t entryType;
float startTime;
float duration;
// For "event" entries only:
std::optional<float> processingStart;
std::optional<float> processingEnd;
std::optional<float> interactionId;
};

template <>
struct Bridging<RawPerformanceEntry> {
static RawPerformanceEntry fromJs(
jsi::Runtime &rt,
const jsi::Object &value,
const std::shared_ptr<CallInvoker> &jsInvoker) {
RawPerformanceEntry result{
bridging::fromJs<std::string>(
rt, value.getProperty(rt, "name"), jsInvoker),
bridging::fromJs<int32_t>(
rt, value.getProperty(rt, "entryType"), jsInvoker),
bridging::fromJs<float>(
rt, value.getProperty(rt, "startTime"), jsInvoker),
bridging::fromJs<float>(
rt, value.getProperty(rt, "duration"), jsInvoker),
bridging::fromJs<std::optional<float>>(
rt, value.getProperty(rt, "processingStart"), jsInvoker),
bridging::fromJs<std::optional<float>>(
rt, value.getProperty(rt, "processingEnd"), jsInvoker),
bridging::fromJs<std::optional<float>>(
rt, value.getProperty(rt, "interactionId"), jsInvoker),
};
return result;
}

static jsi::Object toJs(jsi::Runtime &rt, const RawPerformanceEntry &value) {
auto result = facebook::jsi::Object(rt);
result.setProperty(rt, "name", bridging::toJs(rt, value.name));
result.setProperty(rt, "entryType", bridging::toJs(rt, value.entryType));
result.setProperty(rt, "startTime", bridging::toJs(rt, value.startTime));
result.setProperty(rt, "duration", bridging::toJs(rt, value.duration));
if (value.processingStart) {
result.setProperty(
rt,
"processingStart",
bridging::toJs(rt, value.processingStart.value()));
}
if (value.processingEnd) {
result.setProperty(
rt, "processingEnd", bridging::toJs(rt, value.processingEnd.value()));
}
if (value.interactionId) {
result.setProperty(
rt, "interactionId", bridging::toJs(rt, value.interactionId.value()));
}
return result;
}
};

} // namespace facebook::react
7 changes: 3 additions & 4 deletions Libraries/WebPerformance/PerformanceObserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@

import type {
RawPerformanceEntry,
RawPerformanceEntryList,
RawPerformanceEntryType,
} from '../NativeModules/specs/NativePerformanceObserverCxx';
} from './NativePerformanceObserver';

import NativePerformanceObserver from '../NativeModules/specs/NativePerformanceObserverCxx';
import warnOnce from '../Utilities/warnOnce';
import NativePerformanceObserver from './NativePerformanceObserver';

export type HighResTimeStamp = number;
// TODO: Extend once new types (such as event) are supported.
Expand Down Expand Up @@ -210,7 +209,7 @@ function onPerformanceEntry() {
if (!NativePerformanceObserver) {
return;
}
const rawEntries: RawPerformanceEntryList =
const rawEntries: $ReadOnlyArray<RawPerformanceEntry> =
NativePerformanceObserver.getPendingEntries();
const entries = rawEntries.map(rawToPerformanceEntry);
_observers.forEach(observer => {
Expand Down

0 comments on commit e100c9f

Please sign in to comment.