Skip to content

Commit

Permalink
feat: support dedicated thread mode in rust.
Browse files Browse the repository at this point in the history
  • Loading branch information
andycall committed Nov 9, 2024
1 parent 8457894 commit e113768
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 13 deletions.
4 changes: 4 additions & 0 deletions bridge/core/api/executing_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ WebFValue<SharedExceptionState, ExceptionStatePublicMethods> ExecutingContextWeb
ExceptionState::publicMethodPointer(), nullptr);
}

void ExecutingContextWebFMethods::FinishRecordingUIOperations(webf::ExecutingContext* context) {
context->uiCommandBuffer()->AddCommand(UICommand::kFinishRecordingCommand, nullptr, nullptr, nullptr, false);
}

} // namespace webf
1 change: 1 addition & 0 deletions bridge/core/executing_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ ExecutingContext::ExecutingContext(DartIsolateContext* dart_isolate_context,
ExecutingContext::~ExecutingContext() {
is_context_valid_ = false;
valid_contexts[context_id_] = false;
executing_context_status_->disposed = true;

// Check if current context have unhandled exceptions.
JSValue exception = JS_GetException(script_state_.ctx());
Expand Down
2 changes: 2 additions & 0 deletions bridge/core/executing_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ class ExecutingContext {
assert(dart_isolate_context_->valid());
return dart_isolate_context_->dartMethodPtr();
}
FORCE_INLINE WebFValueStatus* status() const { return executing_context_status_; }
FORCE_INLINE ExecutingContextWebFMethods* publicMethodPtr() const { return public_method_ptr_.get(); }
FORCE_INLINE bool isDedicated() { return is_dedicated_; }
FORCE_INLINE std::chrono::time_point<std::chrono::system_clock> timeOrigin() const { return time_origin_; }
Expand Down Expand Up @@ -216,6 +217,7 @@ class ExecutingContext {
RejectedPromises rejected_promises_;
MemberMutationScope* active_mutation_scope{nullptr};
std::unordered_set<ScriptWrappable*> active_wrappers_;
WebFValueStatus* executing_context_status_{new WebFValueStatus()};
bool is_dedicated_;

// Rust methods ptr should keep alive when ExecutingContext is disposing.
Expand Down
8 changes: 2 additions & 6 deletions bridge/core/native/native_loader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,13 @@ static void ExecuteNativeLibrary(PluginLibraryEntryPoint entry_point,
native_library_load_context->promise_resolver->Reject(exception_value);
JS_FreeValue(context->ctx(), exception_value);
} else {
auto exec_status = new WebFValueStatus();
auto entry_data = WebFValue<ExecutingContext, ExecutingContextWebFMethods>{
native_library_load_context->context, native_library_load_context->context->publicMethodPtr(), exec_status};
WEBF_LOG(VERBOSE) << " entry_point: " << entry_point;
native_library_load_context->context, native_library_load_context->context->publicMethodPtr(),
native_library_load_context->context->status()};
void* result = entry_point(entry_data);
WEBF_LOG(VERBOSE) << " result: " << result;
}

delete native_library_load_context;

WEBF_LOG(VERBOSE) << " EXEC LIB";
}

static void HandleNativeLibraryLoad(PluginLibraryEntryPoint entry_point,
Expand Down
3 changes: 3 additions & 0 deletions bridge/include/plugin_api/executing_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,21 @@ class Window;
using PublicContextGetDocument = WebFValue<Document, DocumentPublicMethods> (*)(ExecutingContext*);
using PublicContextGetWindow = WebFValue<Window, WindowPublicMethods> (*)(ExecutingContext*);
using PublicContextGetExceptionState = WebFValue<SharedExceptionState, ExceptionStatePublicMethods> (*)();
using PublicFinishRecordingUIOperations = void (*)(ExecutingContext* context);

// Memory aligned and readable from WebF side.
// Only C type member can be included in this class, any C++ type and classes can is not allowed to use here.
struct ExecutingContextWebFMethods {
static WebFValue<Document, DocumentPublicMethods> document(ExecutingContext* context);
static WebFValue<Window, WindowPublicMethods> window(ExecutingContext* context);
static WebFValue<SharedExceptionState, ExceptionStatePublicMethods> CreateExceptionState();
static void FinishRecordingUIOperations(ExecutingContext* context);

double version{1.0};
PublicContextGetDocument rust_context_get_document_{document};
PublicContextGetWindow rust_context_get_window_{window};
PublicContextGetExceptionState rust_context_get_exception_state_{CreateExceptionState};
PublicFinishRecordingUIOperations finish_recording_ui_operations{FinishRecordingUIOperations};
};

} // namespace webf
Expand Down
5 changes: 4 additions & 1 deletion bridge/rusty_webf_sys/src/event_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ struct EventCallbackContext {
struct EventCallbackContextData {
executing_context_ptr: *const OpaquePtr,
executing_context_method_pointer: *const ExecutingContextRustMethods,
executing_context_status: *const RustValueStatus,
func: EventListenerCallback,
}

Expand Down Expand Up @@ -112,7 +113,7 @@ extern "C" fn handle_event_listener_callback(
unsafe {
let func = &(*callback_context_data).func;
let callback_data = &(*callback_context_data);
let executing_context = ExecutingContext::initialize(callback_data.executing_context_ptr, callback_data.executing_context_method_pointer);
let executing_context = ExecutingContext::initialize(callback_data.executing_context_ptr, callback_data.executing_context_method_pointer, callback_data.executing_context_status);
let event = Event::initialize(event_ptr, &executing_context, event_method_pointer, status);
func(&event);
}
Expand Down Expand Up @@ -148,6 +149,7 @@ impl EventTarget {
let callback_context_data = Box::new(EventCallbackContextData {
executing_context_ptr: self.context().ptr,
executing_context_method_pointer: self.context().method_pointer(),
executing_context_status: self.context().status,
func: callback,
});
let callback_context_data_ptr = Box::into_raw(callback_context_data);
Expand Down Expand Up @@ -178,6 +180,7 @@ impl EventTarget {
let callback_context_data = Box::new(EventCallbackContextData {
executing_context_ptr: self.context().ptr,
executing_context_method_pointer: self.context().method_pointer(),
executing_context_status: self.context().status,
func: callback,
});
let callback_context_data_ptr = Box::into_raw(callback_context_data);
Expand Down
21 changes: 17 additions & 4 deletions bridge/rusty_webf_sys/src/executing_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use libc::c_uint;
use crate::document::{Document, DocumentRustMethods};
use crate::event_target::EventTargetMethods;
use crate::exception_state::{ExceptionState, ExceptionStateRustMethods};
use crate::{OpaquePtr, RustValue};
use crate::{OpaquePtr, RustValue, RustValueStatus};
use crate::custom_event::{CustomEvent, CustomEventRustMethods};
use crate::window::{Window, WindowRustMethods};

Expand All @@ -19,7 +19,7 @@ pub struct ExecutingContextRustMethods {
pub get_document: extern "C" fn(*const OpaquePtr) -> RustValue<DocumentRustMethods>,
pub get_window: extern "C" fn(*const OpaquePtr) -> RustValue<WindowRustMethods>,
pub create_exception_state: extern "C" fn() -> RustValue<ExceptionStateRustMethods>,
pub create_custom_event: extern "C" fn() -> RustValue<CustomEventRustMethods>,
pub finish_recording_ui_operations: extern "C" fn(executing_context: *const OpaquePtr) -> c_void,
}

/// An environment contains all the necessary running states of a web page.
Expand All @@ -41,13 +41,15 @@ pub struct ExecutingContext {
pub ptr: *const OpaquePtr,
// Methods available for export from the C++ world for use.
method_pointer: *const ExecutingContextRustMethods,
pub status: *const RustValueStatus,
}

impl ExecutingContext {
pub fn initialize(ptr: *const OpaquePtr, method_pointer: *const ExecutingContextRustMethods) -> ExecutingContext {
pub fn initialize(ptr: *const OpaquePtr, method_pointer: *const ExecutingContextRustMethods, status: *const RustValueStatus) -> ExecutingContext {
ExecutingContext {
ptr,
method_pointer
method_pointer,
status
}
}

Expand Down Expand Up @@ -80,3 +82,14 @@ impl ExecutingContext {
ExceptionState::initialize(result.value, result.method_pointer)
}
}

impl Drop for ExecutingContext {
fn drop(&mut self) {
unsafe {
if (*((*self).status)).disposed {
return;
};
((*self.method_pointer).finish_recording_ui_operations)(self.ptr);
}
}
}
2 changes: 1 addition & 1 deletion bridge/rusty_webf_sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub struct RustValue<T> {
}

pub fn initialize_webf_api(value: RustValue<ExecutingContextRustMethods>) -> ExecutingContext {
ExecutingContext::initialize(value.value, value.method_pointer)
ExecutingContext::initialize(value.value, value.method_pointer, value.status)
}

// This is the entrypoint when your rust app compiled as dynamic library and loaded & executed by WebF.
Expand Down
1 change: 0 additions & 1 deletion webf/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ class FirstPageState extends State<FirstPage> {
super.didChangeDependencies();
controller = WebFController(
context,
runningThread: FlutterUIThread(),
devToolsService: ChromeDevToolsService(),
);
controller.preload(WebFBundle.fromUrl('assets:assets/bundle.html'));
Expand Down

0 comments on commit e113768

Please sign in to comment.