mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-26 21:00:16 +08:00
Add timeline traces in the console, let enabling them through the package.json
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
import { assert, assertEqual, assertFalse, assertTrue, assertThrows } from "../TKUnit";
|
||||
import { enable, disable, profile, time, start, stop, pause, isRunning } from "tns-core-modules/profiling";
|
||||
import { enable, disable, profile, time, start, stop, timer, isRunning, resetProfiles } from "tns-core-modules/profiling";
|
||||
|
||||
enable();
|
||||
class TestClass {
|
||||
@ -22,6 +22,20 @@ class TestClass {
|
||||
unnamed2() {
|
||||
// noop
|
||||
}
|
||||
|
||||
private isInReentrant = false;
|
||||
|
||||
@profile
|
||||
reentrant() {
|
||||
try {
|
||||
if (!this.isInReentrant) {
|
||||
this.isInReentrant = true;
|
||||
this.reentrant();
|
||||
}
|
||||
} finally {
|
||||
this.isInReentrant = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const testFunction1 = profile(function testFunction1() {
|
||||
@ -45,41 +59,54 @@ function retry(count: number, action: () => void) {
|
||||
}
|
||||
}
|
||||
|
||||
export function setUp() {
|
||||
enable();
|
||||
}
|
||||
|
||||
export function tearDown() {
|
||||
disable();
|
||||
}
|
||||
|
||||
export function test_time_returns_number() {
|
||||
assertEqual(typeof time(), "number");
|
||||
};
|
||||
|
||||
export function test_isRunning() {
|
||||
resetProfiles();
|
||||
const name = "test_isRunning";
|
||||
assertFalse(isRunning(name), "isRunning should be false before start");
|
||||
|
||||
start(name);
|
||||
assertTrue(isRunning(name), "isRunning should be true after start");
|
||||
|
||||
pause(name);
|
||||
assertFalse(isRunning(name), "isRunning should be false after pause");
|
||||
stop(name);
|
||||
assertFalse(isRunning(name), "isRunning should be false after stop");
|
||||
|
||||
start(name);
|
||||
assertTrue(isRunning(name), "isRunning should be true after second start");
|
||||
|
||||
stop(name);
|
||||
assertFalse(isRunning(name), "isRunning should be false after stop");
|
||||
assertFalse(isRunning(name), "isRunning should be false after second stop");
|
||||
}
|
||||
|
||||
export function test_isRunning_withReentrancy() {
|
||||
resetProfiles();
|
||||
const name = "test_isRunning";
|
||||
assertFalse(isRunning(name), "isRunning should be false before start");
|
||||
|
||||
start(name);
|
||||
assertTrue(isRunning(name), "isRunning should be true after start");
|
||||
|
||||
start(name);
|
||||
assertTrue(isRunning(name), "isRunning should be true after second start");
|
||||
|
||||
stop(name);
|
||||
assertTrue(isRunning(name), "isRunning should be true after first stop");
|
||||
|
||||
stop(name);
|
||||
assertFalse(isRunning(name), "isRunning should be false after second stop");
|
||||
}
|
||||
|
||||
export function test_start_stop() {
|
||||
resetProfiles();
|
||||
retry(5, () => {
|
||||
const name = "test_start_stop";
|
||||
|
||||
start(name);
|
||||
const res = stop(name);
|
||||
stop(name);
|
||||
const res = timer(name);
|
||||
|
||||
assertEqual(res.count, 1);
|
||||
assert(res.totalTime <= 1);
|
||||
@ -87,18 +114,20 @@ export function test_start_stop() {
|
||||
};
|
||||
|
||||
export function test_start_pause_count() {
|
||||
resetProfiles();
|
||||
const name = "test_start_pause_count";
|
||||
|
||||
for (var i = 0; i < 10; i++) {
|
||||
start(name);
|
||||
pause(name);
|
||||
stop(name);
|
||||
}
|
||||
|
||||
const res = stop(name);
|
||||
const res = timer(name);
|
||||
assertEqual(res.count, 10);
|
||||
};
|
||||
|
||||
export function test_profile_decorator_count() {
|
||||
resetProfiles();
|
||||
const test = new TestClass();
|
||||
for (var i = 0; i < 10; i++) {
|
||||
test.doNothing();
|
||||
@ -109,36 +138,39 @@ export function test_profile_decorator_count() {
|
||||
}
|
||||
|
||||
["__func_decorator__", "TestClass.unnamed1", "TestClass.unnamed2", "testFunction1", "testFunction2"].forEach(key => {
|
||||
const res = stop(key);
|
||||
const res = timer(key);
|
||||
assertEqual(res.count, 10, "Expected profile with name ${key} to have traced 10 calls.");
|
||||
});
|
||||
}
|
||||
|
||||
export function test_profile_decorator_handles_exceptions() {
|
||||
resetProfiles();
|
||||
const test = new TestClass();
|
||||
|
||||
assertThrows(() => test.throwError());
|
||||
assertFalse(isRunning("__func_decorator_error__"), "Timer should be stopped on exception.");
|
||||
assertEqual(stop("__func_decorator_error__").count, 1, "Timer should be called once");
|
||||
assertEqual(timer("__func_decorator_error__").count, 1, "Timer should be called once");
|
||||
}
|
||||
|
||||
export function test_start_pause_performance() {
|
||||
resetProfiles();
|
||||
retry(5, () => {
|
||||
const count = 10000;
|
||||
const name = "test_start_pause_performance";
|
||||
|
||||
for (var i = 0; i < count; i++) {
|
||||
start(name);
|
||||
pause(name);
|
||||
stop(name);
|
||||
}
|
||||
|
||||
const res = stop(name);
|
||||
const res = timer(name);
|
||||
assertEqual(res.count, count);
|
||||
assert(res.totalTime <= 500, `Total time for ${count} timer operations is too much: ${res.totalTime}`);
|
||||
});
|
||||
};
|
||||
|
||||
export function test_profile_decorator_performance() {
|
||||
resetProfiles();
|
||||
retry(5, () => {
|
||||
var start = Date.now();
|
||||
const count = 10000;
|
||||
@ -147,7 +179,7 @@ export function test_profile_decorator_performance() {
|
||||
test.doNothing();
|
||||
}
|
||||
|
||||
const res = stop("__func_decorator__");
|
||||
const res = timer("__func_decorator__");
|
||||
assertEqual(res.count, count);
|
||||
|
||||
assert(res.totalTime <= 500, `Total time for ${count} timer operations is too much: ${res.totalTime}`);
|
||||
@ -155,3 +187,12 @@ export function test_profile_decorator_performance() {
|
||||
assert(end - start <= 1000, `Total time for test execution is too much: ${end - start}ms`);
|
||||
});
|
||||
}
|
||||
|
||||
export function test_reentrancy() {
|
||||
resetProfiles();
|
||||
// reentrant
|
||||
retry(5, () => {
|
||||
const test = new TestClass();
|
||||
test.reentrant();
|
||||
});
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import {
|
||||
notify, hasListeners, lowMemoryEvent, orientationChangedEvent, suspendEvent, resumeEvent, displayedEvent,
|
||||
setApplication, livesync, Observable
|
||||
} from "./application-common";
|
||||
import { profile } from "../profiling";
|
||||
|
||||
// First reexport so that app module is initialized.
|
||||
export * from "./application-common";
|
||||
@ -167,7 +168,7 @@ global.__onLiveSync = function () {
|
||||
function initLifecycleCallbacks() {
|
||||
// TODO: Verify whether the logic for triggerring application-wide events based on Activity callbacks is working properly
|
||||
const lifecycleCallbacks = new android.app.Application.ActivityLifecycleCallbacks({
|
||||
onActivityCreated: function (activity: android.app.Activity, savedInstanceState: android.os.Bundle) {
|
||||
onActivityCreated: profile("onActivityCreated", function (activity: android.app.Activity, savedInstanceState: android.os.Bundle) {
|
||||
// Set app theme after launch screen was used during startup
|
||||
const activityInfo = activity.getPackageManager().getActivityInfo(activity.getComponentName(), android.content.pm.PackageManager.GET_META_DATA);
|
||||
if (activityInfo.metaData) {
|
||||
@ -194,9 +195,9 @@ function initLifecycleCallbacks() {
|
||||
});
|
||||
rootView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
onActivityDestroyed: function (activity: android.app.Activity) {
|
||||
onActivityDestroyed: profile("onActivityDestroyed", function (activity: android.app.Activity) {
|
||||
if (activity === androidApp.foregroundActivity) {
|
||||
androidApp.foregroundActivity = undefined;
|
||||
}
|
||||
@ -208,18 +209,18 @@ function initLifecycleCallbacks() {
|
||||
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityDestroyed, object: androidApp, activity: activity });
|
||||
// TODO: This is a temporary workaround to force the V8's Garbage Collector, which will force the related Java Object to be collected.
|
||||
gc();
|
||||
},
|
||||
}),
|
||||
|
||||
onActivityPaused: function (activity: android.app.Activity) {
|
||||
onActivityPaused: profile("onActivityPaused", function (activity: android.app.Activity) {
|
||||
if ((<any>activity).isNativeScriptActivity) {
|
||||
androidApp.paused = true;
|
||||
notify(<ApplicationEventData>{ eventName: suspendEvent, object: androidApp, android: activity });
|
||||
}
|
||||
|
||||
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityPaused, object: androidApp, activity: activity });
|
||||
},
|
||||
}),
|
||||
|
||||
onActivityResumed: function (activity: android.app.Activity) {
|
||||
onActivityResumed: profile("onActivityResumed", function (activity: android.app.Activity) {
|
||||
androidApp.foregroundActivity = activity;
|
||||
|
||||
if ((<any>activity).isNativeScriptActivity) {
|
||||
@ -228,19 +229,19 @@ function initLifecycleCallbacks() {
|
||||
}
|
||||
|
||||
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityResumed, object: androidApp, activity: activity });
|
||||
},
|
||||
}),
|
||||
|
||||
onActivitySaveInstanceState: function (activity: android.app.Activity, outState: android.os.Bundle) {
|
||||
onActivitySaveInstanceState: profile("onActivityResumed", function (activity: android.app.Activity, outState: android.os.Bundle) {
|
||||
androidApp.notify(<AndroidActivityBundleEventData>{ eventName: SaveActivityState, object: androidApp, activity: activity, bundle: outState });
|
||||
},
|
||||
}),
|
||||
|
||||
onActivityStarted: function (activity: android.app.Activity) {
|
||||
onActivityStarted: profile("onActivityStarted", function (activity: android.app.Activity) {
|
||||
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityStarted, object: androidApp, activity: activity });
|
||||
},
|
||||
}),
|
||||
|
||||
onActivityStopped: function (activity: android.app.Activity) {
|
||||
onActivityStopped: profile("onActivityStopped", function (activity: android.app.Activity) {
|
||||
androidApp.notify(<AndroidActivityEventData>{ eventName: ActivityStopped, object: androidApp, activity: activity });
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return lifecycleCallbacks;
|
||||
@ -249,17 +250,17 @@ function initLifecycleCallbacks() {
|
||||
let currentOrientation: number;
|
||||
function initComponentCallbacks() {
|
||||
let componentCallbacks = new android.content.ComponentCallbacks2({
|
||||
onLowMemory: function () {
|
||||
onLowMemory: profile("onLowMemory", function () {
|
||||
gc();
|
||||
java.lang.System.gc();
|
||||
notify(<ApplicationEventData>{ eventName: lowMemoryEvent, object: this, android: this });
|
||||
},
|
||||
}),
|
||||
|
||||
onTrimMemory: function (level: number) {
|
||||
onTrimMemory: profile("onTrimMemory", function (level: number) {
|
||||
// TODO: This is skipped for now, test carefully for OutOfMemory exceptions
|
||||
},
|
||||
}),
|
||||
|
||||
onConfigurationChanged: function (newConfig: android.content.res.Configuration) {
|
||||
onConfigurationChanged: profile("onConfigurationChanged", function (newConfig: android.content.res.Configuration) {
|
||||
const newOrientation = newConfig.orientation;
|
||||
if (newOrientation === currentOrientation) {
|
||||
return;
|
||||
@ -286,7 +287,7 @@ function initComponentCallbacks() {
|
||||
newValue: newValue,
|
||||
object: androidApp
|
||||
});
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return componentCallbacks;
|
||||
|
42
tns-core-modules/profiling/profiling.d.ts
vendored
42
tns-core-modules/profiling/profiling.d.ts
vendored
@ -10,9 +10,32 @@ interface TimerInfo {
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables profiling.
|
||||
* Profiling mode to use.
|
||||
* - `counters` Accumulates method call counts and times until dumpProfiles is called and then prints agregated statistic in the console. This is the default.
|
||||
* - `timeline` Outputs method names along start/end timestamps in the console on the go.
|
||||
*/
|
||||
export declare function enable(): void;
|
||||
type InstrumentationMode = "counters" | "timeline";
|
||||
|
||||
/**
|
||||
* Enables profiling.
|
||||
*
|
||||
* Upon loading of the module it will cache the package.json of the app and check if there is a "profiling" key set,
|
||||
* its value can be one of the options available for InstrumentationMode, and if set,
|
||||
* enable() will be called in pre app start with the value in the package.json.
|
||||
*
|
||||
* An example for an `app/package.json` enabling the manual instrumentation profiling is:
|
||||
* ```
|
||||
* {
|
||||
* "main": "main.js",
|
||||
* "profiling": "timeline"
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param type Profiling mode to use.
|
||||
* - "counters" - Accumulates method call counts and times until dumpProfiles is called and then prints agregated statistic in the console. This is the default.
|
||||
* - "timeline" - Outputs method names along start/end timestamps in the console on the go.
|
||||
*/
|
||||
export declare function enable(type?: InstrumentationMode): void;
|
||||
|
||||
/**
|
||||
* Disables profiling.
|
||||
@ -37,15 +60,13 @@ export declare function start(name: string): void;
|
||||
* @param name Name of the timer.
|
||||
* @returns TimerInfo for the paused timer.
|
||||
*/
|
||||
export declare function pause(name: string): TimerInfo;
|
||||
export declare function stop(name: string): TimerInfo;
|
||||
|
||||
/**
|
||||
* Stops a timer with a specific name. This will print the count and the total time and will also reset the timer.
|
||||
* Works only if profiling is enabled.
|
||||
* @param name Name of the timer.
|
||||
* @returns TimerInfo for the stopped timer.
|
||||
* Read a timer info.
|
||||
* @param name The name of the timer to obtain information about.
|
||||
*/
|
||||
export declare function stop(name: string): TimerInfo;
|
||||
export function timer(name: string): TimerInfo;
|
||||
|
||||
/**
|
||||
* Returns true if a timer is currently running.
|
||||
@ -60,18 +81,21 @@ export declare function isRunning(name: string): boolean;
|
||||
* @param name Name of the timer which will be used for method calls. If not provided - the name of the method will be used.
|
||||
*/
|
||||
export declare function profile(name?: string): MethodDecorator;
|
||||
|
||||
/**
|
||||
* Function factory. It will intercept the function call and start and pause a timer before and after the function call. Works only if profiling is enabled.
|
||||
* Works only if profiling is enabled.
|
||||
* @param fn The function to wrap. Uses the function name to track the times.
|
||||
*/
|
||||
export declare function profile<F extends Function>(fn: F): F;
|
||||
|
||||
/**
|
||||
* Function factory. It will intercept the function call and start and pause a timer before and after the function call. Works only if profiling is enabled.
|
||||
* @param name The name used to track calls and times.
|
||||
* @param fn The function to wrap.
|
||||
*/
|
||||
export declare function profile<F extends Function>(name: string, fn: F): F;
|
||||
|
||||
/**
|
||||
* Method decorator. It will intercept the method calls and start and pause a timer before and after the method call. Works only if profiling is enabled.
|
||||
*/
|
||||
@ -103,4 +127,4 @@ export declare function stopCPUProfile(name: string): void;
|
||||
/**
|
||||
* Gets the uptime of the current process in miliseconds.
|
||||
*/
|
||||
export function uptime(): number;
|
||||
export function uptime(): number;
|
||||
|
@ -1,7 +1,7 @@
|
||||
declare var __startCPUProfiler: any;
|
||||
declare var __stopCPUProfiler: any;
|
||||
|
||||
import { TimerInfo as TimerInfoDefinition } from ".";
|
||||
import { TimerInfo as TimerInfoDefinition, InstrumentationMode } from ".";
|
||||
|
||||
export const uptime = global.android ? (<any>org).nativescript.Process.getUpTime : (<any>global).__tns_uptime;
|
||||
|
||||
@ -10,7 +10,10 @@ interface TimerInfo extends TimerInfoDefinition {
|
||||
lastTime?: number;
|
||||
count: number;
|
||||
currentStart: number;
|
||||
isRunning: boolean;
|
||||
/**
|
||||
* Counts the number of entry and exits a function had.
|
||||
*/
|
||||
runCount: number;
|
||||
}
|
||||
|
||||
// Use object instead of map as it is a bit faster
|
||||
@ -18,87 +21,119 @@ const timers: { [index: string]: TimerInfo } = {};
|
||||
const anyGlobal = <any>global;
|
||||
const profileNames: string[] = [];
|
||||
|
||||
let instrumentationEnabled = false;
|
||||
|
||||
export function enable() {
|
||||
instrumentationEnabled = true;
|
||||
}
|
||||
|
||||
export function disable() {
|
||||
instrumentationEnabled = false;
|
||||
}
|
||||
|
||||
export const time = (<any>global).__time || Date.now;
|
||||
|
||||
export function start(name: string): void {
|
||||
let info = timers[name];
|
||||
|
||||
if (info) {
|
||||
if (info.isRunning) {
|
||||
throw new Error(`Timer already running: ${name}`);
|
||||
}
|
||||
info.currentStart = time();
|
||||
info.isRunning = true;
|
||||
info.runCount++;
|
||||
} else {
|
||||
info = {
|
||||
totalTime: 0,
|
||||
count: 0,
|
||||
currentStart: time(),
|
||||
isRunning: true
|
||||
runCount: 1
|
||||
};
|
||||
timers[name] = info;
|
||||
}
|
||||
}
|
||||
|
||||
export function pause(name: string): TimerInfo {
|
||||
let info = pauseInternal(name);
|
||||
return info;
|
||||
}
|
||||
|
||||
export function stop(name: string): TimerInfo {
|
||||
let info = pauseInternal(name);
|
||||
console.log(`---- [${name}] STOP total: ${info.totalTime} count:${info.count}`);
|
||||
|
||||
timers[name] = undefined;
|
||||
return info;
|
||||
}
|
||||
|
||||
export function isRunning(name: string): boolean {
|
||||
const info = timers[name];
|
||||
return !!(info && info.isRunning);
|
||||
}
|
||||
|
||||
function pauseInternal(name: string): TimerInfo {
|
||||
const info = timers[name];
|
||||
|
||||
if (!info) {
|
||||
throw new Error(`No timer started: ${name}`);
|
||||
}
|
||||
|
||||
if (info.isRunning) {
|
||||
info.lastTime = time() - info.currentStart;
|
||||
info.totalTime += info.lastTime;
|
||||
info.count++;
|
||||
info.currentStart = 0;
|
||||
info.isRunning = false;
|
||||
if (info.runCount) {
|
||||
info.runCount--;
|
||||
if (info.runCount) {
|
||||
info.count++;
|
||||
} else {
|
||||
info.lastTime = time() - info.currentStart;
|
||||
info.totalTime += info.lastTime;
|
||||
info.count++;
|
||||
info.currentStart = 0;
|
||||
}
|
||||
} else {
|
||||
throw new Error(`Timer ${name} paused more times than started.`);
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
function profileFunction<F extends Function>(fn: F, customName?: string): F {
|
||||
const name = customName || fn.name;
|
||||
export function timer(name: string): TimerInfo {
|
||||
return timers[name];
|
||||
}
|
||||
|
||||
export function print(name: string): TimerInfo {
|
||||
const info = timers[name];
|
||||
if (!info) {
|
||||
throw new Error(`No timer started: ${name}`);
|
||||
}
|
||||
|
||||
console.log(`---- [${name}] STOP total: ${info.totalTime} count:${info.count}`);
|
||||
return info;
|
||||
}
|
||||
|
||||
export function isRunning(name: string): boolean {
|
||||
const info = timers[name];
|
||||
return !!(info && info.runCount);
|
||||
}
|
||||
|
||||
function countersProfileFunctionFactory<F extends Function>(fn: F, name: string): F {
|
||||
profileNames.push(name);
|
||||
return <any>function() {
|
||||
start(name);
|
||||
try {
|
||||
return fn.apply(this, arguments);
|
||||
} finally {
|
||||
pause(name);
|
||||
stop(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function timelineProfileFunctionFactory<F extends Function>(fn: F, name: string): F {
|
||||
return <any>function() {
|
||||
const start = time();
|
||||
try {
|
||||
return fn.apply(this, arguments);
|
||||
} finally {
|
||||
const end = time();
|
||||
console.log(`Timeline: Modules: ${name} (${start}ms. - ${end}ms.)`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let profileFunctionFactory: <F extends Function>(fn: F, name: string) => F;
|
||||
export function enable(mode: InstrumentationMode = "counters") {
|
||||
profileFunctionFactory = mode && {
|
||||
counters: countersProfileFunctionFactory,
|
||||
timeline: timelineProfileFunctionFactory
|
||||
}[mode];
|
||||
}
|
||||
|
||||
try {
|
||||
const appConfig = global.require("~/package.json");
|
||||
if (appConfig && appConfig.profiling) {
|
||||
if (appConfig && appConfig.profiling) {
|
||||
enable(appConfig.profiling);
|
||||
}
|
||||
}
|
||||
} catch(e) {
|
||||
console.log("Profiling startup failed to figure out defaults from package.json, error: " + e);
|
||||
}
|
||||
|
||||
export function disable() {
|
||||
profileFunctionFactory = undefined;
|
||||
}
|
||||
|
||||
function profileFunction<F extends Function>(fn: F, customName?: string): F {
|
||||
return profileFunctionFactory(fn, customName || fn.name);
|
||||
}
|
||||
|
||||
const profileMethodUnnamed = (target, key, descriptor) => {
|
||||
// save a reference to the original method this way we keep the values currently in the
|
||||
// descriptor and don't overwrite what another decorator might have done to the descriptor.
|
||||
@ -114,17 +149,8 @@ const profileMethodUnnamed = (target, key, descriptor) => {
|
||||
|
||||
let name = className + key;
|
||||
|
||||
profileNames.push(name);
|
||||
|
||||
//editing the descriptor/value parameter
|
||||
descriptor.value = function () {
|
||||
start(name);
|
||||
try {
|
||||
return originalMethod.apply(this, arguments);
|
||||
} finally {
|
||||
pause(name);
|
||||
}
|
||||
};
|
||||
descriptor.value = profileFunctionFactory(originalMethod, name);
|
||||
|
||||
// return edited descriptor as opposed to overwriting the descriptor
|
||||
return descriptor;
|
||||
@ -140,17 +166,8 @@ function profileMethodNamed(name: string): MethodDecorator {
|
||||
}
|
||||
var originalMethod = descriptor.value;
|
||||
|
||||
profileNames.push(name);
|
||||
|
||||
//editing the descriptor/value parameter
|
||||
descriptor.value = function () {
|
||||
start(name);
|
||||
try {
|
||||
return originalMethod.apply(this, arguments);
|
||||
} finally {
|
||||
pause(name);
|
||||
}
|
||||
};
|
||||
descriptor.value = profileFunctionFactory(originalMethod, name);
|
||||
|
||||
// return edited descriptor as opposed to overwriting the descriptor
|
||||
return descriptor;
|
||||
@ -163,27 +180,27 @@ const voidMethodDecorator = () => {
|
||||
|
||||
export function profile(nameFnOrTarget?: string | Function | Object, fnOrKey?: Function | string | symbol, descriptor?: PropertyDescriptor): Function | MethodDecorator {
|
||||
if (typeof nameFnOrTarget === "object" && (typeof fnOrKey === "string" || typeof fnOrKey === "symbol")) {
|
||||
if (!instrumentationEnabled) {
|
||||
if (!profileFunctionFactory) {
|
||||
return;
|
||||
}
|
||||
return profileMethodUnnamed(nameFnOrTarget, fnOrKey, descriptor);
|
||||
} else if (typeof nameFnOrTarget === "string" && typeof fnOrKey === "function") {
|
||||
if (!instrumentationEnabled) {
|
||||
if (!profileFunctionFactory) {
|
||||
return fnOrKey;
|
||||
}
|
||||
return profileFunction(fnOrKey, nameFnOrTarget);
|
||||
} else if (typeof nameFnOrTarget === "function") {
|
||||
if (!instrumentationEnabled) {
|
||||
if (!profileFunctionFactory) {
|
||||
return nameFnOrTarget;
|
||||
}
|
||||
return profileFunction(nameFnOrTarget);
|
||||
} else if (typeof nameFnOrTarget === "string") {
|
||||
if (!instrumentationEnabled) {
|
||||
if (!profileFunctionFactory) {
|
||||
return voidMethodDecorator;
|
||||
}
|
||||
return profileMethodNamed(nameFnOrTarget);
|
||||
} else {
|
||||
if (!instrumentationEnabled) {
|
||||
if (!profileFunctionFactory) {
|
||||
return voidMethodDecorator;
|
||||
}
|
||||
return profileMethodUnnamed;
|
||||
@ -193,7 +210,6 @@ export function profile(nameFnOrTarget?: string | Function | Object, fnOrKey?: F
|
||||
export function dumpProfiles(): void {
|
||||
profileNames.forEach(function (name) {
|
||||
const info = timers[name];
|
||||
|
||||
if (info) {
|
||||
console.log("---- [" + name + "] STOP total: " + info.totalTime + " count:" + info.count);
|
||||
}
|
||||
@ -206,12 +222,11 @@ export function dumpProfiles(): void {
|
||||
export function resetProfiles(): void {
|
||||
profileNames.forEach(function (name) {
|
||||
const info = timers[name];
|
||||
|
||||
if (info) {
|
||||
if (!info.isRunning) {
|
||||
timers[name] = undefined;
|
||||
} else {
|
||||
if (info.runCount) {
|
||||
console.log("---- timer with name [" + name + "] is currently running and won't be reset");
|
||||
} else {
|
||||
timers[name] = undefined;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -3,7 +3,7 @@
|
||||
paddingLeftProperty, paddingTopProperty, paddingRightProperty, paddingBottomProperty,
|
||||
Length, zIndexProperty, textAlignmentProperty, TextAlignment
|
||||
} from "./button-common";
|
||||
|
||||
import { profile } from "../../profiling";
|
||||
import { TouchGestureEventData, GestureTypes, TouchAction } from "../gestures";
|
||||
|
||||
export * from "./button-common";
|
||||
@ -41,6 +41,7 @@ export class Button extends ButtonBase {
|
||||
|
||||
private _highlightedHandler: (args: TouchGestureEventData) => void;
|
||||
|
||||
@profile
|
||||
public createNativeView() {
|
||||
initializeClickListener();
|
||||
const button = new android.widget.Button(this._context);
|
||||
|
@ -6,6 +6,8 @@ import { ViewBase } from "../view-base";
|
||||
import { WrappedValue, PropertyChangeData } from "../../../data/observable";
|
||||
import { Style } from "../../styling/style";
|
||||
|
||||
import { profile } from "../../../profiling";
|
||||
|
||||
export { Style };
|
||||
|
||||
export const unsetValue: any = new Object();
|
||||
@ -964,7 +966,7 @@ function inheritableCssPropertyValuesOn(style: Style): Array<{ property: Inherit
|
||||
return array;
|
||||
}
|
||||
|
||||
export function initNativeView(view: ViewBase): void {
|
||||
export const initNativeView = profile('"properties".initNativeView', function initNativeView(view: ViewBase): void {
|
||||
let symbols = Object.getOwnPropertySymbols(view);
|
||||
for (let symbol of symbols) {
|
||||
const property: Property<any, any> = symbolPropertyMap[symbol];
|
||||
@ -1005,7 +1007,7 @@ export function initNativeView(view: ViewBase): void {
|
||||
view[property.setNative](value);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export function resetNativeView(view: ViewBase): void {
|
||||
let symbols = Object.getOwnPropertySymbols(view);
|
||||
|
@ -17,6 +17,8 @@ import * as types from "../../../utils/types";
|
||||
|
||||
import { Color } from "../../../color";
|
||||
|
||||
import { profile } from "../../../profiling";
|
||||
|
||||
export { isIOS, isAndroid, layout, Color };
|
||||
export * from "../bindable";
|
||||
export * from "../properties";
|
||||
@ -260,6 +262,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
this[name] = WrappedValue.unwrap(value);
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
this._isLoaded = true;
|
||||
this._loadEachChild();
|
||||
@ -273,6 +276,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
});
|
||||
}
|
||||
|
||||
@profile
|
||||
public onUnloaded() {
|
||||
this._unloadEachChild();
|
||||
this._isLoaded = false;
|
||||
@ -299,6 +303,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
});
|
||||
}
|
||||
|
||||
@profile
|
||||
public _applyStyleFromScope() {
|
||||
const scope = this._styleScope;
|
||||
if (scope) {
|
||||
@ -309,6 +314,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
}
|
||||
|
||||
// TODO: Make sure the state is set to null and this is called on unloaded to clean up change listeners...
|
||||
@profile
|
||||
_setCssState(next: ssm.CssState): void {
|
||||
const previous = this._cssState;
|
||||
this._cssState = next;
|
||||
@ -380,6 +386,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
private _invalidateCssHandler;
|
||||
private _invalidateCssHandlerSuspended: boolean;
|
||||
|
||||
@profile
|
||||
private applyCssState(): void {
|
||||
this._batchUpdate(() => {
|
||||
if (!this._cssState) {
|
||||
@ -412,6 +419,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
return allStates;
|
||||
}
|
||||
|
||||
@profile
|
||||
public addPseudoClass(name: string): void {
|
||||
let allStates = this.getAllAliasedStates(name);
|
||||
for (let i = 0; i < allStates.length; i++) {
|
||||
@ -422,6 +430,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public deletePseudoClass(name: string): void {
|
||||
let allStates = this.getAllAliasedStates(name);
|
||||
for (let i = 0; i < allStates.length; i++) {
|
||||
@ -432,6 +441,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
private _applyInlineStyle(inlineStyle) {
|
||||
if (typeof inlineStyle === "string") {
|
||||
try {
|
||||
@ -504,6 +514,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public requestLayout(): void {
|
||||
let parent = this.parent;
|
||||
if (parent) {
|
||||
@ -515,6 +526,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
//
|
||||
}
|
||||
|
||||
@profile
|
||||
public _addView(view: ViewBase, atIndex?: number) {
|
||||
if (traceEnabled()) {
|
||||
traceWrite(`${this}._addView(${view}, ${atIndex})`, traceCategories.ViewHierarchy);
|
||||
@ -535,6 +547,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
view._parentChanged(null);
|
||||
}
|
||||
|
||||
@profile
|
||||
private _setStyleScope(scope: ssm.StyleScope): void {
|
||||
this._styleScope = scope;
|
||||
this._applyStyleFromScope();
|
||||
@ -623,6 +636,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public _setupUI(context: android.content.Context, atIndex?: number, parentIsLoaded?: boolean) {
|
||||
traceNotifyEvent(this, "_setupUI");
|
||||
if (traceEnabled()) {
|
||||
@ -701,6 +715,7 @@ export abstract class ViewBase extends Observable implements ViewBaseDefinition
|
||||
});
|
||||
}
|
||||
|
||||
@profile
|
||||
public _tearDownUI(force?: boolean) {
|
||||
// No context means we are already teared down.
|
||||
if (!this._context) {
|
||||
|
@ -17,6 +17,7 @@ import {
|
||||
rotateProperty, scaleXProperty, scaleYProperty, translateXProperty, translateYProperty,
|
||||
zIndexProperty, backgroundInternalProperty
|
||||
} from "../../styling/style-properties";
|
||||
import { profile } from "../../../profiling";
|
||||
|
||||
export * from "./view-common";
|
||||
|
||||
@ -82,11 +83,13 @@ export class View extends ViewCommon {
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
this.setOnTouchListener();
|
||||
}
|
||||
|
||||
@profile
|
||||
public onUnloaded() {
|
||||
if (this.touchListenerIsSet) {
|
||||
this.nativeView.setOnTouchListener(null);
|
||||
@ -132,6 +135,7 @@ export class View extends ViewCommon {
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public requestLayout(): void {
|
||||
super.requestLayout();
|
||||
if (this.nativeView) {
|
||||
|
@ -6,7 +6,6 @@ import {
|
||||
ViewCommon, layout, isEnabledProperty, originXProperty, originYProperty, automationTextProperty, isUserInteractionEnabledProperty,
|
||||
traceEnabled, traceWrite, traceCategories
|
||||
} from "./view-common";
|
||||
|
||||
import {
|
||||
Visibility,
|
||||
visibilityProperty, opacityProperty,
|
||||
@ -14,6 +13,7 @@ import {
|
||||
translateXProperty, translateYProperty, zIndexProperty,
|
||||
backgroundInternalProperty, clipPathProperty
|
||||
} from "../../styling/style-properties";
|
||||
import { profile } from "../../../profiling";
|
||||
|
||||
export * from "./view-common";
|
||||
|
||||
@ -80,6 +80,7 @@ export class View extends ViewCommon {
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public layout(left: number, top: number, right: number, bottom: number): void {
|
||||
let { boundsChanged, sizeChanged } = this._setCurrentLayoutBounds(left, top, right, bottom);
|
||||
this.layoutNativeView(left, top, right, bottom);
|
||||
@ -100,6 +101,7 @@ export class View extends ViewCommon {
|
||||
this._privateFlags |= PFLAG_MEASURED_DIMENSION_SET;
|
||||
}
|
||||
|
||||
@profile
|
||||
public onMeasure(widthMeasureSpec: number, heightMeasureSpec: number): void {
|
||||
const view = this.nativeView;
|
||||
const width = layout.getMeasureSpecSize(widthMeasureSpec);
|
||||
|
@ -10,6 +10,8 @@ import { FrameBase, application, NavigationContext, stack, goBack, View, Observa
|
||||
import { DIALOG_FRAGMENT_TAG } from "../page/constants";
|
||||
import * as transitionModule from "../transition";
|
||||
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "./frame-common";
|
||||
|
||||
const HIDDEN = "_hidden";
|
||||
@ -117,6 +119,7 @@ export class Frame extends FrameBase {
|
||||
return this._android;
|
||||
}
|
||||
|
||||
@profile
|
||||
public _navigateCore(backstackEntry: BackstackEntry) {
|
||||
super._navigateCore(backstackEntry);
|
||||
|
||||
@ -631,6 +634,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
public entry: BackstackEntry;
|
||||
public clearHistory: boolean;
|
||||
|
||||
@profile
|
||||
public onHiddenChanged(fragment: android.app.Fragment, hidden: boolean, superFunc: Function): void {
|
||||
if (traceEnabled()) {
|
||||
traceWrite(`${fragment}.onHiddenChanged(${hidden})`, traceCategories.NativeLifecycle);
|
||||
@ -644,6 +648,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public onCreateAnimator(fragment: android.app.Fragment, transit: number, enter: boolean, nextAnim: number, superFunc: Function): android.animation.Animator {
|
||||
let nextAnimString: string;
|
||||
switch (nextAnim) {
|
||||
@ -665,6 +670,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
return animator;
|
||||
}
|
||||
|
||||
@profile
|
||||
public onCreate(fragment: android.app.Fragment, savedInstanceState: android.os.Bundle, superFunc: Function): void {
|
||||
if (traceEnabled()) {
|
||||
traceWrite(`${fragment}.onCreate(${savedInstanceState})`, traceCategories.NativeLifecycle);
|
||||
@ -687,6 +693,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public onCreateView(fragment: android.app.Fragment, inflater: android.view.LayoutInflater, container: android.view.ViewGroup, savedInstanceState: android.os.Bundle, superFunc: Function): android.view.View {
|
||||
if (traceEnabled()) {
|
||||
traceWrite(`${fragment}.onCreateView(inflater, container, ${savedInstanceState})`, traceCategories.NativeLifecycle);
|
||||
@ -709,6 +716,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
return page.nativeView;
|
||||
}
|
||||
|
||||
@profile
|
||||
public onSaveInstanceState(fragment: android.app.Fragment, outState: android.os.Bundle, superFunc: Function): void {
|
||||
if (traceEnabled()) {
|
||||
traceWrite(`${fragment}.onSaveInstanceState(${outState})`, traceCategories.NativeLifecycle);
|
||||
@ -719,6 +727,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public onDestroyView(fragment: android.app.Fragment, superFunc: Function): void {
|
||||
if (traceEnabled()) {
|
||||
traceWrite(`${fragment}.onDestroyView()`, traceCategories.NativeLifecycle);
|
||||
@ -728,6 +737,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
onFragmentHidden(fragment, true);
|
||||
}
|
||||
|
||||
@profile
|
||||
public onDestroy(fragment: android.app.Fragment, superFunc: Function): void {
|
||||
if (traceEnabled()) {
|
||||
traceWrite(`${fragment}.onDestroy()`, traceCategories.NativeLifecycle);
|
||||
@ -735,6 +745,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
superFunc.call(fragment);
|
||||
}
|
||||
|
||||
@profile
|
||||
public toStringOverride(fragment: android.app.Fragment, superFunc: Function): string {
|
||||
return `${fragment.getTag()}<${this.entry ? this.entry.resolvedPage : ""}>`;
|
||||
}
|
||||
@ -743,6 +754,7 @@ class FragmentCallbacksImplementation implements AndroidFragmentCallbacks {
|
||||
class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
||||
private _rootView: View;
|
||||
|
||||
@profile
|
||||
public onCreate(activity: android.app.Activity, savedInstanceState: android.os.Bundle, superFunc: Function): void {
|
||||
if (traceEnabled()) {
|
||||
traceWrite(`Activity.onCreate(${savedInstanceState})`, traceCategories.NativeLifecycle);
|
||||
@ -812,6 +824,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
||||
activityInitialized = true;
|
||||
}
|
||||
|
||||
@profile
|
||||
public onSaveInstanceState(activity: android.app.Activity, outState: android.os.Bundle, superFunc: Function): void {
|
||||
superFunc.call(activity, outState);
|
||||
let view = this._rootView;
|
||||
@ -820,6 +833,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public onStart(activity: any, superFunc: Function): void {
|
||||
superFunc.call(activity);
|
||||
|
||||
@ -832,6 +846,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public onStop(activity: any, superFunc: Function): void {
|
||||
superFunc.call(activity);
|
||||
|
||||
@ -844,6 +859,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public onDestroy(activity: any, superFunc: Function): void {
|
||||
let rootView = this._rootView;
|
||||
if (rootView && rootView._context) {
|
||||
@ -860,6 +876,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
||||
application.notify(exitArgs);
|
||||
}
|
||||
|
||||
@profile
|
||||
public onBackPressed(activity: any, superFunc: Function): void {
|
||||
if (traceEnabled()) {
|
||||
traceWrite("NativeScriptActivity.onBackPressed;", traceCategories.NativeLifecycle);
|
||||
@ -882,6 +899,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public onRequestPermissionsResult(activity: any, requestCode: number, permissions: Array<String>, grantResults: Array<number>, superFunc: Function): void {
|
||||
if (traceEnabled()) {
|
||||
traceWrite("NativeScriptActivity.onRequestPermissionsResult;", traceCategories.NativeLifecycle);
|
||||
@ -897,6 +915,7 @@ class ActivityCallbacksImplementation implements AndroidActivityCallbacks {
|
||||
});
|
||||
}
|
||||
|
||||
@profile
|
||||
public onActivityResult(activity: any, requestCode: number, resultCode: number, data: android.content.Intent, superFunc: Function): void {
|
||||
superFunc.call(activity, requestCode, resultCode, data);
|
||||
if (traceEnabled()) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Definitions.
|
||||
import { iOSFrame as iOSFrameDefinition, BackstackEntry, NavigationTransition } from ".";
|
||||
import { Page } from "../page";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
//Types.
|
||||
import { FrameBase, View, application, layout, traceEnabled, traceWrite, traceCategories, isCategorySet } from "./frame-common";
|
||||
@ -59,6 +60,7 @@ export class Frame extends FrameBase {
|
||||
});
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
|
||||
@ -78,6 +80,7 @@ export class Frame extends FrameBase {
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public _navigateCore(backstackEntry: BackstackEntry) {
|
||||
super._navigateCore(backstackEntry);
|
||||
|
||||
@ -491,6 +494,7 @@ class UINavigationControllerImpl extends UINavigationController {
|
||||
return this._owner.get();
|
||||
}
|
||||
|
||||
@profile
|
||||
public viewDidLoad(): void {
|
||||
super.viewDidLoad();
|
||||
let owner = this._owner.get();
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Label as LabelDefinition } from ".";
|
||||
import { TextBase, WhiteSpace, whiteSpaceProperty } from "../text-base";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "../text-base";
|
||||
|
||||
@ -15,6 +16,7 @@ export class Label extends TextBase implements LabelDefinition {
|
||||
this.style.whiteSpace = value ? "normal" : "nowrap";
|
||||
}
|
||||
|
||||
@profile
|
||||
public createNativeView() {
|
||||
if (!TextView) {
|
||||
TextView = android.widget.TextView;
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { ListPickerBase, Color, selectedIndexProperty, itemsProperty, backgroundColorProperty, colorProperty } from "./list-picker-common";
|
||||
import { ItemsSource } from ".";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "./list-picker-common";
|
||||
|
||||
@ -18,6 +19,7 @@ export class ListPicker extends ListPickerBase {
|
||||
this.nativeView = this._ios;
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
this._ios.delegate = this._delegate;
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
import { StackLayout } from "../layouts/stack-layout";
|
||||
import { ProxyViewContainer } from "../proxy-view-container";
|
||||
import { LayoutBase } from "../layouts/layout-base";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "./list-view-common";
|
||||
|
||||
@ -49,6 +50,7 @@ export class ListView extends ListViewBase {
|
||||
public _realizedItems = new Map<android.view.View, View>();
|
||||
public _realizedTemplates = new Map<string, Map<android.view.View, View>>();
|
||||
|
||||
@profile
|
||||
public createNativeView() {
|
||||
initializeItemClickListener();
|
||||
|
||||
@ -238,6 +240,7 @@ function ensureListViewAdapterClass() {
|
||||
return itemViewType;
|
||||
}
|
||||
|
||||
@profile
|
||||
public getView(index: number, convertView: android.view.View, parent: android.view.ViewGroup): android.view.View {
|
||||
//this.owner._dumpRealizedTemplates();
|
||||
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
import { StackLayout } from "../layouts/stack-layout";
|
||||
import { ProxyViewContainer } from "../proxy-view-container";
|
||||
import { ios } from "../../utils/utils";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "./list-view-common";
|
||||
|
||||
@ -225,6 +226,7 @@ export class ListView extends ListViewBase {
|
||||
this._ios.clipsToBounds = true;
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
if (this._isDataDirty) {
|
||||
|
@ -8,6 +8,7 @@ import { ActionBar } from "../action-bar";
|
||||
import { KeyframeAnimationInfo } from "../animation/keyframe-animation";
|
||||
import { StyleScope } from "../styling/style-scope";
|
||||
import { File, path, knownFolders } from "../../file-system";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "../content-view";
|
||||
|
||||
@ -93,6 +94,7 @@ export class PageBase extends ContentView implements PageDefinition {
|
||||
return this;
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded(): void {
|
||||
this._refreshCss();
|
||||
super.onLoaded();
|
||||
|
@ -3,6 +3,7 @@ import { ActionBar } from "../action-bar";
|
||||
import { GridLayout } from "../layouts/grid-layout";
|
||||
import { DIALOG_FRAGMENT_TAG } from "./constants";
|
||||
import { device } from "../../platform";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "./page-common";
|
||||
|
||||
@ -118,6 +119,7 @@ export class Page extends PageBase {
|
||||
return super._addViewToNativeVisualTree(child, atIndex);
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
if (this.actionBarHidden !== undefined) {
|
||||
|
@ -8,6 +8,7 @@ import { device } from "../../platform";
|
||||
// HACK: Webpack. Use a fully-qualified import to allow resolve.extensions(.ios.js) to
|
||||
// kick in. `../utils` doesn't seem to trigger the webpack extensions mechanism.
|
||||
import * as uiUtils from "tns-core-modules/ui/utils";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "./page-common";
|
||||
|
||||
@ -354,6 +355,7 @@ export class Page extends PageBase {
|
||||
this._addNativeView(newView);
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
// loaded/unloaded events are handled in page viewWillAppear/viewDidDisappear
|
||||
if (this._enableLoadedEvents) {
|
||||
|
@ -5,6 +5,7 @@ import { StackLayout } from "../layouts/stack-layout";
|
||||
import { ObservableArray, ChangedData } from "../../data/observable-array";
|
||||
import { addWeakEventListener, removeWeakEventListener } from "../core/weak-event-listener";
|
||||
import { parse } from "../builder";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "../layouts/layout-base";
|
||||
|
||||
@ -27,6 +28,7 @@ export class Repeater extends CustomLayoutView implements RepeaterDefinition {
|
||||
public itemTemplate: string | Template;
|
||||
public itemsLayout: LayoutBase;
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
if (this._isDirty) {
|
||||
this.refresh();
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { ScrollView as ScrollViewDefinition, Orientation } from ".";
|
||||
import { ContentView, Property, makeParser, makeValidator } from "../content-view";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "../content-view";
|
||||
|
||||
@ -27,6 +28,7 @@ export abstract class ScrollViewBase extends ContentView implements ScrollViewDe
|
||||
}
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
|
||||
|
@ -5,10 +5,10 @@ import {
|
||||
tabTextColorProperty, tabBackgroundColorProperty, selectedTabTextColorProperty, iosIconRenderingModeProperty,
|
||||
View, fontInternalProperty, layout, traceEnabled, traceWrite, traceCategories, Color, initNativeView
|
||||
} from "./tab-view-common"
|
||||
|
||||
import { textTransformProperty, TextTransform, getTransformedText } from "../text-base";
|
||||
import { fromFileOrResource } from "../../image-source";
|
||||
import { Page } from "../page";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "./tab-view-common";
|
||||
|
||||
@ -184,6 +184,7 @@ export class TabView extends TabViewBase {
|
||||
//This delegate is set on the last line of _addTabs method.
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
this._ios.delegate = this._delegate;
|
||||
|
@ -2,6 +2,7 @@
|
||||
TextFieldBase, secureProperty, textProperty, hintProperty, colorProperty, placeholderColorProperty,
|
||||
Length, paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty, _updateCharactersInRangeReplacementString, Color, layout
|
||||
} from "./text-field-common";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "./text-field-common";
|
||||
|
||||
@ -145,6 +146,7 @@ export class TextField extends TextFieldBase {
|
||||
this.nativeView = this._ios;
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
this._ios.delegate = this._delegate;
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
paddingTopProperty, paddingRightProperty, paddingBottomProperty, paddingLeftProperty,
|
||||
Length, _updateCharactersInRangeReplacementString, Color, layout
|
||||
} from "../editable-text-base";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "../editable-text-base";
|
||||
|
||||
@ -92,6 +93,7 @@ export class TextView extends EditableTextBase implements TextViewDefinition {
|
||||
this._delegate = UITextViewDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
this._ios.delegate = this._delegate;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { WebViewBase, knownFolders, traceWrite, traceEnabled, traceCategories, NavigationType } from "./web-view-common";
|
||||
import { profile } from "../../profiling";
|
||||
|
||||
export * from "./web-view-common";
|
||||
|
||||
@ -91,6 +92,7 @@ export class WebView extends WebViewBase {
|
||||
this._delegate = UIWebViewDelegateImpl.initWithOwner(new WeakRef(this));
|
||||
}
|
||||
|
||||
@profile
|
||||
public onLoaded() {
|
||||
super.onLoaded();
|
||||
this._ios.delegate = this._delegate;
|
||||
|
Reference in New Issue
Block a user