-
-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathNativeScript.mm
More file actions
137 lines (112 loc) · 3.95 KB
/
NativeScript.mm
File metadata and controls
137 lines (112 loc) · 3.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include "NativeScript.h"
#include <Foundation/Foundation.h>
#include "inspector/JsV8InspectorClient.h"
#include "runtime/Console.h"
#include "runtime/Helpers.h"
#include "runtime/Runtime.h"
#include "runtime/RuntimeConfig.h"
#include "runtime/Tasks.h"
using namespace v8;
using namespace tns;
namespace tns {
// External flag from Runtime.mm to track JavaScript errors
extern bool jsErrorOccurred;
}
@implementation Config
@synthesize BaseDir;
@synthesize ApplicationPath;
@synthesize MetadataPtr;
@synthesize IsDebug;
@end
@implementation NativeScript
extern char defaultStartOfMetadataSection __asm("section$start$__DATA$__TNSMetadata");
- (void)runScriptString:(NSString*)script runLoop:(BOOL)runLoop {
std::string cppString = std::string([script UTF8String]);
runtime_->RunScript(cppString);
if (runLoop) {
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true);
}
tns::Tasks::Drain();
}
std::unique_ptr<Runtime> runtime_;
- (void)runMainApplication {
runtime_->RunMainScript();
// In debug mode, if JavaScript errors occurred, keep the app alive indefinitely
// This prevents iOS from terminating the app and allows hot-reload to work
if (RuntimeConfig.IsDebug && jsErrorOccurred) {
// Log(@"Debug mode - JavaScript errors detected, entering infinite run loop to prevent app termination");
while (true) {
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, true);
tns::Tasks::Drain();
}
// Note: This line is never reached in debug mode with errors
}
// Normal execution path (no errors or release mode)
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true);
tns::Tasks::Drain();
}
- (bool)liveSync {
if (runtime_ == nullptr) {
return false;
}
Isolate* isolate = runtime_->GetIsolate();
return tns::LiveSync(isolate);
}
- (void)shutdownRuntime {
if (RuntimeConfig.IsDebug) {
Console::DetachInspectorClient();
}
tns::Tasks::ClearTasks();
if (runtime_ != nullptr) {
runtime_ = nullptr;
}
}
- (instancetype)initializeWithConfig:(Config*)config {
if (self = [super init]) {
RuntimeConfig.BaseDir = [config.BaseDir UTF8String];
if (config.ApplicationPath != nil) {
RuntimeConfig.ApplicationPath =
[[config.BaseDir stringByAppendingPathComponent:config.ApplicationPath] UTF8String];
} else {
RuntimeConfig.ApplicationPath =
[[config.BaseDir stringByAppendingPathComponent:@"app"] UTF8String];
}
if (config.MetadataPtr != nil) {
RuntimeConfig.MetadataPtr = [config MetadataPtr];
} else {
RuntimeConfig.MetadataPtr = &defaultStartOfMetadataSection;
}
RuntimeConfig.IsDebug = [config IsDebug];
RuntimeConfig.LogToSystemConsole = [config LogToSystemConsole];
Runtime::Initialize();
runtime_ = nullptr;
runtime_ = std::make_unique<Runtime>();
std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
Isolate* isolate = runtime_->CreateIsolate();
v8::Locker l(isolate);
runtime_->Init(isolate);
std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
printf("Runtime initialization took %llims (version %s, V8 version %s)\n", duration,
NATIVESCRIPT_VERSION, V8::GetVersion());
if (config.IsDebug) {
Isolate::Scope isolate_scope(isolate);
HandleScope handle_scope(isolate);
v8_inspector::JsV8InspectorClient* inspectorClient =
new v8_inspector::JsV8InspectorClient(runtime_.get());
inspectorClient->init();
inspectorClient->registerModules();
inspectorClient->connect([config ArgumentsCount], [config Arguments]);
Console::AttachInspectorClient(inspectorClient);
}
}
return self;
}
- (instancetype)initWithConfig:(Config*)config {
return [self initializeWithConfig:config];
}
- (void)restartWithConfig:(Config*)config {
[self shutdownRuntime];
[self initializeWithConfig:config];
}
@end