mirror of
https://github.com/R0m1k3/xtremflow.git
synced 2026-10-23 15:08:07 +02:00
chore: remove Windows platform files - focus on web only
This commit is contained in:
1 parent
576c5ee7df
commit
3486e15334
69 files changed
-5667
No files matched your search
@@ -1,17 +0,0 @@
|
|||||||
flutter/ephemeral/
|
|
||||||
|
|
||||||
# Visual Studio user-specific files.
|
|
||||||
*.suo
|
|
||||||
*.user
|
|
||||||
*.userosscache
|
|
||||||
*.sln.docstates
|
|
||||||
|
|
||||||
# Visual Studio build-related files.
|
|
||||||
x64/
|
|
||||||
x86/
|
|
||||||
|
|
||||||
# Visual Studio cache files
|
|
||||||
# files ending in .cache can be ignored
|
|
||||||
*.[Cc]ache
|
|
||||||
# but keep track of directories ending in .cache
|
|
||||||
!*.[Cc]ache/
|
|
||||||
@@ -1,108 +0,0 @@
|
|||||||
# Project-level configuration.
|
|
||||||
cmake_minimum_required(VERSION 3.14)
|
|
||||||
project(xtremflow LANGUAGES CXX)
|
|
||||||
|
|
||||||
# The name of the executable created for the application. Change this to change
|
|
||||||
# the on-disk name of your application.
|
|
||||||
set(BINARY_NAME "xtremflow")
|
|
||||||
|
|
||||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
|
||||||
# versions of CMake.
|
|
||||||
cmake_policy(VERSION 3.14...3.25)
|
|
||||||
|
|
||||||
# Define build configuration option.
|
|
||||||
get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
|
|
||||||
if(IS_MULTICONFIG)
|
|
||||||
set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
|
|
||||||
CACHE STRING "" FORCE)
|
|
||||||
else()
|
|
||||||
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
|
|
||||||
set(CMAKE_BUILD_TYPE "Debug" CACHE
|
|
||||||
STRING "Flutter build mode" FORCE)
|
|
||||||
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
|
|
||||||
"Debug" "Profile" "Release")
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
# Define settings for the Profile build mode.
|
|
||||||
set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
|
|
||||||
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
|
|
||||||
set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
|
|
||||||
set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
|
|
||||||
|
|
||||||
# Use Unicode for all projects.
|
|
||||||
add_definitions(-DUNICODE -D_UNICODE)
|
|
||||||
|
|
||||||
# Compilation settings that should be applied to most targets.
|
|
||||||
#
|
|
||||||
# Be cautious about adding new options here, as plugins use this function by
|
|
||||||
# default. In most cases, you should add new options to specific targets instead
|
|
||||||
# of modifying this function.
|
|
||||||
function(APPLY_STANDARD_SETTINGS TARGET)
|
|
||||||
target_compile_features(${TARGET} PUBLIC cxx_std_17)
|
|
||||||
target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
|
|
||||||
target_compile_options(${TARGET} PRIVATE /EHsc)
|
|
||||||
target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
|
|
||||||
target_compile_definitions(${TARGET} PRIVATE "$<$<CONFIG:Debug>:_DEBUG>")
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
# Flutter library and tool build rules.
|
|
||||||
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
|
|
||||||
add_subdirectory(${FLUTTER_MANAGED_DIR})
|
|
||||||
|
|
||||||
# Application build; see runner/CMakeLists.txt.
|
|
||||||
add_subdirectory("runner")
|
|
||||||
|
|
||||||
|
|
||||||
# Generated plugin build rules, which manage building the plugins and adding
|
|
||||||
# them to the application.
|
|
||||||
include(flutter/generated_plugins.cmake)
|
|
||||||
|
|
||||||
|
|
||||||
# === Installation ===
|
|
||||||
# Support files are copied into place next to the executable, so that it can
|
|
||||||
# run in place. This is done instead of making a separate bundle (as on Linux)
|
|
||||||
# so that building and running from within Visual Studio will work.
|
|
||||||
set(BUILD_BUNDLE_DIR "$<TARGET_FILE_DIR:${BINARY_NAME}>")
|
|
||||||
# Make the "install" step default, as it's required to run.
|
|
||||||
set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
|
|
||||||
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
|
||||||
set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
|
|
||||||
set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
|
|
||||||
|
|
||||||
install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
if(PLUGIN_BUNDLED_LIBRARIES)
|
|
||||||
install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
|
|
||||||
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Copy the native assets provided by the build.dart from all packages.
|
|
||||||
set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/")
|
|
||||||
install(DIRECTORY "${NATIVE_ASSETS_DIR}"
|
|
||||||
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
|
|
||||||
COMPONENT Runtime)
|
|
||||||
|
|
||||||
# Fully re-copy the assets directory on each build to avoid having stale files
|
|
||||||
# from a previous install.
|
|
||||||
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
|
|
||||||
install(CODE "
|
|
||||||
file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
|
|
||||||
" COMPONENT Runtime)
|
|
||||||
install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
|
|
||||||
DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
|
|
||||||
|
|
||||||
# Install the AOT library on non-Debug builds only.
|
|
||||||
install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
|
|
||||||
CONFIGURATIONS Profile;Release
|
|
||||||
COMPONENT Runtime)
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
# This file controls Flutter-level build steps. It should not be edited.
|
|
||||||
cmake_minimum_required(VERSION 3.14)
|
|
||||||
|
|
||||||
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
|
|
||||||
|
|
||||||
# Configuration provided via flutter tool.
|
|
||||||
include(${EPHEMERAL_DIR}/generated_config.cmake)
|
|
||||||
|
|
||||||
# TODO: Move the rest of this into files in ephemeral. See
|
|
||||||
# https://github.com/flutter/flutter/issues/57146.
|
|
||||||
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
|
|
||||||
|
|
||||||
# Set fallback configurations for older versions of the flutter tool.
|
|
||||||
if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
|
|
||||||
set(FLUTTER_TARGET_PLATFORM "windows-x64")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# === Flutter Library ===
|
|
||||||
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
|
|
||||||
|
|
||||||
# Published to parent scope for install step.
|
|
||||||
set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
|
|
||||||
set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
|
|
||||||
set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
|
|
||||||
set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE)
|
|
||||||
|
|
||||||
list(APPEND FLUTTER_LIBRARY_HEADERS
|
|
||||||
"flutter_export.h"
|
|
||||||
"flutter_windows.h"
|
|
||||||
"flutter_messenger.h"
|
|
||||||
"flutter_plugin_registrar.h"
|
|
||||||
"flutter_texture_registrar.h"
|
|
||||||
)
|
|
||||||
list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/")
|
|
||||||
add_library(flutter INTERFACE)
|
|
||||||
target_include_directories(flutter INTERFACE
|
|
||||||
"${EPHEMERAL_DIR}"
|
|
||||||
)
|
|
||||||
target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib")
|
|
||||||
add_dependencies(flutter flutter_assemble)
|
|
||||||
|
|
||||||
# === Wrapper ===
|
|
||||||
list(APPEND CPP_WRAPPER_SOURCES_CORE
|
|
||||||
"core_implementations.cc"
|
|
||||||
"standard_codec.cc"
|
|
||||||
)
|
|
||||||
list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/")
|
|
||||||
list(APPEND CPP_WRAPPER_SOURCES_PLUGIN
|
|
||||||
"plugin_registrar.cc"
|
|
||||||
)
|
|
||||||
list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/")
|
|
||||||
list(APPEND CPP_WRAPPER_SOURCES_APP
|
|
||||||
"flutter_engine.cc"
|
|
||||||
"flutter_view_controller.cc"
|
|
||||||
)
|
|
||||||
list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/")
|
|
||||||
|
|
||||||
# Wrapper sources needed for a plugin.
|
|
||||||
add_library(flutter_wrapper_plugin STATIC
|
|
||||||
${CPP_WRAPPER_SOURCES_CORE}
|
|
||||||
${CPP_WRAPPER_SOURCES_PLUGIN}
|
|
||||||
)
|
|
||||||
apply_standard_settings(flutter_wrapper_plugin)
|
|
||||||
set_target_properties(flutter_wrapper_plugin PROPERTIES
|
|
||||||
POSITION_INDEPENDENT_CODE ON)
|
|
||||||
set_target_properties(flutter_wrapper_plugin PROPERTIES
|
|
||||||
CXX_VISIBILITY_PRESET hidden)
|
|
||||||
target_link_libraries(flutter_wrapper_plugin PUBLIC flutter)
|
|
||||||
target_include_directories(flutter_wrapper_plugin PUBLIC
|
|
||||||
"${WRAPPER_ROOT}/include"
|
|
||||||
)
|
|
||||||
add_dependencies(flutter_wrapper_plugin flutter_assemble)
|
|
||||||
|
|
||||||
# Wrapper sources needed for the runner.
|
|
||||||
add_library(flutter_wrapper_app STATIC
|
|
||||||
${CPP_WRAPPER_SOURCES_CORE}
|
|
||||||
${CPP_WRAPPER_SOURCES_APP}
|
|
||||||
)
|
|
||||||
apply_standard_settings(flutter_wrapper_app)
|
|
||||||
target_link_libraries(flutter_wrapper_app PUBLIC flutter)
|
|
||||||
target_include_directories(flutter_wrapper_app PUBLIC
|
|
||||||
"${WRAPPER_ROOT}/include"
|
|
||||||
)
|
|
||||||
add_dependencies(flutter_wrapper_app flutter_assemble)
|
|
||||||
|
|
||||||
# === Flutter tool backend ===
|
|
||||||
# _phony_ is a non-existent file to force this command to run every time,
|
|
||||||
# since currently there's no way to get a full input/output list from the
|
|
||||||
# flutter tool.
|
|
||||||
set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
|
|
||||||
set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE)
|
|
||||||
add_custom_command(
|
|
||||||
OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
|
|
||||||
${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
|
|
||||||
${CPP_WRAPPER_SOURCES_APP}
|
|
||||||
${PHONY_OUTPUT}
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E env
|
|
||||||
${FLUTTER_TOOL_ENVIRONMENT}
|
|
||||||
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
|
|
||||||
${FLUTTER_TARGET_PLATFORM} $<CONFIG>
|
|
||||||
VERBATIM
|
|
||||||
)
|
|
||||||
add_custom_target(flutter_assemble DEPENDS
|
|
||||||
"${FLUTTER_LIBRARY}"
|
|
||||||
${FLUTTER_LIBRARY_HEADERS}
|
|
||||||
${CPP_WRAPPER_SOURCES_CORE}
|
|
||||||
${CPP_WRAPPER_SOURCES_PLUGIN}
|
|
||||||
${CPP_WRAPPER_SOURCES_APP}
|
|
||||||
)
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
C:/Users/Jacques/AppData/Local/Pub/Cache/hosted/pub.dev/package_info_plus-9.0.0/
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
C:/Users/Jacques/AppData/Local/Pub/Cache/hosted/pub.dev/path_provider_windows-2.3.0/
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
C:/Users/Jacques/AppData/Local/Pub/Cache/hosted/pub.dev/shared_preferences_windows-2.4.1/
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
C:/Users/Jacques/AppData/Local/Pub/Cache/hosted/pub.dev/video_player_win-3.2.2/
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
C:/Users/Jacques/AppData/Local/Pub/Cache/hosted/pub.dev/wakelock_plus-1.4.0/
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_BINARY_MESSENGER_IMPL_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_BINARY_MESSENGER_IMPL_H_
|
|
||||||
|
|
||||||
#include <flutter_messenger.h>
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "include/flutter/binary_messenger.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// Wrapper around a FlutterDesktopMessengerRef that implements the
|
|
||||||
// BinaryMessenger API.
|
|
||||||
class BinaryMessengerImpl : public BinaryMessenger {
|
|
||||||
public:
|
|
||||||
explicit BinaryMessengerImpl(FlutterDesktopMessengerRef core_messenger);
|
|
||||||
|
|
||||||
virtual ~BinaryMessengerImpl();
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
BinaryMessengerImpl(BinaryMessengerImpl const&) = delete;
|
|
||||||
BinaryMessengerImpl& operator=(BinaryMessengerImpl const&) = delete;
|
|
||||||
|
|
||||||
// |flutter::BinaryMessenger|
|
|
||||||
void Send(const std::string& channel,
|
|
||||||
const uint8_t* message,
|
|
||||||
size_t message_size,
|
|
||||||
BinaryReply reply) const override;
|
|
||||||
|
|
||||||
// |flutter::BinaryMessenger|
|
|
||||||
void SetMessageHandler(const std::string& channel,
|
|
||||||
BinaryMessageHandler handler) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Handle for interacting with the C API.
|
|
||||||
FlutterDesktopMessengerRef messenger_;
|
|
||||||
|
|
||||||
// A map from channel names to the BinaryMessageHandler that should be called
|
|
||||||
// for incoming messages on that channel.
|
|
||||||
std::map<std::string, BinaryMessageHandler> handlers_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_BINARY_MESSENGER_IMPL_H_
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_BYTE_BUFFER_STREAMS_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_BYTE_BUFFER_STREAMS_H_
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "include/flutter/byte_streams.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// Implementation of ByteStreamReader base on a byte array.
|
|
||||||
class ByteBufferStreamReader : public ByteStreamReader {
|
|
||||||
public:
|
|
||||||
// Createa a reader reading from |bytes|, which must have a length of |size|.
|
|
||||||
// |bytes| must remain valid for the lifetime of this object.
|
|
||||||
explicit ByteBufferStreamReader(const uint8_t* bytes, size_t size)
|
|
||||||
: bytes_(bytes), size_(size) {}
|
|
||||||
|
|
||||||
virtual ~ByteBufferStreamReader() = default;
|
|
||||||
|
|
||||||
// |ByteStreamReader|
|
|
||||||
uint8_t ReadByte() override {
|
|
||||||
if (location_ >= size_) {
|
|
||||||
std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return bytes_[location_++];
|
|
||||||
}
|
|
||||||
|
|
||||||
// |ByteStreamReader|
|
|
||||||
void ReadBytes(uint8_t* buffer, size_t length) override {
|
|
||||||
if (location_ + length > size_) {
|
|
||||||
std::cerr << "Invalid read in StandardCodecByteStreamReader" << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::memcpy(buffer, &bytes_[location_], length);
|
|
||||||
location_ += length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// |ByteStreamReader|
|
|
||||||
void ReadAlignment(uint8_t alignment) override {
|
|
||||||
uint8_t mod = location_ % alignment;
|
|
||||||
if (mod) {
|
|
||||||
location_ += alignment - mod;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The buffer to read from.
|
|
||||||
const uint8_t* bytes_;
|
|
||||||
// The total size of the buffer.
|
|
||||||
size_t size_;
|
|
||||||
// The current read location.
|
|
||||||
size_t location_ = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Implementation of ByteStreamWriter based on a byte array.
|
|
||||||
class ByteBufferStreamWriter : public ByteStreamWriter {
|
|
||||||
public:
|
|
||||||
// Creates a writer that writes into |buffer|.
|
|
||||||
// |buffer| must remain valid for the lifetime of this object.
|
|
||||||
explicit ByteBufferStreamWriter(std::vector<uint8_t>* buffer)
|
|
||||||
: bytes_(buffer) {
|
|
||||||
assert(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~ByteBufferStreamWriter() = default;
|
|
||||||
|
|
||||||
// |ByteStreamWriter|
|
|
||||||
void WriteByte(uint8_t byte) { bytes_->push_back(byte); }
|
|
||||||
|
|
||||||
// |ByteStreamWriter|
|
|
||||||
void WriteBytes(const uint8_t* bytes, size_t length) {
|
|
||||||
assert(length > 0);
|
|
||||||
bytes_->insert(bytes_->end(), bytes, bytes + length);
|
|
||||||
}
|
|
||||||
|
|
||||||
// |ByteStreamWriter|
|
|
||||||
void WriteAlignment(uint8_t alignment) {
|
|
||||||
uint8_t mod = bytes_->size() % alignment;
|
|
||||||
if (mod) {
|
|
||||||
for (int i = 0; i < alignment - mod; ++i) {
|
|
||||||
WriteByte(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The buffer to write to.
|
|
||||||
std::vector<uint8_t>* bytes_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_BYTE_BUFFER_STREAMS_H_
|
|
||||||
@@ -1,284 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// This file contains the implementations of any class in the wrapper that
|
|
||||||
// - is not fully inline, and
|
|
||||||
// - is necessary for all clients of the wrapper (either app or plugin).
|
|
||||||
// It exists instead of the usual structure of having some_class_name.cc files
|
|
||||||
// so that changes to the set of things that need non-header implementations
|
|
||||||
// are not breaking changes for the template.
|
|
||||||
//
|
|
||||||
// If https://github.com/flutter/flutter/issues/57146 is fixed, this can be
|
|
||||||
// removed in favor of the normal structure since templates will no longer
|
|
||||||
// manually include files.
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <iostream>
|
|
||||||
#include <variant>
|
|
||||||
|
|
||||||
#include "binary_messenger_impl.h"
|
|
||||||
#include "include/flutter/engine_method_result.h"
|
|
||||||
#include "include/flutter/method_channel.h"
|
|
||||||
#include "include/flutter/standard_method_codec.h"
|
|
||||||
#include "texture_registrar_impl.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// ========== binary_messenger_impl.h ==========
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
using FlutterDesktopMessengerScopedLock =
|
|
||||||
std::unique_ptr<FlutterDesktopMessenger,
|
|
||||||
decltype(&FlutterDesktopMessengerUnlock)>;
|
|
||||||
|
|
||||||
// Passes |message| to |user_data|, which must be a BinaryMessageHandler, along
|
|
||||||
// with a BinaryReply that will send a response on |message|'s response handle.
|
|
||||||
//
|
|
||||||
// This serves as an adaptor between the function-pointer-based message callback
|
|
||||||
// interface provided by the C API and the std::function-based message handler
|
|
||||||
// interface of BinaryMessenger.
|
|
||||||
void ForwardToHandler(FlutterDesktopMessengerRef messenger,
|
|
||||||
const FlutterDesktopMessage* message,
|
|
||||||
void* user_data) {
|
|
||||||
auto* response_handle = message->response_handle;
|
|
||||||
auto messenger_ptr = std::shared_ptr<FlutterDesktopMessenger>(
|
|
||||||
FlutterDesktopMessengerAddRef(messenger),
|
|
||||||
&FlutterDesktopMessengerRelease);
|
|
||||||
BinaryReply reply_handler = [messenger_ptr, response_handle](
|
|
||||||
const uint8_t* reply,
|
|
||||||
size_t reply_size) mutable {
|
|
||||||
// Note: This lambda can be called on any thread.
|
|
||||||
auto lock = FlutterDesktopMessengerScopedLock(
|
|
||||||
FlutterDesktopMessengerLock(messenger_ptr.get()),
|
|
||||||
&FlutterDesktopMessengerUnlock);
|
|
||||||
if (!FlutterDesktopMessengerIsAvailable(messenger_ptr.get())) {
|
|
||||||
// Drop reply if it comes in after the engine is destroyed.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!response_handle) {
|
|
||||||
std::cerr << "Error: Response can be set only once. Ignoring "
|
|
||||||
"duplicate response."
|
|
||||||
<< std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FlutterDesktopMessengerSendResponse(messenger_ptr.get(), response_handle,
|
|
||||||
reply, reply_size);
|
|
||||||
// The engine frees the response handle once
|
|
||||||
// FlutterDesktopSendMessageResponse is called.
|
|
||||||
response_handle = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
const BinaryMessageHandler& message_handler =
|
|
||||||
*static_cast<BinaryMessageHandler*>(user_data);
|
|
||||||
|
|
||||||
message_handler(message->message, message->message_size,
|
|
||||||
std::move(reply_handler));
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
BinaryMessengerImpl::BinaryMessengerImpl(
|
|
||||||
FlutterDesktopMessengerRef core_messenger)
|
|
||||||
: messenger_(core_messenger) {}
|
|
||||||
|
|
||||||
BinaryMessengerImpl::~BinaryMessengerImpl() = default;
|
|
||||||
|
|
||||||
void BinaryMessengerImpl::Send(const std::string& channel,
|
|
||||||
const uint8_t* message,
|
|
||||||
size_t message_size,
|
|
||||||
BinaryReply reply) const {
|
|
||||||
if (reply == nullptr) {
|
|
||||||
FlutterDesktopMessengerSend(messenger_, channel.c_str(), message,
|
|
||||||
message_size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
struct Captures {
|
|
||||||
BinaryReply reply;
|
|
||||||
};
|
|
||||||
auto captures = new Captures();
|
|
||||||
captures->reply = reply;
|
|
||||||
|
|
||||||
auto message_reply = [](const uint8_t* data, size_t data_size,
|
|
||||||
void* user_data) {
|
|
||||||
auto captures = reinterpret_cast<Captures*>(user_data);
|
|
||||||
captures->reply(data, data_size);
|
|
||||||
delete captures;
|
|
||||||
};
|
|
||||||
bool result = FlutterDesktopMessengerSendWithReply(
|
|
||||||
messenger_, channel.c_str(), message, message_size, message_reply,
|
|
||||||
captures);
|
|
||||||
if (!result) {
|
|
||||||
delete captures;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BinaryMessengerImpl::SetMessageHandler(const std::string& channel,
|
|
||||||
BinaryMessageHandler handler) {
|
|
||||||
if (!handler) {
|
|
||||||
handlers_.erase(channel);
|
|
||||||
FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(), nullptr,
|
|
||||||
nullptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Save the handler, to keep it alive.
|
|
||||||
handlers_[channel] = std::move(handler);
|
|
||||||
BinaryMessageHandler* message_handler = &handlers_[channel];
|
|
||||||
// Set an adaptor callback that will invoke the handler.
|
|
||||||
FlutterDesktopMessengerSetCallback(messenger_, channel.c_str(),
|
|
||||||
ForwardToHandler, message_handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ========== engine_method_result.h ==========
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
ReplyManager::ReplyManager(BinaryReply reply_handler)
|
|
||||||
: reply_handler_(std::move(reply_handler)) {
|
|
||||||
assert(reply_handler_);
|
|
||||||
}
|
|
||||||
|
|
||||||
ReplyManager::~ReplyManager() {
|
|
||||||
if (reply_handler_) {
|
|
||||||
// Warn, rather than send a not-implemented response, since the engine may
|
|
||||||
// no longer be valid at this point.
|
|
||||||
std::cerr
|
|
||||||
<< "Warning: Failed to respond to a message. This is a memory leak."
|
|
||||||
<< std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReplyManager::SendResponseData(const std::vector<uint8_t>* data) {
|
|
||||||
if (!reply_handler_) {
|
|
||||||
std::cerr
|
|
||||||
<< "Error: Only one of Success, Error, or NotImplemented can be "
|
|
||||||
"called,"
|
|
||||||
<< " and it can be called exactly once. Ignoring duplicate result."
|
|
||||||
<< std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t* message = data && !data->empty() ? data->data() : nullptr;
|
|
||||||
size_t message_size = data ? data->size() : 0;
|
|
||||||
reply_handler_(message, message_size);
|
|
||||||
reply_handler_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
// ========== method_channel.h ==========
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
constexpr char kControlChannelName[] = "dev.flutter/channel-buffers";
|
|
||||||
constexpr char kResizeMethod[] = "resize";
|
|
||||||
constexpr char kOverflowMethod[] = "overflow";
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
void ResizeChannel(BinaryMessenger* messenger, std::string name, int new_size) {
|
|
||||||
auto control_channel = std::make_unique<MethodChannel<EncodableValue>>(
|
|
||||||
messenger, kControlChannelName, &StandardMethodCodec::GetInstance());
|
|
||||||
|
|
||||||
// The deserialization logic handles only 32 bits values, see
|
|
||||||
// https://github.com/flutter/engine/blob/93e8901490e78c7ba7e319cce4470d9c6478c6dc/lib/ui/channel_buffers.dart#L495.
|
|
||||||
control_channel->InvokeMethod(
|
|
||||||
kResizeMethod, std::make_unique<EncodableValue>(EncodableList{
|
|
||||||
EncodableValue(name),
|
|
||||||
EncodableValue(static_cast<int32_t>(new_size)),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetChannelWarnsOnOverflow(BinaryMessenger* messenger,
|
|
||||||
std::string name,
|
|
||||||
bool warns) {
|
|
||||||
auto control_channel = std::make_unique<MethodChannel<EncodableValue>>(
|
|
||||||
messenger, kControlChannelName, &StandardMethodCodec::GetInstance());
|
|
||||||
|
|
||||||
control_channel->InvokeMethod(kOverflowMethod,
|
|
||||||
std::make_unique<EncodableValue>(EncodableList{
|
|
||||||
EncodableValue(name),
|
|
||||||
EncodableValue(!warns),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
// ========== texture_registrar_impl.h ==========
|
|
||||||
|
|
||||||
TextureRegistrarImpl::TextureRegistrarImpl(
|
|
||||||
FlutterDesktopTextureRegistrarRef texture_registrar_ref)
|
|
||||||
: texture_registrar_ref_(texture_registrar_ref) {}
|
|
||||||
|
|
||||||
TextureRegistrarImpl::~TextureRegistrarImpl() = default;
|
|
||||||
|
|
||||||
int64_t TextureRegistrarImpl::RegisterTexture(TextureVariant* texture) {
|
|
||||||
FlutterDesktopTextureInfo info = {};
|
|
||||||
if (auto pixel_buffer_texture = std::get_if<PixelBufferTexture>(texture)) {
|
|
||||||
info.type = kFlutterDesktopPixelBufferTexture;
|
|
||||||
info.pixel_buffer_config.user_data = pixel_buffer_texture;
|
|
||||||
info.pixel_buffer_config.callback =
|
|
||||||
[](size_t width, size_t height,
|
|
||||||
void* user_data) -> const FlutterDesktopPixelBuffer* {
|
|
||||||
auto texture = static_cast<PixelBufferTexture*>(user_data);
|
|
||||||
return texture->CopyPixelBuffer(width, height);
|
|
||||||
};
|
|
||||||
} else if (auto gpu_surface_texture =
|
|
||||||
std::get_if<GpuSurfaceTexture>(texture)) {
|
|
||||||
info.type = kFlutterDesktopGpuSurfaceTexture;
|
|
||||||
info.gpu_surface_config.struct_size =
|
|
||||||
sizeof(FlutterDesktopGpuSurfaceTextureConfig);
|
|
||||||
info.gpu_surface_config.type = gpu_surface_texture->surface_type();
|
|
||||||
info.gpu_surface_config.user_data = gpu_surface_texture;
|
|
||||||
info.gpu_surface_config.callback =
|
|
||||||
[](size_t width, size_t height,
|
|
||||||
void* user_data) -> const FlutterDesktopGpuSurfaceDescriptor* {
|
|
||||||
auto texture = static_cast<GpuSurfaceTexture*>(user_data);
|
|
||||||
return texture->ObtainDescriptor(width, height);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
std::cerr << "Attempting to register unknown texture variant." << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t texture_id = FlutterDesktopTextureRegistrarRegisterExternalTexture(
|
|
||||||
texture_registrar_ref_, &info);
|
|
||||||
return texture_id;
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
bool TextureRegistrarImpl::MarkTextureFrameAvailable(int64_t texture_id) {
|
|
||||||
return FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable(
|
|
||||||
texture_registrar_ref_, texture_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextureRegistrarImpl::UnregisterTexture(int64_t texture_id,
|
|
||||||
std::function<void()> callback) {
|
|
||||||
if (callback == nullptr) {
|
|
||||||
FlutterDesktopTextureRegistrarUnregisterExternalTexture(
|
|
||||||
texture_registrar_ref_, texture_id, nullptr, nullptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Captures {
|
|
||||||
std::function<void()> callback;
|
|
||||||
};
|
|
||||||
auto captures = new Captures();
|
|
||||||
captures->callback = std::move(callback);
|
|
||||||
FlutterDesktopTextureRegistrarUnregisterExternalTexture(
|
|
||||||
texture_registrar_ref_, texture_id,
|
|
||||||
[](void* opaque) {
|
|
||||||
auto captures = reinterpret_cast<Captures*>(opaque);
|
|
||||||
captures->callback();
|
|
||||||
delete captures;
|
|
||||||
},
|
|
||||||
captures);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool TextureRegistrarImpl::UnregisterTexture(int64_t texture_id) {
|
|
||||||
UnregisterTexture(texture_id, nullptr);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// This file is deprecated in favor of core_implementations.cc. This is a
|
|
||||||
// temporary forwarding implementation so that the switch to
|
|
||||||
// core_implementations.cc isn't an immediate breaking change, allowing for the
|
|
||||||
// template to be updated to include it and update the template version before
|
|
||||||
// removing this file.
|
|
||||||
|
|
||||||
#include "core_implementations.cc"
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "include/flutter/flutter_engine.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
#include "binary_messenger_impl.h"
|
|
||||||
#include "flutter_windows.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
FlutterEngine::FlutterEngine(const DartProject& project) {
|
|
||||||
FlutterDesktopEngineProperties c_engine_properties = {};
|
|
||||||
c_engine_properties.assets_path = project.assets_path().c_str();
|
|
||||||
c_engine_properties.icu_data_path = project.icu_data_path().c_str();
|
|
||||||
c_engine_properties.aot_library_path = project.aot_library_path().c_str();
|
|
||||||
c_engine_properties.dart_entrypoint = project.dart_entrypoint().c_str();
|
|
||||||
c_engine_properties.gpu_preference =
|
|
||||||
static_cast<FlutterDesktopGpuPreference>(project.gpu_preference());
|
|
||||||
c_engine_properties.ui_thread_policy =
|
|
||||||
static_cast<FlutterDesktopUIThreadPolicy>(project.ui_thread_policy());
|
|
||||||
|
|
||||||
const std::vector<std::string>& entrypoint_args =
|
|
||||||
project.dart_entrypoint_arguments();
|
|
||||||
std::vector<const char*> entrypoint_argv;
|
|
||||||
std::transform(
|
|
||||||
entrypoint_args.begin(), entrypoint_args.end(),
|
|
||||||
std::back_inserter(entrypoint_argv),
|
|
||||||
[](const std::string& arg) -> const char* { return arg.c_str(); });
|
|
||||||
|
|
||||||
c_engine_properties.dart_entrypoint_argc =
|
|
||||||
static_cast<int>(entrypoint_argv.size());
|
|
||||||
c_engine_properties.dart_entrypoint_argv =
|
|
||||||
entrypoint_argv.empty() ? nullptr : entrypoint_argv.data();
|
|
||||||
|
|
||||||
engine_ = FlutterDesktopEngineCreate(&c_engine_properties);
|
|
||||||
|
|
||||||
auto core_messenger = FlutterDesktopEngineGetMessenger(engine_);
|
|
||||||
messenger_ = std::make_unique<BinaryMessengerImpl>(core_messenger);
|
|
||||||
}
|
|
||||||
|
|
||||||
FlutterEngine::~FlutterEngine() {
|
|
||||||
ShutDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FlutterEngine::Run() {
|
|
||||||
return Run(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FlutterEngine::Run(const char* entry_point) {
|
|
||||||
if (!engine_) {
|
|
||||||
std::cerr << "Cannot run an engine that failed creation." << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (run_succeeded_) {
|
|
||||||
std::cerr << "Cannot run an engine more than once." << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool run_succeeded = FlutterDesktopEngineRun(engine_, entry_point);
|
|
||||||
if (!run_succeeded) {
|
|
||||||
std::cerr << "Failed to start engine." << std::endl;
|
|
||||||
}
|
|
||||||
run_succeeded_ = true;
|
|
||||||
return run_succeeded;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlutterEngine::ShutDown() {
|
|
||||||
if (engine_ && owns_engine_) {
|
|
||||||
FlutterDesktopEngineDestroy(engine_);
|
|
||||||
}
|
|
||||||
engine_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::chrono::nanoseconds FlutterEngine::ProcessMessages() {
|
|
||||||
return std::chrono::nanoseconds(FlutterDesktopEngineProcessMessages(engine_));
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlutterEngine::ReloadSystemFonts() {
|
|
||||||
FlutterDesktopEngineReloadSystemFonts(engine_);
|
|
||||||
}
|
|
||||||
|
|
||||||
FlutterDesktopPluginRegistrarRef FlutterEngine::GetRegistrarForPlugin(
|
|
||||||
const std::string& plugin_name) {
|
|
||||||
if (!engine_) {
|
|
||||||
std::cerr << "Cannot get plugin registrar on an engine that isn't running; "
|
|
||||||
"call Run first."
|
|
||||||
<< std::endl;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return FlutterDesktopEngineGetPluginRegistrar(engine_, plugin_name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlutterEngine::SetNextFrameCallback(std::function<void()> callback) {
|
|
||||||
next_frame_callback_ = std::move(callback);
|
|
||||||
FlutterDesktopEngineSetNextFrameCallback(
|
|
||||||
engine_,
|
|
||||||
[](void* user_data) {
|
|
||||||
FlutterEngine* self = static_cast<FlutterEngine*>(user_data);
|
|
||||||
self->next_frame_callback_();
|
|
||||||
self->next_frame_callback_ = nullptr;
|
|
||||||
},
|
|
||||||
this);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<LRESULT> FlutterEngine::ProcessExternalWindowMessage(
|
|
||||||
HWND hwnd,
|
|
||||||
UINT message,
|
|
||||||
WPARAM wparam,
|
|
||||||
LPARAM lparam) {
|
|
||||||
LRESULT result;
|
|
||||||
if (FlutterDesktopEngineProcessExternalWindowMessage(
|
|
||||||
engine_, hwnd, message, wparam, lparam, &result)) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
FlutterDesktopEngineRef FlutterEngine::RelinquishEngine() {
|
|
||||||
owns_engine_ = false;
|
|
||||||
return engine_;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "include/flutter/flutter_view_controller.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
FlutterViewController::FlutterViewController(int width,
|
|
||||||
int height,
|
|
||||||
const DartProject& project) {
|
|
||||||
engine_ = std::make_shared<FlutterEngine>(project);
|
|
||||||
controller_ = FlutterDesktopViewControllerCreate(width, height,
|
|
||||||
engine_->RelinquishEngine());
|
|
||||||
if (!controller_) {
|
|
||||||
std::cerr << "Failed to create view controller." << std::endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
view_ = std::make_unique<FlutterView>(
|
|
||||||
FlutterDesktopViewControllerGetView(controller_));
|
|
||||||
}
|
|
||||||
|
|
||||||
FlutterViewController::~FlutterViewController() {
|
|
||||||
if (controller_) {
|
|
||||||
FlutterDesktopViewControllerDestroy(controller_);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FlutterViewId FlutterViewController::view_id() const {
|
|
||||||
auto view_id = FlutterDesktopViewControllerGetViewId(controller_);
|
|
||||||
|
|
||||||
return static_cast<FlutterViewId>(view_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlutterViewController::ForceRedraw() {
|
|
||||||
FlutterDesktopViewControllerForceRedraw(controller_);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<LRESULT> FlutterViewController::HandleTopLevelWindowProc(
|
|
||||||
HWND hwnd,
|
|
||||||
UINT message,
|
|
||||||
WPARAM wparam,
|
|
||||||
LPARAM lparam) {
|
|
||||||
LRESULT result;
|
|
||||||
bool handled = FlutterDesktopViewControllerHandleTopLevelWindowProc(
|
|
||||||
controller_, hwnd, message, wparam, lparam, &result);
|
|
||||||
return handled ? result : std::optional<LRESULT>(std::nullopt);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BASIC_MESSAGE_CHANNEL_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BASIC_MESSAGE_CHANNEL_H_
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "binary_messenger.h"
|
|
||||||
#include "message_codec.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
// Internal helper functions used by BasicMessageChannel and MethodChannel.
|
|
||||||
|
|
||||||
// Adjusts the number of messages that will get buffered when sending messages
|
|
||||||
// to channels that aren't fully set up yet. For example, the engine isn't
|
|
||||||
// running yet or the channel's message handler isn't set up on the Dart side
|
|
||||||
// yet.
|
|
||||||
void ResizeChannel(BinaryMessenger* messenger, std::string name, int new_size);
|
|
||||||
|
|
||||||
// Defines whether the channel should show warning messages when discarding
|
|
||||||
// messages due to overflow.
|
|
||||||
//
|
|
||||||
// When |warns| is false, the channel is expected to overflow and warning
|
|
||||||
// messages will not be shown.
|
|
||||||
void SetChannelWarnsOnOverflow(BinaryMessenger* messenger,
|
|
||||||
std::string name,
|
|
||||||
bool warns);
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
class EncodableValue;
|
|
||||||
|
|
||||||
// A message reply callback.
|
|
||||||
//
|
|
||||||
// Used for submitting a reply back to a Flutter message sender.
|
|
||||||
template <typename T>
|
|
||||||
using MessageReply = std::function<void(const T& reply)>;
|
|
||||||
|
|
||||||
// A handler for receiving a message from the Flutter engine.
|
|
||||||
//
|
|
||||||
// Implementations must asynchronously call reply exactly once with the reply
|
|
||||||
// to the message.
|
|
||||||
template <typename T>
|
|
||||||
using MessageHandler =
|
|
||||||
std::function<void(const T& message, const MessageReply<T>& reply)>;
|
|
||||||
|
|
||||||
// A channel for communicating with the Flutter engine by sending asynchronous
|
|
||||||
// messages.
|
|
||||||
template <typename T = EncodableValue>
|
|
||||||
class BasicMessageChannel {
|
|
||||||
public:
|
|
||||||
// Creates an instance that sends and receives method calls on the channel
|
|
||||||
// named |name|, encoded with |codec| and dispatched via |messenger|.
|
|
||||||
BasicMessageChannel(BinaryMessenger* messenger,
|
|
||||||
const std::string& name,
|
|
||||||
const MessageCodec<T>* codec)
|
|
||||||
: messenger_(messenger), name_(name), codec_(codec) {}
|
|
||||||
|
|
||||||
~BasicMessageChannel() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
BasicMessageChannel(BasicMessageChannel const&) = delete;
|
|
||||||
BasicMessageChannel& operator=(BasicMessageChannel const&) = delete;
|
|
||||||
|
|
||||||
// Sends a message to the Flutter engine on this channel.
|
|
||||||
void Send(const T& message) {
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> raw_message =
|
|
||||||
codec_->EncodeMessage(message);
|
|
||||||
messenger_->Send(name_, raw_message->data(), raw_message->size());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sends a message to the Flutter engine on this channel expecting a reply.
|
|
||||||
void Send(const T& message, BinaryReply reply) {
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> raw_message =
|
|
||||||
codec_->EncodeMessage(message);
|
|
||||||
messenger_->Send(name_, raw_message->data(), raw_message->size(),
|
|
||||||
std::move(reply));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registers a handler that should be called any time a message is
|
|
||||||
// received on this channel. A null handler will remove any previous handler.
|
|
||||||
//
|
|
||||||
// Note that the BasicMessageChannel does not own the handler, and will not
|
|
||||||
// unregister it on destruction, so the caller is responsible for
|
|
||||||
// unregistering explicitly if it should no longer be called.
|
|
||||||
void SetMessageHandler(const MessageHandler<T>& handler) const {
|
|
||||||
if (!handler) {
|
|
||||||
messenger_->SetMessageHandler(name_, nullptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto* codec = codec_;
|
|
||||||
std::string channel_name = name_;
|
|
||||||
BinaryMessageHandler binary_handler = [handler, codec, channel_name](
|
|
||||||
const uint8_t* binary_message,
|
|
||||||
const size_t binary_message_size,
|
|
||||||
const BinaryReply& binary_reply) {
|
|
||||||
// Use this channel's codec to decode the message and build a reply
|
|
||||||
// handler.
|
|
||||||
std::unique_ptr<T> message =
|
|
||||||
codec->DecodeMessage(binary_message, binary_message_size);
|
|
||||||
if (!message) {
|
|
||||||
std::cerr << "Unable to decode message on channel " << channel_name
|
|
||||||
<< std::endl;
|
|
||||||
binary_reply(nullptr, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageReply<T> unencoded_reply = [binary_reply,
|
|
||||||
codec](const T& unencoded_response) {
|
|
||||||
auto binary_response = codec->EncodeMessage(unencoded_response);
|
|
||||||
binary_reply(binary_response->data(), binary_response->size());
|
|
||||||
};
|
|
||||||
handler(*message, std::move(unencoded_reply));
|
|
||||||
};
|
|
||||||
messenger_->SetMessageHandler(name_, std::move(binary_handler));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjusts the number of messages that will get buffered when sending messages
|
|
||||||
// to channels that aren't fully set up yet. For example, the engine isn't
|
|
||||||
// running yet or the channel's message handler isn't set up on the Dart side
|
|
||||||
// yet.
|
|
||||||
void Resize(int new_size) {
|
|
||||||
internal::ResizeChannel(messenger_, name_, new_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defines whether the channel should show warning messages when discarding
|
|
||||||
// messages due to overflow.
|
|
||||||
//
|
|
||||||
// When |warns| is false, the channel is expected to overflow and warning
|
|
||||||
// messages will not be shown.
|
|
||||||
void SetWarnsOnOverflow(bool warns) {
|
|
||||||
internal::SetChannelWarnsOnOverflow(messenger_, name_, warns);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BinaryMessenger* messenger_;
|
|
||||||
std::string name_;
|
|
||||||
const MessageCodec<T>* codec_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BASIC_MESSAGE_CHANNEL_H_
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BINARY_MESSENGER_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BINARY_MESSENGER_H_
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// A binary message reply callback.
|
|
||||||
//
|
|
||||||
// Used for submitting a binary reply back to a Flutter message sender.
|
|
||||||
typedef std::function<void(const uint8_t* reply, size_t reply_size)>
|
|
||||||
BinaryReply;
|
|
||||||
|
|
||||||
// A message handler callback.
|
|
||||||
//
|
|
||||||
// Used for receiving messages from Flutter and providing an asynchronous reply.
|
|
||||||
typedef std::function<
|
|
||||||
void(const uint8_t* message, size_t message_size, BinaryReply reply)>
|
|
||||||
BinaryMessageHandler;
|
|
||||||
|
|
||||||
// A protocol for a class that handles communication of binary data on named
|
|
||||||
// channels to and from the Flutter engine.
|
|
||||||
class BinaryMessenger {
|
|
||||||
public:
|
|
||||||
virtual ~BinaryMessenger() = default;
|
|
||||||
|
|
||||||
// Sends a binary message to the Flutter engine on the specified channel.
|
|
||||||
//
|
|
||||||
// If |reply| is provided, it will be called back with the response from the
|
|
||||||
// engine.
|
|
||||||
virtual void Send(const std::string& channel,
|
|
||||||
const uint8_t* message,
|
|
||||||
size_t message_size,
|
|
||||||
BinaryReply reply = nullptr) const = 0;
|
|
||||||
|
|
||||||
// Registers a message handler for incoming binary messages from the Flutter
|
|
||||||
// side on the specified channel.
|
|
||||||
//
|
|
||||||
// Replaces any existing handler. Provide a null handler to unregister the
|
|
||||||
// existing handler.
|
|
||||||
virtual void SetMessageHandler(const std::string& channel,
|
|
||||||
BinaryMessageHandler handler) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BINARY_MESSENGER_H_
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BYTE_STREAMS_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BYTE_STREAMS_H_
|
|
||||||
|
|
||||||
// Interfaces for interacting with a stream of bytes, for use in codecs.
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// An interface for a class that reads from a byte stream.
|
|
||||||
class ByteStreamReader {
|
|
||||||
public:
|
|
||||||
explicit ByteStreamReader() = default;
|
|
||||||
virtual ~ByteStreamReader() = default;
|
|
||||||
|
|
||||||
// Reads and returns the next byte from the stream.
|
|
||||||
virtual uint8_t ReadByte() = 0;
|
|
||||||
|
|
||||||
// Reads the next |length| bytes from the stream into |buffer|. The caller
|
|
||||||
// is responsible for ensuring that |buffer| is large enough.
|
|
||||||
virtual void ReadBytes(uint8_t* buffer, size_t length) = 0;
|
|
||||||
|
|
||||||
// Advances the read cursor to the next multiple of |alignment| relative to
|
|
||||||
// the start of the stream, unless it is already aligned.
|
|
||||||
virtual void ReadAlignment(uint8_t alignment) = 0;
|
|
||||||
|
|
||||||
// Reads and returns the next 32-bit integer from the stream.
|
|
||||||
int32_t ReadInt32() {
|
|
||||||
int32_t value = 0;
|
|
||||||
ReadBytes(reinterpret_cast<uint8_t*>(&value), 4);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reads and returns the next 64-bit integer from the stream.
|
|
||||||
int64_t ReadInt64() {
|
|
||||||
int64_t value = 0;
|
|
||||||
ReadBytes(reinterpret_cast<uint8_t*>(&value), 8);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reads and returns the next 64-bit floating point number from the stream.
|
|
||||||
double ReadDouble() {
|
|
||||||
double value = 0;
|
|
||||||
ReadBytes(reinterpret_cast<uint8_t*>(&value), 8);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// An interface for a class that writes to a byte stream.
|
|
||||||
class ByteStreamWriter {
|
|
||||||
public:
|
|
||||||
explicit ByteStreamWriter() = default;
|
|
||||||
virtual ~ByteStreamWriter() = default;
|
|
||||||
|
|
||||||
// Writes |byte| to the stream.
|
|
||||||
virtual void WriteByte(uint8_t byte) = 0;
|
|
||||||
|
|
||||||
// Writes the next |length| bytes from |bytes| to the stream
|
|
||||||
virtual void WriteBytes(const uint8_t* bytes, size_t length) = 0;
|
|
||||||
|
|
||||||
// Writes 0s until the next multiple of |alignment| relative to the start
|
|
||||||
// of the stream, unless the write positition is already aligned.
|
|
||||||
virtual void WriteAlignment(uint8_t alignment) = 0;
|
|
||||||
|
|
||||||
// Writes the given 32-bit int to the stream.
|
|
||||||
void WriteInt32(int32_t value) {
|
|
||||||
WriteBytes(reinterpret_cast<const uint8_t*>(&value), 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Writes the given 64-bit int to the stream.
|
|
||||||
void WriteInt64(int64_t value) {
|
|
||||||
WriteBytes(reinterpret_cast<const uint8_t*>(&value), 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Writes the given 36-bit double to the stream.
|
|
||||||
void WriteDouble(double value) {
|
|
||||||
WriteBytes(reinterpret_cast<const uint8_t*>(&value), 8);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_BYTE_STREAMS_H_
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_DART_PROJECT_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_DART_PROJECT_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// Configures how the Flutter engine selects a GPU.
|
|
||||||
enum class GpuPreference {
|
|
||||||
// No preference.
|
|
||||||
NoPreference,
|
|
||||||
// Prefer energy efficiency over performance, such as an integrated GPU.
|
|
||||||
// This falls back to a high performance GPU if no low power GPU is
|
|
||||||
// available.
|
|
||||||
LowPowerPreference,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Configures the thread policy for running the UI isolate.
|
|
||||||
enum class UIThreadPolicy {
|
|
||||||
// Default value. Currently will run the UI isolate on separate thread,
|
|
||||||
// later will be changed to running the UI isolate on platform thread.
|
|
||||||
Default,
|
|
||||||
// Run the UI isolate on platform thread.
|
|
||||||
RunOnPlatformThread,
|
|
||||||
// Run the UI isolate on a separate thread.
|
|
||||||
RunOnSeparateThread,
|
|
||||||
};
|
|
||||||
|
|
||||||
// A set of Flutter and Dart assets used to initialize a Flutter engine.
|
|
||||||
class DartProject {
|
|
||||||
public:
|
|
||||||
// Creates a DartProject from a series of absolute paths.
|
|
||||||
// The three paths are:
|
|
||||||
// - assets_path: Path to the assets directory as built by the Flutter tool.
|
|
||||||
// - icu_data_path: Path to the icudtl.dat file.
|
|
||||||
// - aot_library_path: Path to the AOT snapshot file.
|
|
||||||
//
|
|
||||||
// The paths may either be absolute or relative to the directory containing
|
|
||||||
// the running executable.
|
|
||||||
explicit DartProject(const std::wstring& assets_path,
|
|
||||||
const std::wstring& icu_data_path,
|
|
||||||
const std::wstring& aot_library_path) {
|
|
||||||
assets_path_ = assets_path;
|
|
||||||
icu_data_path_ = icu_data_path;
|
|
||||||
aot_library_path_ = aot_library_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates a DartProject from a directory path. The directory should contain
|
|
||||||
// the following top-level items:
|
|
||||||
// - icudtl.dat (provided as a resource by the Flutter tool)
|
|
||||||
// - flutter_assets (as built by the Flutter tool)
|
|
||||||
// - app.so, for an AOT build (as built by the Flutter tool)
|
|
||||||
//
|
|
||||||
// The path can either be absolute, or relative to the directory containing
|
|
||||||
// the running executable.
|
|
||||||
explicit DartProject(const std::wstring& path) {
|
|
||||||
assets_path_ = path + L"\\flutter_assets";
|
|
||||||
icu_data_path_ = path + L"\\icudtl.dat";
|
|
||||||
aot_library_path_ = path + L"\\app.so";
|
|
||||||
}
|
|
||||||
|
|
||||||
~DartProject() = default;
|
|
||||||
|
|
||||||
// Sets the Dart entrypoint to the specified value.
|
|
||||||
//
|
|
||||||
// If not set, the default entrypoint (main) is used. Custom Dart entrypoints
|
|
||||||
// must be decorated with `@pragma('vm:entry-point')`.
|
|
||||||
void set_dart_entrypoint(const std::string& entrypoint) {
|
|
||||||
if (entrypoint.empty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
dart_entrypoint_ = entrypoint;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the Dart entrypoint.
|
|
||||||
const std::string& dart_entrypoint() const { return dart_entrypoint_; }
|
|
||||||
|
|
||||||
// Sets the command line arguments that should be passed to the Dart
|
|
||||||
// entrypoint.
|
|
||||||
void set_dart_entrypoint_arguments(std::vector<std::string> arguments) {
|
|
||||||
dart_entrypoint_arguments_ = std::move(arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns any command line arguments that should be passed to the Dart
|
|
||||||
// entrypoint.
|
|
||||||
const std::vector<std::string>& dart_entrypoint_arguments() const {
|
|
||||||
return dart_entrypoint_arguments_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sets the GPU usage preference for flutter engine.
|
|
||||||
void set_gpu_preference(GpuPreference gpu_preference) {
|
|
||||||
gpu_preference_ = gpu_preference;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the project's GPU preference.
|
|
||||||
// Defaults to NoPreference.
|
|
||||||
GpuPreference gpu_preference() const { return gpu_preference_; }
|
|
||||||
|
|
||||||
// Sets the thread policy for UI isolate.
|
|
||||||
void set_ui_thread_policy(UIThreadPolicy policy) {
|
|
||||||
ui_thread_policy_ = policy;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the policy for UI isolate.
|
|
||||||
// Defaults to UIThreadPolicy::Default.
|
|
||||||
UIThreadPolicy ui_thread_policy() const { return ui_thread_policy_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Accessors for internals are private, so that they can be changed if more
|
|
||||||
// flexible options for project structures are needed later without it
|
|
||||||
// being a breaking change. Provide access to internal classes that need
|
|
||||||
// them.
|
|
||||||
friend class FlutterEngine;
|
|
||||||
friend class FlutterViewController;
|
|
||||||
friend class DartProjectTest;
|
|
||||||
|
|
||||||
const std::wstring& assets_path() const { return assets_path_; }
|
|
||||||
const std::wstring& icu_data_path() const { return icu_data_path_; }
|
|
||||||
const std::wstring& aot_library_path() const { return aot_library_path_; }
|
|
||||||
|
|
||||||
// The path to the assets directory.
|
|
||||||
std::wstring assets_path_;
|
|
||||||
// The path to the ICU data.
|
|
||||||
std::wstring icu_data_path_;
|
|
||||||
// The path to the AOT library. This will always return a path, but non-AOT
|
|
||||||
// builds will not be expected to actually have a library at that path.
|
|
||||||
std::wstring aot_library_path_;
|
|
||||||
// The Dart entrypoint to launch.
|
|
||||||
std::string dart_entrypoint_;
|
|
||||||
// The list of arguments to pass through to the Dart entrypoint.
|
|
||||||
std::vector<std::string> dart_entrypoint_arguments_;
|
|
||||||
// The preference for GPU to be used by flutter engine.
|
|
||||||
GpuPreference gpu_preference_ = GpuPreference::NoPreference;
|
|
||||||
// Thread policy for UI isolate.
|
|
||||||
UIThreadPolicy ui_thread_policy_ = UIThreadPolicy::Default;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_DART_PROJECT_H_
|
|
||||||
@@ -1,274 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_ENCODABLE_VALUE_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_ENCODABLE_VALUE_H_
|
|
||||||
|
|
||||||
#include <any>
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstdint>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
#include <variant>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// Unless overridden, attempt to detect the RTTI state from the compiler.
|
|
||||||
#ifndef FLUTTER_ENABLE_RTTI
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#ifdef _CPPRTTI
|
|
||||||
#define FLUTTER_ENABLE_RTTI 1
|
|
||||||
#endif
|
|
||||||
#elif defined(__clang__)
|
|
||||||
#if __has_feature(cxx_rtti)
|
|
||||||
#define FLUTTER_ENABLE_RTTI 1
|
|
||||||
#endif
|
|
||||||
#elif defined(__GNUC__)
|
|
||||||
#ifdef __GXX_RTTI
|
|
||||||
#define FLUTTER_ENABLE_RTTI 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#endif // #ifndef FLUTTER_ENABLE_RTTI
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
static_assert(sizeof(double) == 8, "EncodableValue requires a 64-bit double");
|
|
||||||
|
|
||||||
// A container for arbitrary types in EncodableValue.
|
|
||||||
//
|
|
||||||
// This is used in conjunction with StandardCodecExtension to allow using other
|
|
||||||
// types with a StandardMethodCodec/StandardMessageCodec. It is implicitly
|
|
||||||
// convertible to EncodableValue, so constructing an EncodableValue from a
|
|
||||||
// custom type can generally be written as:
|
|
||||||
// CustomEncodableValue(MyType(...))
|
|
||||||
// rather than:
|
|
||||||
// EncodableValue(CustomEncodableValue(MyType(...)))
|
|
||||||
//
|
|
||||||
// For extracting received custom types, it is implicitly convertible to
|
|
||||||
// std::any. For example:
|
|
||||||
// const MyType& my_type_value =
|
|
||||||
// std::any_cast<MyType>(std::get<CustomEncodableValue>(value));
|
|
||||||
//
|
|
||||||
// If RTTI is enabled, different extension types can be checked with type():
|
|
||||||
// if (custom_value->type() == typeid(SomeData)) { ... }
|
|
||||||
// Clients that wish to disable RTTI would need to decide on another approach
|
|
||||||
// for distinguishing types (e.g., in StandardCodecExtension::WriteValueOfType)
|
|
||||||
// if multiple custom types are needed. For instance, wrapping all of the
|
|
||||||
// extension types in an EncodableValue-style variant, and only ever storing
|
|
||||||
// that variant in CustomEncodableValue.
|
|
||||||
class CustomEncodableValue {
|
|
||||||
public:
|
|
||||||
explicit CustomEncodableValue(const std::any& value) : value_(value) {}
|
|
||||||
~CustomEncodableValue() = default;
|
|
||||||
|
|
||||||
// Allow implicit conversion to std::any to allow direct use of any_cast.
|
|
||||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
||||||
operator std::any&() { return value_; }
|
|
||||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
||||||
operator const std::any&() const { return value_; }
|
|
||||||
|
|
||||||
#if defined(FLUTTER_ENABLE_RTTI) && FLUTTER_ENABLE_RTTI
|
|
||||||
// Passthrough to std::any's type().
|
|
||||||
const std::type_info& type() const noexcept { return value_.type(); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// This operator exists only to provide a stable ordering for use as a
|
|
||||||
// std::map key, to satisfy the compiler requirements for EncodableValue.
|
|
||||||
// It does not attempt to provide useful ordering semantics, and using a
|
|
||||||
// custom value as a map key is not recommended.
|
|
||||||
bool operator<(const CustomEncodableValue& other) const {
|
|
||||||
return this < &other;
|
|
||||||
}
|
|
||||||
bool operator==(const CustomEncodableValue& other) const {
|
|
||||||
return this == &other;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::any value_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class EncodableValue;
|
|
||||||
|
|
||||||
// Convenience type aliases.
|
|
||||||
using EncodableList = std::vector<EncodableValue>;
|
|
||||||
using EncodableMap = std::map<EncodableValue, EncodableValue>;
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
// The base class for EncodableValue. Do not use this directly; it exists only
|
|
||||||
// for EncodableValue to inherit from.
|
|
||||||
//
|
|
||||||
// Do not change the order or indexes of the items here; see the comment on
|
|
||||||
// EncodableValue
|
|
||||||
using EncodableValueVariant = std::variant<std::monostate,
|
|
||||||
bool,
|
|
||||||
int32_t,
|
|
||||||
int64_t,
|
|
||||||
double,
|
|
||||||
std::string,
|
|
||||||
std::vector<uint8_t>,
|
|
||||||
std::vector<int32_t>,
|
|
||||||
std::vector<int64_t>,
|
|
||||||
std::vector<double>,
|
|
||||||
EncodableList,
|
|
||||||
EncodableMap,
|
|
||||||
CustomEncodableValue,
|
|
||||||
std::vector<float>>;
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
// An object that can contain any value or collection type supported by
|
|
||||||
// Flutter's standard method codec.
|
|
||||||
//
|
|
||||||
// For details, see:
|
|
||||||
// https://api.flutter.dev/flutter/services/StandardMessageCodec-class.html
|
|
||||||
//
|
|
||||||
// As an example, the following Dart structure:
|
|
||||||
// {
|
|
||||||
// 'flag': true,
|
|
||||||
// 'name': 'Thing',
|
|
||||||
// 'values': [1, 2.0, 4],
|
|
||||||
// }
|
|
||||||
// would correspond to:
|
|
||||||
// EncodableValue(EncodableMap{
|
|
||||||
// {EncodableValue("flag"), EncodableValue(true)},
|
|
||||||
// {EncodableValue("name"), EncodableValue("Thing")},
|
|
||||||
// {EncodableValue("values"), EncodableValue(EncodableList{
|
|
||||||
// EncodableValue(1),
|
|
||||||
// EncodableValue(2.0),
|
|
||||||
// EncodableValue(4),
|
|
||||||
// })},
|
|
||||||
// })
|
|
||||||
//
|
|
||||||
// The primary API surface for this object is std::variant. For instance,
|
|
||||||
// getting a string value from an EncodableValue, with type checking:
|
|
||||||
// if (std::holds_alternative<std::string>(value)) {
|
|
||||||
// std::string some_string = std::get<std::string>(value);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// The order/indexes of the variant types is part of the API surface, and is
|
|
||||||
// guaranteed not to change.
|
|
||||||
//
|
|
||||||
// The variant types are mapped with Dart types in following ways:
|
|
||||||
// std::monostate -> null
|
|
||||||
// bool -> bool
|
|
||||||
// int32_t -> int
|
|
||||||
// int64_t -> int
|
|
||||||
// double -> double
|
|
||||||
// std::string -> String
|
|
||||||
// std::vector<uint8_t> -> Uint8List
|
|
||||||
// std::vector<int32_t> -> Int32List
|
|
||||||
// std::vector<int64_t> -> Int64List
|
|
||||||
// std::vector<float> -> Float32List
|
|
||||||
// std::vector<double> -> Float64List
|
|
||||||
// EncodableList -> List
|
|
||||||
// EncodableMap -> Map
|
|
||||||
class EncodableValue : public internal::EncodableValueVariant {
|
|
||||||
public:
|
|
||||||
// Rely on std::variant for most of the constructors/operators.
|
|
||||||
using super = internal::EncodableValueVariant;
|
|
||||||
using super::super;
|
|
||||||
using super::operator=;
|
|
||||||
|
|
||||||
explicit EncodableValue() = default;
|
|
||||||
|
|
||||||
// Avoid the C++17 pitfall of conversion from char* to bool. Should not be
|
|
||||||
// needed for C++20.
|
|
||||||
explicit EncodableValue(const char* string) : super(std::string(string)) {}
|
|
||||||
EncodableValue& operator=(const char* other) {
|
|
||||||
*this = std::string(other);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow implicit conversion from CustomEncodableValue; the only reason to
|
|
||||||
// make a CustomEncodableValue (which can only be constructed explicitly) is
|
|
||||||
// to use it with EncodableValue, so the risk of unintended conversions is
|
|
||||||
// minimal, and it avoids the need for the verbose:
|
|
||||||
// EncodableValue(CustomEncodableValue(...)).
|
|
||||||
// NOLINTNEXTLINE(google-explicit-constructor)
|
|
||||||
EncodableValue(const CustomEncodableValue& v) : super(v) {}
|
|
||||||
|
|
||||||
// Override the conversion constructors from std::variant to make them
|
|
||||||
// explicit, to avoid implicit conversion.
|
|
||||||
//
|
|
||||||
// While implicit conversion can be convenient in some cases, it can have very
|
|
||||||
// surprising effects. E.g., calling a function that takes an EncodableValue
|
|
||||||
// but accidentally passing an EncodableValue* would, instead of failing to
|
|
||||||
// compile, go through a pointer->bool->EncodableValue(bool) chain and
|
|
||||||
// silently call the function with a temp-constructed EncodableValue(true).
|
|
||||||
template <class T>
|
|
||||||
constexpr explicit EncodableValue(T&& t) noexcept : super(t) {}
|
|
||||||
|
|
||||||
// Returns true if the value is null. Convenience wrapper since unlike the
|
|
||||||
// other types, std::monostate uses aren't self-documenting.
|
|
||||||
bool IsNull() const { return std::holds_alternative<std::monostate>(*this); }
|
|
||||||
|
|
||||||
// Convenience method to simplify handling objects received from Flutter
|
|
||||||
// where the values may be larger than 32-bit, since they have the same type
|
|
||||||
// on the Dart side, but will be either 32-bit or 64-bit here depending on
|
|
||||||
// the value.
|
|
||||||
//
|
|
||||||
// Calling this method if the value doesn't contain either an int32_t or an
|
|
||||||
// int64_t will throw an exception.
|
|
||||||
int64_t LongValue() const {
|
|
||||||
if (std::holds_alternative<int32_t>(*this)) {
|
|
||||||
return std::get<int32_t>(*this);
|
|
||||||
}
|
|
||||||
return std::get<int64_t>(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The C++ Standard Library implementations can get into issues with recursive
|
|
||||||
// constraint satisfaction when (among other things) objects of this type (which
|
|
||||||
// is an `std::variant` subclass) are put into containers like `std::vector`.
|
|
||||||
//
|
|
||||||
// A definition of `operator<` is provided to break that recursion. However, in
|
|
||||||
// C++20 with the latest compilers (Clang compilers newer than 20 and the latest
|
|
||||||
// GCC variants, see https://gcc.godbolt.org/z/KM6n6qane) requiring that that
|
|
||||||
// the `std::three_way_comparable` constraint be satisfied requires the
|
|
||||||
// provision of `operator<=>` to do the same thing.
|
|
||||||
//
|
|
||||||
// The code below makes this translation unit be safe to include from both C++17
|
|
||||||
// and C++20 translation units while also using the newest compilers.
|
|
||||||
//
|
|
||||||
// The correctness of the compiler's gripes with this code and the subsequent
|
|
||||||
// need for these workarounds is not fully understood or explored. If you run
|
|
||||||
// into issues with this code again, the following breadcrumbs may prove
|
|
||||||
// useful. If you cannot access some or all of these links, the compiler
|
|
||||||
// explorer link above should serve a reduced test case to base an investigation
|
|
||||||
// off of.
|
|
||||||
//
|
|
||||||
// * b/423885648#comment8
|
|
||||||
// * b/423885648#comment19
|
|
||||||
// * cl/542631351
|
|
||||||
// * cl/542541552
|
|
||||||
// * https://github.com/flutter/engine/pull/43091
|
|
||||||
//
|
|
||||||
#if __cplusplus >= 202002L
|
|
||||||
friend std::partial_ordering operator<=>(const EncodableValue& lhs,
|
|
||||||
const EncodableValue& rhs) {
|
|
||||||
auto& lv = static_cast<const super&>(lhs);
|
|
||||||
auto& rv = static_cast<const super&>(rhs);
|
|
||||||
|
|
||||||
if (lv < rv) {
|
|
||||||
return std::partial_ordering::less;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rv < lv) {
|
|
||||||
return std::partial_ordering::greater;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lv == rv) {
|
|
||||||
return std::partial_ordering::equivalent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::partial_ordering::unordered;
|
|
||||||
}
|
|
||||||
#else // __cplusplus >= 202002L
|
|
||||||
friend bool operator<(const EncodableValue& lhs, const EncodableValue& rhs) {
|
|
||||||
return static_cast<const super&>(lhs) < static_cast<const super&>(rhs);
|
|
||||||
}
|
|
||||||
#endif // __cplusplus >= 202002L
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_ENCODABLE_VALUE_H_
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_ENGINE_METHOD_RESULT_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_ENGINE_METHOD_RESULT_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "binary_messenger.h"
|
|
||||||
#include "method_codec.h"
|
|
||||||
#include "method_result.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
// Manages the one-time sending of response data. This is an internal helper
|
|
||||||
// class for EngineMethodResult, separated out since the implementation doesn't
|
|
||||||
// vary based on the template type.
|
|
||||||
class ReplyManager {
|
|
||||||
public:
|
|
||||||
explicit ReplyManager(BinaryReply reply_handler_);
|
|
||||||
~ReplyManager();
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
ReplyManager(ReplyManager const&) = delete;
|
|
||||||
ReplyManager& operator=(ReplyManager const&) = delete;
|
|
||||||
|
|
||||||
// Sends the given response data (which must either be nullptr, which
|
|
||||||
// indicates an unhandled method, or a response serialized with |codec_|) to
|
|
||||||
// the engine.
|
|
||||||
void SendResponseData(const std::vector<uint8_t>* data);
|
|
||||||
|
|
||||||
private:
|
|
||||||
BinaryReply reply_handler_;
|
|
||||||
};
|
|
||||||
} // namespace internal
|
|
||||||
|
|
||||||
// Implemention of MethodResult that sends a response to the Flutter engine
|
|
||||||
// exactly once, encoded using a given codec.
|
|
||||||
template <typename T>
|
|
||||||
class EngineMethodResult : public MethodResult<T> {
|
|
||||||
public:
|
|
||||||
// Creates a result object that will send results to |reply_handler|, encoded
|
|
||||||
// using |codec|. The |codec| pointer must remain valid for as long as this
|
|
||||||
// object exists.
|
|
||||||
EngineMethodResult(BinaryReply reply_handler, const MethodCodec<T>* codec)
|
|
||||||
: reply_manager_(
|
|
||||||
std::make_unique<internal::ReplyManager>(std::move(reply_handler))),
|
|
||||||
codec_(codec) {}
|
|
||||||
|
|
||||||
~EngineMethodResult() = default;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// |flutter::MethodResult|
|
|
||||||
void SuccessInternal(const T* result) override {
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> data =
|
|
||||||
codec_->EncodeSuccessEnvelope(result);
|
|
||||||
reply_manager_->SendResponseData(data.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
// |flutter::MethodResult|
|
|
||||||
void ErrorInternal(const std::string& error_code,
|
|
||||||
const std::string& error_message,
|
|
||||||
const T* error_details) override {
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> data =
|
|
||||||
codec_->EncodeErrorEnvelope(error_code, error_message, error_details);
|
|
||||||
reply_manager_->SendResponseData(data.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
// |flutter::MethodResult|
|
|
||||||
void NotImplementedInternal() override {
|
|
||||||
reply_manager_->SendResponseData(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<internal::ReplyManager> reply_manager_;
|
|
||||||
|
|
||||||
const MethodCodec<T>* codec_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_ENGINE_METHOD_RESULT_H_
|
|
||||||
@@ -1,181 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_CHANNEL_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_CHANNEL_H_
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "binary_messenger.h"
|
|
||||||
#include "engine_method_result.h"
|
|
||||||
#include "event_sink.h"
|
|
||||||
#include "event_stream_handler.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
class EncodableValue;
|
|
||||||
|
|
||||||
// A named channel for communicating with the Flutter application using
|
|
||||||
// asynchronous event streams. Incoming requests for event stream setup are
|
|
||||||
// decoded from binary on receipt, and C++ responses and events are encoded into
|
|
||||||
// binary before being transmitted back to Flutter. The MethodCodec used must be
|
|
||||||
// compatible with the one used by the Flutter application. This can be achieved
|
|
||||||
// by creating an EventChannel
|
|
||||||
// ("https://api.flutter.dev/flutter/services/EventChannel-class.html")
|
|
||||||
// counterpart of this channel on the Dart side.
|
|
||||||
// The C++ type of stream configuration arguments, events, and error details are
|
|
||||||
// templated, but only values supported by the specified MethodCodec can be
|
|
||||||
// used.
|
|
||||||
template <typename T = EncodableValue>
|
|
||||||
class EventChannel {
|
|
||||||
public:
|
|
||||||
// Creates an instance that sends and receives event handler on the channel
|
|
||||||
// named |name|, encoded with |codec| and dispatched via |messenger|.
|
|
||||||
EventChannel(BinaryMessenger* messenger,
|
|
||||||
const std::string& name,
|
|
||||||
const MethodCodec<T>* codec)
|
|
||||||
: messenger_(messenger), name_(name), codec_(codec) {}
|
|
||||||
~EventChannel() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
EventChannel(EventChannel const&) = delete;
|
|
||||||
EventChannel& operator=(EventChannel const&) = delete;
|
|
||||||
|
|
||||||
// Registers a stream handler on this channel.
|
|
||||||
// If no handler has been registered, any incoming stream setup requests will
|
|
||||||
// be handled silently by providing an empty stream.
|
|
||||||
//
|
|
||||||
// Note that the EventChannel does not own the handler and will not
|
|
||||||
// unregister it on destruction. The caller is responsible for unregistering
|
|
||||||
// the handler if it should no longer be called.
|
|
||||||
void SetStreamHandler(std::unique_ptr<StreamHandler<T>> handler) {
|
|
||||||
if (!handler) {
|
|
||||||
messenger_->SetMessageHandler(name_, nullptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::function requires a copyable lambda, so convert to a shared pointer.
|
|
||||||
// This is safe since only one copy of the shared_pointer will ever be
|
|
||||||
// accessed.
|
|
||||||
std::shared_ptr<StreamHandler<T>> shared_handler(handler.release());
|
|
||||||
const MethodCodec<T>* codec = codec_;
|
|
||||||
const std::string channel_name = name_;
|
|
||||||
const BinaryMessenger* messenger = messenger_;
|
|
||||||
BinaryMessageHandler binary_handler =
|
|
||||||
[shared_handler, codec, channel_name, messenger,
|
|
||||||
// Mutable state to track the handler's listening status.
|
|
||||||
is_listening = false](const uint8_t* message,
|
|
||||||
const size_t message_size,
|
|
||||||
const BinaryReply& reply) mutable {
|
|
||||||
constexpr char kOnListenMethod[] = "listen";
|
|
||||||
constexpr char kOnCancelMethod[] = "cancel";
|
|
||||||
|
|
||||||
std::unique_ptr<MethodCall<T>> method_call =
|
|
||||||
codec->DecodeMethodCall(message, message_size);
|
|
||||||
if (!method_call) {
|
|
||||||
std::cerr
|
|
||||||
<< "Unable to construct method call from message on channel: "
|
|
||||||
<< channel_name << std::endl;
|
|
||||||
reply(nullptr, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string& method = method_call->method_name();
|
|
||||||
if (method.compare(kOnListenMethod) == 0) {
|
|
||||||
if (is_listening) {
|
|
||||||
std::unique_ptr<StreamHandlerError<T>> error =
|
|
||||||
shared_handler->OnCancel(nullptr);
|
|
||||||
if (error) {
|
|
||||||
std::cerr << "Failed to cancel existing stream: "
|
|
||||||
<< (error->error_code) << ", "
|
|
||||||
<< (error->error_message) << ", "
|
|
||||||
<< (error->error_details);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is_listening = true;
|
|
||||||
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> result;
|
|
||||||
auto sink = std::make_unique<EventSinkImplementation>(
|
|
||||||
messenger, channel_name, codec);
|
|
||||||
std::unique_ptr<StreamHandlerError<T>> error =
|
|
||||||
shared_handler->OnListen(method_call->arguments(),
|
|
||||||
std::move(sink));
|
|
||||||
if (error) {
|
|
||||||
result = codec->EncodeErrorEnvelope(error->error_code,
|
|
||||||
error->error_message,
|
|
||||||
error->error_details.get());
|
|
||||||
} else {
|
|
||||||
result = codec->EncodeSuccessEnvelope();
|
|
||||||
}
|
|
||||||
reply(result->data(), result->size());
|
|
||||||
} else if (method.compare(kOnCancelMethod) == 0) {
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> result;
|
|
||||||
if (is_listening) {
|
|
||||||
std::unique_ptr<StreamHandlerError<T>> error =
|
|
||||||
shared_handler->OnCancel(method_call->arguments());
|
|
||||||
if (error) {
|
|
||||||
result = codec->EncodeErrorEnvelope(error->error_code,
|
|
||||||
error->error_message,
|
|
||||||
error->error_details.get());
|
|
||||||
} else {
|
|
||||||
result = codec->EncodeSuccessEnvelope();
|
|
||||||
}
|
|
||||||
is_listening = false;
|
|
||||||
} else {
|
|
||||||
result = codec->EncodeErrorEnvelope(
|
|
||||||
"error", "No active stream to cancel", nullptr);
|
|
||||||
}
|
|
||||||
reply(result->data(), result->size());
|
|
||||||
} else {
|
|
||||||
reply(nullptr, 0);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
messenger_->SetMessageHandler(name_, std::move(binary_handler));
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
class EventSinkImplementation : public EventSink<T> {
|
|
||||||
public:
|
|
||||||
EventSinkImplementation(const BinaryMessenger* messenger,
|
|
||||||
const std::string& name,
|
|
||||||
const MethodCodec<T>* codec)
|
|
||||||
: messenger_(messenger), name_(name), codec_(codec) {}
|
|
||||||
~EventSinkImplementation() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
EventSinkImplementation(EventSinkImplementation const&) = delete;
|
|
||||||
EventSinkImplementation& operator=(EventSinkImplementation const&) = delete;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const BinaryMessenger* messenger_;
|
|
||||||
const std::string name_;
|
|
||||||
const MethodCodec<T>* codec_;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void SuccessInternal(const T* event = nullptr) override {
|
|
||||||
auto result = codec_->EncodeSuccessEnvelope(event);
|
|
||||||
messenger_->Send(name_, result->data(), result->size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void ErrorInternal(const std::string& error_code,
|
|
||||||
const std::string& error_message,
|
|
||||||
const T* error_details) override {
|
|
||||||
auto result =
|
|
||||||
codec_->EncodeErrorEnvelope(error_code, error_message, error_details);
|
|
||||||
messenger_->Send(name_, result->data(), result->size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EndOfStreamInternal() override { messenger_->Send(name_, nullptr, 0); }
|
|
||||||
};
|
|
||||||
|
|
||||||
BinaryMessenger* messenger_;
|
|
||||||
const std::string name_;
|
|
||||||
const MethodCodec<T>* codec_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_CHANNEL_H_
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_SINK_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_SINK_H_
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
class EncodableValue;
|
|
||||||
|
|
||||||
// Event callback. Events to be sent to Flutter application
|
|
||||||
// act as clients of this interface for sending events.
|
|
||||||
template <typename T = EncodableValue>
|
|
||||||
class EventSink {
|
|
||||||
public:
|
|
||||||
EventSink() = default;
|
|
||||||
virtual ~EventSink() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
EventSink(EventSink const&) = delete;
|
|
||||||
EventSink& operator=(EventSink const&) = delete;
|
|
||||||
|
|
||||||
// Consumes a successful event
|
|
||||||
void Success(const T& event) { SuccessInternal(&event); }
|
|
||||||
|
|
||||||
// Consumes a successful event.
|
|
||||||
void Success() { SuccessInternal(nullptr); }
|
|
||||||
|
|
||||||
// Consumes an error event.
|
|
||||||
void Error(const std::string& error_code,
|
|
||||||
const std::string& error_message,
|
|
||||||
const T& error_details) {
|
|
||||||
ErrorInternal(error_code, error_message, &error_details);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consumes an error event.
|
|
||||||
void Error(const std::string& error_code,
|
|
||||||
const std::string& error_message = "") {
|
|
||||||
ErrorInternal(error_code, error_message, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Consumes end of stream. Ensuing calls to Success() or
|
|
||||||
// Error(), if any, are ignored.
|
|
||||||
void EndOfStream() { EndOfStreamInternal(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual void SuccessInternal(const T* event = nullptr) = 0;
|
|
||||||
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual void ErrorInternal(const std::string& error_code,
|
|
||||||
const std::string& error_message,
|
|
||||||
const T* error_details) = 0;
|
|
||||||
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual void EndOfStreamInternal() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_SINK_H_
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "event_sink.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
class EncodableValue;
|
|
||||||
|
|
||||||
template <typename T = EncodableValue>
|
|
||||||
struct StreamHandlerError {
|
|
||||||
const std::string error_code;
|
|
||||||
const std::string error_message;
|
|
||||||
const std::unique_ptr<T> error_details;
|
|
||||||
|
|
||||||
StreamHandlerError(const std::string& error_code,
|
|
||||||
const std::string& error_message,
|
|
||||||
std::unique_ptr<T>&& error_details)
|
|
||||||
: error_code(error_code),
|
|
||||||
error_message(error_message),
|
|
||||||
error_details(std::move(error_details)) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handler for stream setup and teardown requests.
|
|
||||||
// Implementations must be prepared to accept sequences of alternating calls to
|
|
||||||
// OnListen() and OnCancel(). Implementations should ideally consume no
|
|
||||||
// resources when the last such call is not OnListen(). In typical situations,
|
|
||||||
// this means that the implementation should register itself with
|
|
||||||
// platform-specific event sources OnListen() and deregister again OnCancel().
|
|
||||||
template <typename T = EncodableValue>
|
|
||||||
class StreamHandler {
|
|
||||||
public:
|
|
||||||
StreamHandler() = default;
|
|
||||||
virtual ~StreamHandler() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
StreamHandler(StreamHandler const&) = delete;
|
|
||||||
StreamHandler& operator=(StreamHandler const&) = delete;
|
|
||||||
|
|
||||||
// Handles a request to set up an event stream. Returns nullptr on success,
|
|
||||||
// or an error on failure.
|
|
||||||
// |arguments| is stream configuration arguments and
|
|
||||||
// |events| is an EventSink for emitting events to the Flutter receiver.
|
|
||||||
std::unique_ptr<StreamHandlerError<T>> OnListen(
|
|
||||||
const T* arguments,
|
|
||||||
std::unique_ptr<EventSink<T>>&& events) {
|
|
||||||
return OnListenInternal(arguments, std::move(events));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handles a request to tear down the most recently created event stream.
|
|
||||||
// Returns nullptr on success, or an error on failure.
|
|
||||||
// |arguments| is stream configuration arguments.
|
|
||||||
std::unique_ptr<StreamHandlerError<T>> OnCancel(const T* arguments) {
|
|
||||||
return OnCancelInternal(arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual std::unique_ptr<StreamHandlerError<T>> OnListenInternal(
|
|
||||||
const T* arguments,
|
|
||||||
std::unique_ptr<EventSink<T>>&& events) = 0;
|
|
||||||
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual std::unique_ptr<StreamHandlerError<T>> OnCancelInternal(
|
|
||||||
const T* arguments) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_H_
|
|
||||||
-78
@@ -1,78 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_FUNCTIONS_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_FUNCTIONS_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "event_sink.h"
|
|
||||||
#include "event_stream_handler.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
class EncodableValue;
|
|
||||||
|
|
||||||
// Handler types for each of the StreamHandler setup and teardown
|
|
||||||
// requests.
|
|
||||||
template <typename T>
|
|
||||||
using StreamHandlerListen =
|
|
||||||
std::function<std::unique_ptr<StreamHandlerError<T>>(
|
|
||||||
const T* arguments,
|
|
||||||
std::unique_ptr<EventSink<T>>&& events)>;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
using StreamHandlerCancel =
|
|
||||||
std::function<std::unique_ptr<StreamHandlerError<T>>(const T* arguments)>;
|
|
||||||
|
|
||||||
// An implementation of StreamHandler that pass calls through to
|
|
||||||
// provided function objects.
|
|
||||||
template <typename T = EncodableValue>
|
|
||||||
class StreamHandlerFunctions : public StreamHandler<T> {
|
|
||||||
public:
|
|
||||||
// Creates a handler object that calls the provided functions
|
|
||||||
// for the corresponding StreamHandler outcomes.
|
|
||||||
StreamHandlerFunctions(StreamHandlerListen<T> on_listen,
|
|
||||||
StreamHandlerCancel<T> on_cancel)
|
|
||||||
: on_listen_(std::move(on_listen)), on_cancel_(std::move(on_cancel)) {}
|
|
||||||
|
|
||||||
virtual ~StreamHandlerFunctions() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
StreamHandlerFunctions(StreamHandlerFunctions const&) = delete;
|
|
||||||
StreamHandlerFunctions& operator=(StreamHandlerFunctions const&) = delete;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// |flutter::StreamHandler|
|
|
||||||
std::unique_ptr<StreamHandlerError<T>> OnListenInternal(
|
|
||||||
const T* arguments,
|
|
||||||
std::unique_ptr<EventSink<T>>&& events) override {
|
|
||||||
if (on_listen_) {
|
|
||||||
return on_listen_(arguments, std::move(events));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto error = std::make_unique<StreamHandlerError<T>>(
|
|
||||||
"error", "No OnListen handler set", nullptr);
|
|
||||||
return std::move(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// |flutter::StreamHandler|
|
|
||||||
std::unique_ptr<StreamHandlerError<T>> OnCancelInternal(
|
|
||||||
const T* arguments) override {
|
|
||||||
if (on_cancel_) {
|
|
||||||
return on_cancel_(arguments);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto error = std::make_unique<StreamHandlerError<T>>(
|
|
||||||
"error", "No OnCancel handler set", nullptr);
|
|
||||||
return std::move(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
StreamHandlerListen<T> on_listen_;
|
|
||||||
StreamHandlerCancel<T> on_cancel_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_FUNCTIONS_H_
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_ENGINE_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_ENGINE_H_
|
|
||||||
|
|
||||||
#include <flutter_windows.h>
|
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "binary_messenger.h"
|
|
||||||
#include "dart_project.h"
|
|
||||||
#include "plugin_registrar.h"
|
|
||||||
#include "plugin_registry.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// An instance of a Flutter engine.
|
|
||||||
//
|
|
||||||
// In the future, this will be the API surface used for all interactions with
|
|
||||||
// the engine, rather than having them duplicated on FlutterViewController.
|
|
||||||
// For now it is only used in the rare case where you need a headless Flutter
|
|
||||||
// engine.
|
|
||||||
class FlutterEngine : public PluginRegistry {
|
|
||||||
public:
|
|
||||||
// Creates a new engine for running the given project.
|
|
||||||
explicit FlutterEngine(const DartProject& project);
|
|
||||||
|
|
||||||
virtual ~FlutterEngine();
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
FlutterEngine(FlutterEngine const&) = delete;
|
|
||||||
FlutterEngine& operator=(FlutterEngine const&) = delete;
|
|
||||||
|
|
||||||
// Starts running the engine at the entrypoint function specified in the
|
|
||||||
// DartProject used to configure the engine, or main() by default.
|
|
||||||
bool Run();
|
|
||||||
|
|
||||||
// Starts running the engine, with an optional entry point.
|
|
||||||
//
|
|
||||||
// If provided, entry_point must be the name of a top-level function from the
|
|
||||||
// same Dart library that contains the app's main() function, and must be
|
|
||||||
// decorated with `@pragma(vm:entry-point)` to ensure the method is not
|
|
||||||
// tree-shaken by the Dart compiler. If not provided, defaults to main().
|
|
||||||
bool Run(const char* entry_point);
|
|
||||||
|
|
||||||
// Terminates the running engine.
|
|
||||||
void ShutDown();
|
|
||||||
|
|
||||||
// Processes any pending events in the Flutter engine, and returns the
|
|
||||||
// nanosecond delay until the next scheduled event (or max, if none).
|
|
||||||
//
|
|
||||||
// This should be called on every run of the application-level runloop, and
|
|
||||||
// a wait for native events in the runloop should never be longer than the
|
|
||||||
// last return value from this function.
|
|
||||||
std::chrono::nanoseconds ProcessMessages();
|
|
||||||
|
|
||||||
// Tells the engine that the system font list has changed. Should be called
|
|
||||||
// by clients when OS-level font changes happen (e.g., WM_FONTCHANGE in a
|
|
||||||
// Win32 application).
|
|
||||||
void ReloadSystemFonts();
|
|
||||||
|
|
||||||
// Tells the engine that the platform brightness value has changed. Should be
|
|
||||||
// called by clients when OS-level theme changes happen (e.g.,
|
|
||||||
// WM_DWMCOLORIZATIONCOLORCHANGED in a Win32 application).
|
|
||||||
void ReloadPlatformBrightness();
|
|
||||||
|
|
||||||
// flutter::PluginRegistry:
|
|
||||||
FlutterDesktopPluginRegistrarRef GetRegistrarForPlugin(
|
|
||||||
const std::string& plugin_name) override;
|
|
||||||
|
|
||||||
// Returns the messenger to use for creating channels to communicate with the
|
|
||||||
// Flutter engine.
|
|
||||||
//
|
|
||||||
// This pointer will remain valid for the lifetime of this instance.
|
|
||||||
BinaryMessenger* messenger() { return messenger_.get(); }
|
|
||||||
|
|
||||||
// Schedule a callback to be called after the next frame is drawn.
|
|
||||||
//
|
|
||||||
// This must be called from the platform thread. The callback is executed only
|
|
||||||
// once on the platform thread.
|
|
||||||
void SetNextFrameCallback(std::function<void()> callback);
|
|
||||||
|
|
||||||
// Called to pass an external window message to the engine for lifecycle
|
|
||||||
// state updates. Non-Flutter windows must call this method in their WndProc
|
|
||||||
// in order to be included in the logic for application lifecycle state
|
|
||||||
// updates. Returns a result if the message should be consumed.
|
|
||||||
std::optional<LRESULT> ProcessExternalWindowMessage(HWND hwnd,
|
|
||||||
UINT message,
|
|
||||||
WPARAM wparam,
|
|
||||||
LPARAM lparam);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// For access to the engine handle.
|
|
||||||
friend class FlutterViewController;
|
|
||||||
|
|
||||||
// Gives up ownership of |engine_|, but keeps a weak reference to it.
|
|
||||||
//
|
|
||||||
// This is intended to be used by FlutterViewController, since the underlying
|
|
||||||
// C API for view controllers takes over engine ownership.
|
|
||||||
FlutterDesktopEngineRef RelinquishEngine();
|
|
||||||
|
|
||||||
// Handle for interacting with the C API's engine reference.
|
|
||||||
FlutterDesktopEngineRef engine_ = nullptr;
|
|
||||||
|
|
||||||
// Messenger for communicating with the engine.
|
|
||||||
std::unique_ptr<BinaryMessenger> messenger_;
|
|
||||||
|
|
||||||
// Whether or not this wrapper owns |engine_|.
|
|
||||||
bool owns_engine_ = true;
|
|
||||||
|
|
||||||
// Whether |Run| has been called successfully.
|
|
||||||
//
|
|
||||||
// This is used to improve error messages. This can be false while the engine
|
|
||||||
// is running if the engine was started by creating a view.
|
|
||||||
bool run_succeeded_ = false;
|
|
||||||
|
|
||||||
// The callback to execute once the next frame is drawn.
|
|
||||||
std::function<void()> next_frame_callback_ = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_ENGINE_H_
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_H_
|
|
||||||
|
|
||||||
#include <flutter_windows.h>
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// The unique identifier for a view.
|
|
||||||
typedef int64_t FlutterViewId;
|
|
||||||
|
|
||||||
// A view displaying Flutter content.
|
|
||||||
class FlutterView {
|
|
||||||
public:
|
|
||||||
explicit FlutterView(FlutterDesktopViewRef view) : view_(view) {}
|
|
||||||
|
|
||||||
// Destroys this reference to the view. The underlying view is not destroyed.
|
|
||||||
virtual ~FlutterView() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
FlutterView(FlutterView const&) = delete;
|
|
||||||
FlutterView& operator=(FlutterView const&) = delete;
|
|
||||||
|
|
||||||
// Returns the backing HWND for the view.
|
|
||||||
HWND GetNativeWindow() { return FlutterDesktopViewGetHWND(view_); }
|
|
||||||
|
|
||||||
// Returns the DXGI adapter used for rendering or nullptr in case of error.
|
|
||||||
IDXGIAdapter* GetGraphicsAdapter() {
|
|
||||||
return FlutterDesktopViewGetGraphicsAdapter(view_);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Handle for interacting with the C API's view.
|
|
||||||
FlutterDesktopViewRef view_ = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_H_
|
|
||||||
-76
@@ -1,76 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_CONTROLLER_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_CONTROLLER_H_
|
|
||||||
|
|
||||||
#include <flutter_windows.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#include "dart_project.h"
|
|
||||||
#include "flutter_engine.h"
|
|
||||||
#include "flutter_view.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// A controller for a view displaying Flutter content.
|
|
||||||
//
|
|
||||||
// This is the primary wrapper class for the desktop C API.
|
|
||||||
// If you use this class, you should not call any of the setup or teardown
|
|
||||||
// methods in the C API directly, as this class will do that internally.
|
|
||||||
class FlutterViewController {
|
|
||||||
public:
|
|
||||||
// Creates a FlutterView that can be parented into a Windows View hierarchy
|
|
||||||
// either using HWNDs.
|
|
||||||
//
|
|
||||||
// This also creates a new FlutterEngine.
|
|
||||||
//
|
|
||||||
// |dart_project| will be used to configure the engine backing this view.
|
|
||||||
FlutterViewController(int width, int height, const DartProject& project);
|
|
||||||
|
|
||||||
virtual ~FlutterViewController();
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
FlutterViewController(FlutterViewController const&) = delete;
|
|
||||||
FlutterViewController& operator=(FlutterViewController const&) = delete;
|
|
||||||
|
|
||||||
// Returns the view controller's view ID.
|
|
||||||
FlutterViewId view_id() const;
|
|
||||||
|
|
||||||
// Returns the engine running Flutter content in this view.
|
|
||||||
FlutterEngine* engine() const { return engine_.get(); }
|
|
||||||
|
|
||||||
// Returns the view managed by this controller.
|
|
||||||
FlutterView* view() const { return view_.get(); }
|
|
||||||
|
|
||||||
// Requests new frame from the engine and repaints the view.
|
|
||||||
void ForceRedraw();
|
|
||||||
|
|
||||||
// Allows the Flutter engine and any interested plugins an opportunity to
|
|
||||||
// handle the given message.
|
|
||||||
//
|
|
||||||
// If a result is returned, then the message was handled in such a way that
|
|
||||||
// further handling should not be done.
|
|
||||||
std::optional<LRESULT> HandleTopLevelWindowProc(HWND hwnd,
|
|
||||||
UINT message,
|
|
||||||
WPARAM wparam,
|
|
||||||
LPARAM lparam);
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Handle for interacting with the C API's view controller, if any.
|
|
||||||
FlutterDesktopViewControllerRef controller_ = nullptr;
|
|
||||||
|
|
||||||
// The backing engine
|
|
||||||
std::shared_ptr<FlutterEngine> engine_;
|
|
||||||
|
|
||||||
// The owned FlutterView.
|
|
||||||
std::unique_ptr<FlutterView> view_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_CONTROLLER_H_
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_MESSAGE_CODEC_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_MESSAGE_CODEC_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// Translates between a binary message and higher-level method call and
|
|
||||||
// response/error objects.
|
|
||||||
template <typename T>
|
|
||||||
class MessageCodec {
|
|
||||||
public:
|
|
||||||
MessageCodec() = default;
|
|
||||||
|
|
||||||
virtual ~MessageCodec() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
MessageCodec(MessageCodec<T> const&) = delete;
|
|
||||||
MessageCodec& operator=(MessageCodec<T> const&) = delete;
|
|
||||||
|
|
||||||
// Returns the message encoded in |binary_message|, or nullptr if it cannot be
|
|
||||||
// decoded by this codec.
|
|
||||||
std::unique_ptr<T> DecodeMessage(const uint8_t* binary_message,
|
|
||||||
const size_t message_size) const {
|
|
||||||
return std::move(DecodeMessageInternal(binary_message, message_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the message encoded in |binary_message|, or nullptr if it cannot be
|
|
||||||
// decoded by this codec.
|
|
||||||
std::unique_ptr<T> DecodeMessage(
|
|
||||||
const std::vector<uint8_t>& binary_message) const {
|
|
||||||
size_t size = binary_message.size();
|
|
||||||
const uint8_t* data = size > 0 ? &binary_message[0] : nullptr;
|
|
||||||
return std::move(DecodeMessageInternal(data, size));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a binary encoding of the given |message|, or nullptr if the
|
|
||||||
// message cannot be serialized by this codec.
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> EncodeMessage(const T& message) const {
|
|
||||||
return std::move(EncodeMessageInternal(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual std::unique_ptr<T> DecodeMessageInternal(
|
|
||||||
const uint8_t* binary_message,
|
|
||||||
const size_t message_size) const = 0;
|
|
||||||
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual std::unique_ptr<std::vector<uint8_t>> EncodeMessageInternal(
|
|
||||||
const T& message) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_MESSAGE_CODEC_H_
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CALL_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CALL_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
class EncodableValue;
|
|
||||||
|
|
||||||
// An object encapsulating a method call from Flutter whose arguments are of
|
|
||||||
// type T.
|
|
||||||
template <typename T = EncodableValue>
|
|
||||||
class MethodCall {
|
|
||||||
public:
|
|
||||||
// Creates a MethodCall with the given name and arguments.
|
|
||||||
MethodCall(const std::string& method_name, std::unique_ptr<T> arguments)
|
|
||||||
: method_name_(method_name), arguments_(std::move(arguments)) {}
|
|
||||||
|
|
||||||
virtual ~MethodCall() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
MethodCall(MethodCall<T> const&) = delete;
|
|
||||||
MethodCall& operator=(MethodCall<T> const&) = delete;
|
|
||||||
|
|
||||||
// The name of the method being called.
|
|
||||||
const std::string& method_name() const { return method_name_; }
|
|
||||||
|
|
||||||
// The arguments to the method call, or NULL if there are none.
|
|
||||||
const T* arguments() const { return arguments_.get(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string method_name_;
|
|
||||||
std::unique_ptr<T> arguments_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CALL_H_
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CHANNEL_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CHANNEL_H_
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "basic_message_channel.h"
|
|
||||||
#include "binary_messenger.h"
|
|
||||||
#include "engine_method_result.h"
|
|
||||||
#include "method_call.h"
|
|
||||||
#include "method_codec.h"
|
|
||||||
#include "method_result.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
class EncodableValue;
|
|
||||||
|
|
||||||
// A handler for receiving a method call from the Flutter engine.
|
|
||||||
//
|
|
||||||
// Implementations must asynchronously call exactly one of the methods on
|
|
||||||
// |result| to indicate the result of the method call.
|
|
||||||
template <typename T>
|
|
||||||
using MethodCallHandler =
|
|
||||||
std::function<void(const MethodCall<T>& call,
|
|
||||||
std::unique_ptr<MethodResult<T>> result)>;
|
|
||||||
|
|
||||||
// A channel for communicating with the Flutter engine using invocation of
|
|
||||||
// asynchronous methods.
|
|
||||||
template <typename T = EncodableValue>
|
|
||||||
class MethodChannel {
|
|
||||||
public:
|
|
||||||
// Creates an instance that sends and receives method calls on the channel
|
|
||||||
// named |name|, encoded with |codec| and dispatched via |messenger|.
|
|
||||||
MethodChannel(BinaryMessenger* messenger,
|
|
||||||
const std::string& name,
|
|
||||||
const MethodCodec<T>* codec)
|
|
||||||
: messenger_(messenger), name_(name), codec_(codec) {}
|
|
||||||
|
|
||||||
~MethodChannel() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
MethodChannel(MethodChannel const&) = delete;
|
|
||||||
MethodChannel& operator=(MethodChannel const&) = delete;
|
|
||||||
|
|
||||||
// Sends a message to the Flutter engine on this channel.
|
|
||||||
//
|
|
||||||
// If |result| is provided, one of its methods will be invoked with the
|
|
||||||
// response from the engine.
|
|
||||||
void InvokeMethod(const std::string& method,
|
|
||||||
std::unique_ptr<T> arguments,
|
|
||||||
std::unique_ptr<MethodResult<T>> result = nullptr) {
|
|
||||||
MethodCall<T> method_call(method, std::move(arguments));
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> message =
|
|
||||||
codec_->EncodeMethodCall(method_call);
|
|
||||||
if (!result) {
|
|
||||||
messenger_->Send(name_, message->data(), message->size(), nullptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// std::function requires a copyable lambda, so convert to a shared pointer.
|
|
||||||
// This is safe since only one copy of the shared_pointer will ever be
|
|
||||||
// accessed.
|
|
||||||
std::shared_ptr<MethodResult<T>> shared_result(result.release());
|
|
||||||
const auto* codec = codec_;
|
|
||||||
std::string channel_name = name_;
|
|
||||||
BinaryReply reply_handler = [shared_result, codec, channel_name](
|
|
||||||
const uint8_t* reply, size_t reply_size) {
|
|
||||||
if (reply_size == 0) {
|
|
||||||
shared_result->NotImplemented();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Use this channel's codec to decode and handle the
|
|
||||||
// reply.
|
|
||||||
bool decoded = codec->DecodeAndProcessResponseEnvelope(
|
|
||||||
reply, reply_size, shared_result.get());
|
|
||||||
if (!decoded) {
|
|
||||||
std::cerr << "Unable to decode reply to method "
|
|
||||||
"invocation on channel "
|
|
||||||
<< channel_name << std::endl;
|
|
||||||
shared_result->NotImplemented();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
messenger_->Send(name_, message->data(), message->size(),
|
|
||||||
std::move(reply_handler));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registers a handler that should be called any time a method call is
|
|
||||||
// received on this channel. A null handler will remove any previous handler.
|
|
||||||
//
|
|
||||||
// The handler will be owned by the underlying BinaryMessageHandler.
|
|
||||||
// Destroying the MethodChannel will not unregister the handler, so
|
|
||||||
// the caller is responsible for unregistering explicitly if the handler
|
|
||||||
// stops being valid before the engine is destroyed.
|
|
||||||
void SetMethodCallHandler(const MethodCallHandler<T>& handler) const {
|
|
||||||
if (!handler) {
|
|
||||||
messenger_->SetMessageHandler(name_, nullptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const auto* codec = codec_;
|
|
||||||
std::string channel_name = name_;
|
|
||||||
BinaryMessageHandler binary_handler = [handler, codec, channel_name](
|
|
||||||
const uint8_t* message,
|
|
||||||
size_t message_size,
|
|
||||||
BinaryReply reply) {
|
|
||||||
// Use this channel's codec to decode the call and build a result handler.
|
|
||||||
auto result =
|
|
||||||
std::make_unique<EngineMethodResult<T>>(std::move(reply), codec);
|
|
||||||
std::unique_ptr<MethodCall<T>> method_call =
|
|
||||||
codec->DecodeMethodCall(message, message_size);
|
|
||||||
if (!method_call) {
|
|
||||||
std::cerr << "Unable to construct method call from message on channel "
|
|
||||||
<< channel_name << std::endl;
|
|
||||||
result->NotImplemented();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handler(*method_call, std::move(result));
|
|
||||||
};
|
|
||||||
messenger_->SetMessageHandler(name_, std::move(binary_handler));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adjusts the number of messages that will get buffered when sending messages
|
|
||||||
// to channels that aren't fully set up yet. For example, the engine isn't
|
|
||||||
// running yet or the channel's message handler isn't set up on the Dart side
|
|
||||||
// yet.
|
|
||||||
void Resize(int new_size) {
|
|
||||||
internal::ResizeChannel(messenger_, name_, new_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defines whether the channel should show warning messages when discarding
|
|
||||||
// messages due to overflow.
|
|
||||||
//
|
|
||||||
// When |warns| is false, the channel is expected to overflow and warning
|
|
||||||
// messages will not be shown.
|
|
||||||
void SetWarnsOnOverflow(bool warns) {
|
|
||||||
internal::SetChannelWarnsOnOverflow(messenger_, name_, warns);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
BinaryMessenger* messenger_;
|
|
||||||
std::string name_;
|
|
||||||
const MethodCodec<T>* codec_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CHANNEL_H_
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CODEC_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CODEC_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "method_call.h"
|
|
||||||
#include "method_result.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// Translates between a binary message and higher-level method call and
|
|
||||||
// response/error objects.
|
|
||||||
template <typename T>
|
|
||||||
class MethodCodec {
|
|
||||||
public:
|
|
||||||
MethodCodec() = default;
|
|
||||||
|
|
||||||
virtual ~MethodCodec() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
MethodCodec(MethodCodec<T> const&) = delete;
|
|
||||||
MethodCodec& operator=(MethodCodec<T> const&) = delete;
|
|
||||||
|
|
||||||
// Returns the MethodCall encoded in |message|, or nullptr if it cannot be
|
|
||||||
// decoded.
|
|
||||||
std::unique_ptr<MethodCall<T>> DecodeMethodCall(const uint8_t* message,
|
|
||||||
size_t message_size) const {
|
|
||||||
return std::move(DecodeMethodCallInternal(message, message_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the MethodCall encoded in |message|, or nullptr if it cannot be
|
|
||||||
// decoded.
|
|
||||||
std::unique_ptr<MethodCall<T>> DecodeMethodCall(
|
|
||||||
const std::vector<uint8_t>& message) const {
|
|
||||||
size_t size = message.size();
|
|
||||||
const uint8_t* data = size > 0 ? &message[0] : nullptr;
|
|
||||||
return std::move(DecodeMethodCallInternal(data, size));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a binary encoding of the given |method_call|, or nullptr if the
|
|
||||||
// method call cannot be serialized by this codec.
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> EncodeMethodCall(
|
|
||||||
const MethodCall<T>& method_call) const {
|
|
||||||
return std::move(EncodeMethodCallInternal(method_call));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a binary encoding of |result|. |result| must be a type supported
|
|
||||||
// by the codec.
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> EncodeSuccessEnvelope(
|
|
||||||
const T* result = nullptr) const {
|
|
||||||
return std::move(EncodeSuccessEnvelopeInternal(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns a binary encoding of |error|. The |error_details| must be a type
|
|
||||||
// supported by the codec.
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> EncodeErrorEnvelope(
|
|
||||||
const std::string& error_code,
|
|
||||||
const std::string& error_message = "",
|
|
||||||
const T* error_details = nullptr) const {
|
|
||||||
return std::move(
|
|
||||||
EncodeErrorEnvelopeInternal(error_code, error_message, error_details));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decodes the response envelope encoded in |response|, calling the
|
|
||||||
// appropriate method on |result|.
|
|
||||||
//
|
|
||||||
// Returns false if |response| cannot be decoded. In that case the caller is
|
|
||||||
// responsible for calling a |result| method.
|
|
||||||
bool DecodeAndProcessResponseEnvelope(const uint8_t* response,
|
|
||||||
size_t response_size,
|
|
||||||
MethodResult<T>* result) const {
|
|
||||||
return DecodeAndProcessResponseEnvelopeInternal(response, response_size,
|
|
||||||
result);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual std::unique_ptr<MethodCall<T>> DecodeMethodCallInternal(
|
|
||||||
const uint8_t* message,
|
|
||||||
size_t message_size) const = 0;
|
|
||||||
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual std::unique_ptr<std::vector<uint8_t>> EncodeMethodCallInternal(
|
|
||||||
const MethodCall<T>& method_call) const = 0;
|
|
||||||
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual std::unique_ptr<std::vector<uint8_t>> EncodeSuccessEnvelopeInternal(
|
|
||||||
const T* result) const = 0;
|
|
||||||
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual std::unique_ptr<std::vector<uint8_t>> EncodeErrorEnvelopeInternal(
|
|
||||||
const std::string& error_code,
|
|
||||||
const std::string& error_message,
|
|
||||||
const T* error_details) const = 0;
|
|
||||||
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual bool DecodeAndProcessResponseEnvelopeInternal(
|
|
||||||
const uint8_t* response,
|
|
||||||
size_t response_size,
|
|
||||||
MethodResult<T>* result) const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_CODEC_H_
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
class EncodableValue;
|
|
||||||
|
|
||||||
// Encapsulates a result returned from a MethodCall. Only one method should be
|
|
||||||
// called on any given instance.
|
|
||||||
template <typename T = EncodableValue>
|
|
||||||
class MethodResult {
|
|
||||||
public:
|
|
||||||
MethodResult() = default;
|
|
||||||
|
|
||||||
virtual ~MethodResult() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
MethodResult(MethodResult const&) = delete;
|
|
||||||
MethodResult& operator=(MethodResult const&) = delete;
|
|
||||||
|
|
||||||
// Sends a success response, indicating that the call completed successfully
|
|
||||||
// with the given result.
|
|
||||||
void Success(const T& result) { SuccessInternal(&result); }
|
|
||||||
|
|
||||||
// Sends a success response, indicating that the call completed successfully
|
|
||||||
// with no result.
|
|
||||||
void Success() { SuccessInternal(nullptr); }
|
|
||||||
|
|
||||||
// Sends an error response, indicating that the call was understood but
|
|
||||||
// handling failed in some way.
|
|
||||||
//
|
|
||||||
// error_code: A string error code describing the error.
|
|
||||||
// error_message: A user-readable error message.
|
|
||||||
// error_details: Arbitrary extra details about the error.
|
|
||||||
void Error(const std::string& error_code,
|
|
||||||
const std::string& error_message,
|
|
||||||
const T& error_details) {
|
|
||||||
ErrorInternal(error_code, error_message, &error_details);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sends an error response, indicating that the call was understood but
|
|
||||||
// handling failed in some way.
|
|
||||||
//
|
|
||||||
// error_code: A string error code describing the error.
|
|
||||||
// error_message: A user-readable error message (optional).
|
|
||||||
void Error(const std::string& error_code,
|
|
||||||
const std::string& error_message = "") {
|
|
||||||
ErrorInternal(error_code, error_message, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sends a not-implemented response, indicating that the method either was not
|
|
||||||
// recognized, or has not been implemented.
|
|
||||||
void NotImplemented() { NotImplementedInternal(); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual void SuccessInternal(const T* result) = 0;
|
|
||||||
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual void ErrorInternal(const std::string& error_code,
|
|
||||||
const std::string& error_message,
|
|
||||||
const T* error_details) = 0;
|
|
||||||
|
|
||||||
// Implementation of the public interface, to be provided by subclasses.
|
|
||||||
virtual void NotImplementedInternal() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_H_
|
|
||||||
-80
@@ -1,80 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_FUNCTIONS_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_FUNCTIONS_H_
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "method_result.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
class EncodableValue;
|
|
||||||
|
|
||||||
// Handler types for each of the MethodResult outcomes.
|
|
||||||
template <typename T>
|
|
||||||
using ResultHandlerSuccess = std::function<void(const T* result)>;
|
|
||||||
template <typename T>
|
|
||||||
using ResultHandlerError = std::function<void(const std::string& error_code,
|
|
||||||
const std::string& error_message,
|
|
||||||
const T* error_details)>;
|
|
||||||
template <typename T>
|
|
||||||
using ResultHandlerNotImplemented = std::function<void()>;
|
|
||||||
|
|
||||||
// An implementation of MethodResult that pass calls through to provided
|
|
||||||
// function objects, for ease of constructing one-off result handlers.
|
|
||||||
template <typename T = EncodableValue>
|
|
||||||
class MethodResultFunctions : public MethodResult<T> {
|
|
||||||
public:
|
|
||||||
// Creates a result object that calls the provided functions for the
|
|
||||||
// corresponding MethodResult outcomes.
|
|
||||||
MethodResultFunctions(ResultHandlerSuccess<T> on_success,
|
|
||||||
ResultHandlerError<T> on_error,
|
|
||||||
ResultHandlerNotImplemented<T> on_not_implemented)
|
|
||||||
: on_success_(std::move(on_success)),
|
|
||||||
on_error_(std::move(on_error)),
|
|
||||||
on_not_implemented_(std::move(on_not_implemented)) {}
|
|
||||||
|
|
||||||
virtual ~MethodResultFunctions() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
MethodResultFunctions(MethodResultFunctions const&) = delete;
|
|
||||||
MethodResultFunctions& operator=(MethodResultFunctions const&) = delete;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// |flutter::MethodResult|
|
|
||||||
void SuccessInternal(const T* result) override {
|
|
||||||
if (on_success_) {
|
|
||||||
on_success_(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// |flutter::MethodResult|
|
|
||||||
void ErrorInternal(const std::string& error_code,
|
|
||||||
const std::string& error_message,
|
|
||||||
const T* error_details) override {
|
|
||||||
if (on_error_) {
|
|
||||||
on_error_(error_code, error_message, error_details);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// |flutter::MethodResult|
|
|
||||||
void NotImplementedInternal() override {
|
|
||||||
if (on_not_implemented_) {
|
|
||||||
on_not_implemented_();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
ResultHandlerSuccess<T> on_success_;
|
|
||||||
ResultHandlerError<T> on_error_;
|
|
||||||
ResultHandlerNotImplemented<T> on_not_implemented_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_METHOD_RESULT_FUNCTIONS_H_
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_H_
|
|
||||||
|
|
||||||
#include <flutter_plugin_registrar.h>
|
|
||||||
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <set>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "binary_messenger.h"
|
|
||||||
#include "texture_registrar.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
class Plugin;
|
|
||||||
|
|
||||||
// A object managing the registration of a plugin for various events.
|
|
||||||
//
|
|
||||||
// Currently this class has very limited functionality, but is expected to
|
|
||||||
// expand over time to more closely match the functionality of
|
|
||||||
// the Flutter mobile plugin APIs' plugin registrars.
|
|
||||||
class PluginRegistrar {
|
|
||||||
public:
|
|
||||||
// Creates a new PluginRegistrar. |core_registrar| and the messenger it
|
|
||||||
// provides must remain valid as long as this object exists.
|
|
||||||
explicit PluginRegistrar(FlutterDesktopPluginRegistrarRef core_registrar);
|
|
||||||
|
|
||||||
virtual ~PluginRegistrar();
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
PluginRegistrar(PluginRegistrar const&) = delete;
|
|
||||||
PluginRegistrar& operator=(PluginRegistrar const&) = delete;
|
|
||||||
|
|
||||||
// Returns the messenger to use for creating channels to communicate with the
|
|
||||||
// Flutter engine.
|
|
||||||
//
|
|
||||||
// This pointer will remain valid for the lifetime of this instance.
|
|
||||||
BinaryMessenger* messenger() { return messenger_.get(); }
|
|
||||||
|
|
||||||
// Returns the texture registrar to use for the plugin to render a pixel
|
|
||||||
// buffer.
|
|
||||||
TextureRegistrar* texture_registrar() { return texture_registrar_.get(); }
|
|
||||||
|
|
||||||
// Takes ownership of |plugin|.
|
|
||||||
//
|
|
||||||
// Plugins are not required to call this method if they have other lifetime
|
|
||||||
// management, but this is a convenient place for plugins to be owned to
|
|
||||||
// ensure that they stay valid for any registered callbacks.
|
|
||||||
void AddPlugin(std::unique_ptr<Plugin> plugin);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
FlutterDesktopPluginRegistrarRef registrar() const { return registrar_; }
|
|
||||||
|
|
||||||
// Destroys all owned plugins. Subclasses should call this at the beginning of
|
|
||||||
// their destructors to prevent the possibility of an owned plugin trying to
|
|
||||||
// access destroyed state during its own destruction.
|
|
||||||
void ClearPlugins();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Handle for interacting with the C API's registrar.
|
|
||||||
FlutterDesktopPluginRegistrarRef registrar_;
|
|
||||||
|
|
||||||
std::unique_ptr<BinaryMessenger> messenger_;
|
|
||||||
|
|
||||||
std::unique_ptr<TextureRegistrar> texture_registrar_;
|
|
||||||
|
|
||||||
// Plugins registered for ownership.
|
|
||||||
std::set<std::unique_ptr<Plugin>> plugins_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A plugin that can be registered for ownership by a PluginRegistrar.
|
|
||||||
class Plugin {
|
|
||||||
public:
|
|
||||||
virtual ~Plugin() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A singleton to own PluginRegistrars. This is intended for use in plugins,
|
|
||||||
// where there is no higher-level object to own a PluginRegistrar that can
|
|
||||||
// own plugin instances and ensure that they live as long as the engine they
|
|
||||||
// are registered with.
|
|
||||||
class PluginRegistrarManager {
|
|
||||||
public:
|
|
||||||
static PluginRegistrarManager* GetInstance();
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
PluginRegistrarManager(PluginRegistrarManager const&) = delete;
|
|
||||||
PluginRegistrarManager& operator=(PluginRegistrarManager const&) = delete;
|
|
||||||
|
|
||||||
// Returns a plugin registrar wrapper of type T, which must be a kind of
|
|
||||||
// PluginRegistrar, creating it if necessary. The returned registrar will
|
|
||||||
// live as long as the underlying FlutterDesktopPluginRegistrarRef, so
|
|
||||||
// can be used to own plugin instances.
|
|
||||||
//
|
|
||||||
// Calling this multiple times for the same registrar_ref with different
|
|
||||||
// template types results in undefined behavior.
|
|
||||||
template <class T>
|
|
||||||
T* GetRegistrar(FlutterDesktopPluginRegistrarRef registrar_ref) {
|
|
||||||
auto insert_result =
|
|
||||||
registrars_.emplace(registrar_ref, std::make_unique<T>(registrar_ref));
|
|
||||||
auto& registrar_pair = *(insert_result.first);
|
|
||||||
FlutterDesktopPluginRegistrarSetDestructionHandler(registrar_pair.first,
|
|
||||||
OnRegistrarDestroyed);
|
|
||||||
return static_cast<T*>(registrar_pair.second.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroys all registrar wrappers created by the manager.
|
|
||||||
//
|
|
||||||
// This is intended primarily for use in tests.
|
|
||||||
void Reset() { registrars_.clear(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
PluginRegistrarManager();
|
|
||||||
|
|
||||||
using WrapperMap = std::map<FlutterDesktopPluginRegistrarRef,
|
|
||||||
std::unique_ptr<PluginRegistrar>>;
|
|
||||||
|
|
||||||
static void OnRegistrarDestroyed(FlutterDesktopPluginRegistrarRef registrar);
|
|
||||||
|
|
||||||
WrapperMap* registrars() { return ®istrars_; }
|
|
||||||
|
|
||||||
WrapperMap registrars_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_H_
|
|
||||||
-151
@@ -1,151 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_WINDOWS_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_WINDOWS_H_
|
|
||||||
|
|
||||||
#include <flutter_windows.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#include "flutter_view.h"
|
|
||||||
#include "plugin_registrar.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// A delegate callback for WindowProc delegation.
|
|
||||||
//
|
|
||||||
// Implementations should return a value only if they have handled the message
|
|
||||||
// and want to stop all further handling.
|
|
||||||
using WindowProcDelegate = std::function<std::optional<
|
|
||||||
LRESULT>(HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam)>;
|
|
||||||
|
|
||||||
// An extension to PluginRegistrar providing access to Windows-specific
|
|
||||||
// functionality.
|
|
||||||
class PluginRegistrarWindows : public PluginRegistrar {
|
|
||||||
public:
|
|
||||||
// Creates a new PluginRegistrar. |core_registrar| and the messenger it
|
|
||||||
// provides must remain valid as long as this object exists.
|
|
||||||
explicit PluginRegistrarWindows(
|
|
||||||
FlutterDesktopPluginRegistrarRef core_registrar)
|
|
||||||
: PluginRegistrar(core_registrar) {
|
|
||||||
FlutterDesktopViewRef implicit_view =
|
|
||||||
FlutterDesktopPluginRegistrarGetView(core_registrar);
|
|
||||||
if (implicit_view) {
|
|
||||||
implicit_view_ = std::make_unique<FlutterView>(implicit_view);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~PluginRegistrarWindows() {
|
|
||||||
// Must be the first call.
|
|
||||||
ClearPlugins();
|
|
||||||
// Explicitly cleared to facilitate destruction order testing.
|
|
||||||
implicit_view_.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
PluginRegistrarWindows(PluginRegistrarWindows const&) = delete;
|
|
||||||
PluginRegistrarWindows& operator=(PluginRegistrarWindows const&) = delete;
|
|
||||||
|
|
||||||
// Returns the implicit view, or nullptr if there is no implicit view.
|
|
||||||
//
|
|
||||||
// See:
|
|
||||||
// https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/implicitView.html
|
|
||||||
//
|
|
||||||
// DEPRECATED: Use |GetViewById| instead.
|
|
||||||
FlutterView* GetView() { return implicit_view_.get(); }
|
|
||||||
|
|
||||||
// Returns the view with the given ID, or nullptr if the view does not exist.
|
|
||||||
//
|
|
||||||
// Destroying the shared pointer destroys the reference to the view; it does
|
|
||||||
// not destroy the underlying view.
|
|
||||||
std::shared_ptr<FlutterView> GetViewById(FlutterViewId view_id) const {
|
|
||||||
FlutterDesktopViewRef view =
|
|
||||||
FlutterDesktopPluginRegistrarGetViewById(registrar(), view_id);
|
|
||||||
if (!view) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
return std::make_shared<FlutterView>(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Registers |delegate| to receive WindowProc callbacks for the top-level
|
|
||||||
// window containing this Flutter instance. Returns an ID that can be used to
|
|
||||||
// unregister the handler.
|
|
||||||
//
|
|
||||||
// Delegates are not guaranteed to be called:
|
|
||||||
// - The application may choose not to delegate WindowProc calls.
|
|
||||||
// - If multiple plugins are registered, the first one that returns a value
|
|
||||||
// from the delegate message will "win", and others will not be called.
|
|
||||||
// The order of delegate calls is not defined.
|
|
||||||
//
|
|
||||||
// Delegates should be implemented as narrowly as possible, only returning
|
|
||||||
// a value in cases where it's important that other delegates not run, to
|
|
||||||
// minimize the chances of conflicts between plugins.
|
|
||||||
int RegisterTopLevelWindowProcDelegate(WindowProcDelegate delegate) {
|
|
||||||
if (window_proc_delegates_.empty()) {
|
|
||||||
FlutterDesktopPluginRegistrarRegisterTopLevelWindowProcDelegate(
|
|
||||||
registrar(), PluginRegistrarWindows::OnTopLevelWindowProc, this);
|
|
||||||
}
|
|
||||||
int delegate_id = next_window_proc_delegate_id_++;
|
|
||||||
window_proc_delegates_.emplace(delegate_id, std::move(delegate));
|
|
||||||
return delegate_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unregisters a previously registered delegate.
|
|
||||||
void UnregisterTopLevelWindowProcDelegate(int proc_id) {
|
|
||||||
window_proc_delegates_.erase(proc_id);
|
|
||||||
if (window_proc_delegates_.empty()) {
|
|
||||||
FlutterDesktopPluginRegistrarUnregisterTopLevelWindowProcDelegate(
|
|
||||||
registrar(), PluginRegistrarWindows::OnTopLevelWindowProc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
// A FlutterDesktopWindowProcCallback implementation that forwards back to
|
|
||||||
// a PluginRegistarWindows instance provided as |user_data|.
|
|
||||||
static bool OnTopLevelWindowProc(HWND hwnd,
|
|
||||||
UINT message,
|
|
||||||
WPARAM wparam,
|
|
||||||
LPARAM lparam,
|
|
||||||
void* user_data,
|
|
||||||
LRESULT* result) {
|
|
||||||
const auto* registrar = static_cast<PluginRegistrarWindows*>(user_data);
|
|
||||||
std::optional optional_result = registrar->CallTopLevelWindowProcDelegates(
|
|
||||||
hwnd, message, wparam, lparam);
|
|
||||||
if (optional_result) {
|
|
||||||
*result = *optional_result;
|
|
||||||
}
|
|
||||||
return optional_result.has_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<LRESULT> CallTopLevelWindowProcDelegates(HWND hwnd,
|
|
||||||
UINT message,
|
|
||||||
WPARAM wparam,
|
|
||||||
LPARAM lparam) const {
|
|
||||||
std::optional<LRESULT> result;
|
|
||||||
for (const auto& pair : window_proc_delegates_) {
|
|
||||||
result = pair.second(hwnd, message, wparam, lparam);
|
|
||||||
// Stop as soon as any delegate indicates that it has handled the message.
|
|
||||||
if (result) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The associated FlutterView, if any.
|
|
||||||
std::unique_ptr<FlutterView> implicit_view_;
|
|
||||||
|
|
||||||
// The next ID to return from RegisterWindowProcDelegate.
|
|
||||||
int next_window_proc_delegate_id_ = 1;
|
|
||||||
|
|
||||||
std::map<int, WindowProcDelegate> window_proc_delegates_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRAR_WINDOWS_H_
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRY_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRY_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include <flutter_plugin_registrar.h>
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// Vends PluginRegistrars for named plugins.
|
|
||||||
//
|
|
||||||
// Plugins are identified by unique string keys, typically the name of the
|
|
||||||
// plugin's main class.
|
|
||||||
class PluginRegistry {
|
|
||||||
public:
|
|
||||||
PluginRegistry() = default;
|
|
||||||
virtual ~PluginRegistry() = default;
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
PluginRegistry(PluginRegistry const&) = delete;
|
|
||||||
PluginRegistry& operator=(PluginRegistry const&) = delete;
|
|
||||||
|
|
||||||
// Returns the FlutterDesktopPluginRegistrarRef to register a plugin with the
|
|
||||||
// given name.
|
|
||||||
//
|
|
||||||
// The name must be unique across the application.
|
|
||||||
virtual FlutterDesktopPluginRegistrarRef GetRegistrarForPlugin(
|
|
||||||
const std::string& plugin_name) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_PLUGIN_REGISTRY_H_
|
|
||||||
-76
@@ -1,76 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_CODEC_SERIALIZER_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_CODEC_SERIALIZER_H_
|
|
||||||
|
|
||||||
#include "byte_streams.h"
|
|
||||||
#include "encodable_value.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// Encapsulates the logic for encoding/decoding EncodableValues to/from the
|
|
||||||
// standard codec binary representation.
|
|
||||||
//
|
|
||||||
// This can be subclassed to extend the standard codec with support for new
|
|
||||||
// types.
|
|
||||||
class StandardCodecSerializer {
|
|
||||||
public:
|
|
||||||
virtual ~StandardCodecSerializer();
|
|
||||||
|
|
||||||
// Returns the shared serializer instance.
|
|
||||||
static const StandardCodecSerializer& GetInstance();
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
StandardCodecSerializer(StandardCodecSerializer const&) = delete;
|
|
||||||
StandardCodecSerializer& operator=(StandardCodecSerializer const&) = delete;
|
|
||||||
|
|
||||||
// Reads and returns the next value from |stream|.
|
|
||||||
EncodableValue ReadValue(ByteStreamReader* stream) const;
|
|
||||||
|
|
||||||
// Writes the encoding of |value| to |stream|, including the initial type
|
|
||||||
// discrimination byte.
|
|
||||||
//
|
|
||||||
// Can be overridden by a subclass to extend the codec.
|
|
||||||
virtual void WriteValue(const EncodableValue& value,
|
|
||||||
ByteStreamWriter* stream) const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Codecs require long-lived serializers, so clients should always use
|
|
||||||
// GetInstance().
|
|
||||||
StandardCodecSerializer();
|
|
||||||
|
|
||||||
// Reads and returns the next value from |stream|, whose discrimination byte
|
|
||||||
// was |type|.
|
|
||||||
//
|
|
||||||
// The discrimination byte will already have been read from the stream when
|
|
||||||
// this is called.
|
|
||||||
//
|
|
||||||
// Can be overridden by a subclass to extend the codec.
|
|
||||||
virtual EncodableValue ReadValueOfType(uint8_t type,
|
|
||||||
ByteStreamReader* stream) const;
|
|
||||||
|
|
||||||
// Reads the variable-length size from the current position in |stream|.
|
|
||||||
size_t ReadSize(ByteStreamReader* stream) const;
|
|
||||||
|
|
||||||
// Writes the variable-length size encoding to |stream|.
|
|
||||||
void WriteSize(size_t size, ByteStreamWriter* stream) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Reads a fixed-type list whose values are of type T from the current
|
|
||||||
// position in |stream|, and returns it as the corresponding EncodableValue.
|
|
||||||
// |T| must correspond to one of the supported list value types of
|
|
||||||
// EncodableValue.
|
|
||||||
template <typename T>
|
|
||||||
EncodableValue ReadVector(ByteStreamReader* stream) const;
|
|
||||||
|
|
||||||
// Writes |vector| to |stream| as a fixed-type list. |T| must correspond to
|
|
||||||
// one of the supported list value types of EncodableValue.
|
|
||||||
template <typename T>
|
|
||||||
void WriteVector(const std::vector<T> vector, ByteStreamWriter* stream) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_CODEC_SERIALIZER_H_
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_MESSAGE_CODEC_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_MESSAGE_CODEC_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "encodable_value.h"
|
|
||||||
#include "message_codec.h"
|
|
||||||
#include "standard_codec_serializer.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// A binary message encoding/decoding mechanism for communications to/from the
|
|
||||||
// Flutter engine via message channels.
|
|
||||||
class StandardMessageCodec : public MessageCodec<EncodableValue> {
|
|
||||||
public:
|
|
||||||
// Returns an instance of the codec, optionally using a custom serializer to
|
|
||||||
// add support for more types.
|
|
||||||
//
|
|
||||||
// If provided, |serializer| must be long-lived. If no serializer is provided,
|
|
||||||
// the default will be used.
|
|
||||||
//
|
|
||||||
// The instance returned for a given |serializer| will be shared, and
|
|
||||||
// any instance returned from this will be long-lived, and can be safely
|
|
||||||
// passed to, e.g., channel constructors.
|
|
||||||
static const StandardMessageCodec& GetInstance(
|
|
||||||
const StandardCodecSerializer* serializer = nullptr);
|
|
||||||
|
|
||||||
~StandardMessageCodec();
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
StandardMessageCodec(StandardMessageCodec const&) = delete;
|
|
||||||
StandardMessageCodec& operator=(StandardMessageCodec const&) = delete;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// |flutter::MessageCodec|
|
|
||||||
std::unique_ptr<EncodableValue> DecodeMessageInternal(
|
|
||||||
const uint8_t* binary_message,
|
|
||||||
const size_t message_size) const override;
|
|
||||||
|
|
||||||
// |flutter::MessageCodec|
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> EncodeMessageInternal(
|
|
||||||
const EncodableValue& message) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Instances should be obtained via GetInstance.
|
|
||||||
explicit StandardMessageCodec(const StandardCodecSerializer* serializer);
|
|
||||||
|
|
||||||
const StandardCodecSerializer* serializer_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_MESSAGE_CODEC_H_
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_METHOD_CODEC_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_METHOD_CODEC_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "encodable_value.h"
|
|
||||||
#include "method_call.h"
|
|
||||||
#include "method_codec.h"
|
|
||||||
#include "standard_codec_serializer.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// An implementation of MethodCodec that uses a binary serialization.
|
|
||||||
class StandardMethodCodec : public MethodCodec<EncodableValue> {
|
|
||||||
public:
|
|
||||||
// Returns an instance of the codec, optionally using a custom serializer to
|
|
||||||
// add support for more types.
|
|
||||||
//
|
|
||||||
// If provided, |serializer| must be long-lived. If no serializer is provided,
|
|
||||||
// the default will be used.
|
|
||||||
//
|
|
||||||
// The instance returned for a given |extension| will be shared, and
|
|
||||||
// any instance returned from this will be long-lived, and can be safely
|
|
||||||
// passed to, e.g., channel constructors.
|
|
||||||
static const StandardMethodCodec& GetInstance(
|
|
||||||
const StandardCodecSerializer* serializer = nullptr);
|
|
||||||
|
|
||||||
~StandardMethodCodec();
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
StandardMethodCodec(StandardMethodCodec const&) = delete;
|
|
||||||
StandardMethodCodec& operator=(StandardMethodCodec const&) = delete;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// |flutter::MethodCodec|
|
|
||||||
std::unique_ptr<MethodCall<EncodableValue>> DecodeMethodCallInternal(
|
|
||||||
const uint8_t* message,
|
|
||||||
size_t message_size) const override;
|
|
||||||
|
|
||||||
// |flutter::MethodCodec|
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> EncodeMethodCallInternal(
|
|
||||||
const MethodCall<EncodableValue>& method_call) const override;
|
|
||||||
|
|
||||||
// |flutter::MethodCodec|
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> EncodeSuccessEnvelopeInternal(
|
|
||||||
const EncodableValue* result) const override;
|
|
||||||
|
|
||||||
// |flutter::MethodCodec|
|
|
||||||
std::unique_ptr<std::vector<uint8_t>> EncodeErrorEnvelopeInternal(
|
|
||||||
const std::string& error_code,
|
|
||||||
const std::string& error_message,
|
|
||||||
const EncodableValue* error_details) const override;
|
|
||||||
|
|
||||||
// |flutter::MethodCodec|
|
|
||||||
bool DecodeAndProcessResponseEnvelopeInternal(
|
|
||||||
const uint8_t* response,
|
|
||||||
size_t response_size,
|
|
||||||
MethodResult<EncodableValue>* result) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Instances should be obtained via GetInstance.
|
|
||||||
explicit StandardMethodCodec(const StandardCodecSerializer* serializer);
|
|
||||||
|
|
||||||
const StandardCodecSerializer* serializer_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STANDARD_METHOD_CODEC_H_
|
|
||||||
@@ -1,111 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_TEXTURE_REGISTRAR_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_TEXTURE_REGISTRAR_H_
|
|
||||||
|
|
||||||
#include <flutter_texture_registrar.h>
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
#include <variant>
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// A pixel buffer texture.
|
|
||||||
class PixelBufferTexture {
|
|
||||||
public:
|
|
||||||
// A callback used for retrieving pixel buffers.
|
|
||||||
typedef std::function<const FlutterDesktopPixelBuffer*(size_t width,
|
|
||||||
size_t height)>
|
|
||||||
CopyBufferCallback;
|
|
||||||
|
|
||||||
// Creates a pixel buffer texture that uses the provided |copy_buffer_cb| to
|
|
||||||
// retrieve the buffer.
|
|
||||||
// As the callback is usually invoked from the render thread, the callee must
|
|
||||||
// take care of proper synchronization. It also needs to be ensured that the
|
|
||||||
// returned buffer isn't released prior to unregistering this texture.
|
|
||||||
explicit PixelBufferTexture(CopyBufferCallback copy_buffer_callback)
|
|
||||||
: copy_buffer_callback_(std::move(copy_buffer_callback)) {}
|
|
||||||
|
|
||||||
// Returns the callback-provided FlutterDesktopPixelBuffer that contains the
|
|
||||||
// actual pixel data. The intended surface size is specified by |width| and
|
|
||||||
// |height|.
|
|
||||||
const FlutterDesktopPixelBuffer* CopyPixelBuffer(size_t width,
|
|
||||||
size_t height) const {
|
|
||||||
return copy_buffer_callback_(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const CopyBufferCallback copy_buffer_callback_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A GPU surface-based texture.
|
|
||||||
class GpuSurfaceTexture {
|
|
||||||
public:
|
|
||||||
// A callback used for retrieving surface descriptors.
|
|
||||||
typedef std::function<
|
|
||||||
const FlutterDesktopGpuSurfaceDescriptor*(size_t width, size_t height)>
|
|
||||||
ObtainDescriptorCallback;
|
|
||||||
|
|
||||||
GpuSurfaceTexture(FlutterDesktopGpuSurfaceType surface_type,
|
|
||||||
ObtainDescriptorCallback obtain_descriptor_callback)
|
|
||||||
: surface_type_(surface_type),
|
|
||||||
obtain_descriptor_callback_(std::move(obtain_descriptor_callback)) {}
|
|
||||||
|
|
||||||
// Returns the callback-provided FlutterDesktopGpuSurfaceDescriptor that
|
|
||||||
// contains the surface handle. The intended surface size is specified by
|
|
||||||
// |width| and |height|.
|
|
||||||
const FlutterDesktopGpuSurfaceDescriptor* ObtainDescriptor(
|
|
||||||
size_t width,
|
|
||||||
size_t height) const {
|
|
||||||
return obtain_descriptor_callback_(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets the surface type.
|
|
||||||
FlutterDesktopGpuSurfaceType surface_type() const { return surface_type_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
const FlutterDesktopGpuSurfaceType surface_type_;
|
|
||||||
const ObtainDescriptorCallback obtain_descriptor_callback_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// The available texture variants.
|
|
||||||
// Only PixelBufferTexture is currently implemented.
|
|
||||||
// Other variants are expected to be added in the future.
|
|
||||||
typedef std::variant<PixelBufferTexture, GpuSurfaceTexture> TextureVariant;
|
|
||||||
|
|
||||||
// An object keeping track of external textures.
|
|
||||||
//
|
|
||||||
// Thread safety:
|
|
||||||
// It's safe to call the member methods from any thread.
|
|
||||||
class TextureRegistrar {
|
|
||||||
public:
|
|
||||||
virtual ~TextureRegistrar() = default;
|
|
||||||
|
|
||||||
// Registers a |texture| object and returns the ID for that texture.
|
|
||||||
virtual int64_t RegisterTexture(TextureVariant* texture) = 0;
|
|
||||||
|
|
||||||
// Notifies the flutter engine that the texture object corresponding
|
|
||||||
// to |texure_id| needs to render a new frame.
|
|
||||||
//
|
|
||||||
// For PixelBufferTextures, this will effectively make the engine invoke
|
|
||||||
// the callback that was provided upon creating the texture.
|
|
||||||
virtual bool MarkTextureFrameAvailable(int64_t texture_id) = 0;
|
|
||||||
|
|
||||||
// Asynchronously unregisters an existing texture object.
|
|
||||||
// Upon completion, the optional |callback| gets invoked.
|
|
||||||
virtual void UnregisterTexture(int64_t texture_id,
|
|
||||||
std::function<void()> callback) = 0;
|
|
||||||
|
|
||||||
// Unregisters an existing texture object.
|
|
||||||
// DEPRECATED: Use UnregisterTexture(texture_id, optional_callback) instead.
|
|
||||||
virtual bool UnregisterTexture(int64_t texture_id) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_TEXTURE_REGISTRAR_H_
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "include/flutter/plugin_registrar.h"
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
#include "binary_messenger_impl.h"
|
|
||||||
#include "include/flutter/engine_method_result.h"
|
|
||||||
#include "include/flutter/method_channel.h"
|
|
||||||
#include "texture_registrar_impl.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// ===== PluginRegistrar =====
|
|
||||||
|
|
||||||
PluginRegistrar::PluginRegistrar(FlutterDesktopPluginRegistrarRef registrar)
|
|
||||||
: registrar_(registrar) {
|
|
||||||
auto core_messenger = FlutterDesktopPluginRegistrarGetMessenger(registrar_);
|
|
||||||
messenger_ = std::make_unique<BinaryMessengerImpl>(core_messenger);
|
|
||||||
|
|
||||||
auto texture_registrar =
|
|
||||||
FlutterDesktopRegistrarGetTextureRegistrar(registrar_);
|
|
||||||
texture_registrar_ =
|
|
||||||
std::make_unique<TextureRegistrarImpl>(texture_registrar);
|
|
||||||
}
|
|
||||||
|
|
||||||
PluginRegistrar::~PluginRegistrar() {
|
|
||||||
// This must always be the first call.
|
|
||||||
ClearPlugins();
|
|
||||||
|
|
||||||
// Explicitly cleared to facilitate testing of destruction order.
|
|
||||||
messenger_.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginRegistrar::AddPlugin(std::unique_ptr<Plugin> plugin) {
|
|
||||||
plugins_.insert(std::move(plugin));
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginRegistrar::ClearPlugins() {
|
|
||||||
plugins_.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== PluginRegistrarManager =====
|
|
||||||
|
|
||||||
// static
|
|
||||||
PluginRegistrarManager* PluginRegistrarManager::GetInstance() {
|
|
||||||
static PluginRegistrarManager* instance = new PluginRegistrarManager();
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
PluginRegistrarManager::PluginRegistrarManager() = default;
|
|
||||||
|
|
||||||
// static
|
|
||||||
void PluginRegistrarManager::OnRegistrarDestroyed(
|
|
||||||
FlutterDesktopPluginRegistrarRef registrar) {
|
|
||||||
GetInstance()->registrars()->erase(registrar);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
This code is intended to be built into plugins and applications to provide
|
|
||||||
higher-level, C++ abstractions for interacting with the Flutter library.
|
|
||||||
|
|
||||||
Over time, the goal is to move more of this code into the library in a way that
|
|
||||||
provides a usable ABI (e.g., does not use standard library in the interfaces).
|
|
||||||
|
|
||||||
Note that this wrapper is still in early stages. Expect significant churn in
|
|
||||||
both the APIs and the structure of the wrapper (e.g., the exact set of files
|
|
||||||
that need to be built).
|
|
||||||
@@ -1,468 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// This file contains what would normally be standard_codec_serializer.cc,
|
|
||||||
// standard_message_codec.cc, and standard_method_codec.cc. They are grouped
|
|
||||||
// together to simplify use of the client wrapper, since the common case is
|
|
||||||
// that any client that needs one of these files needs all three.
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "byte_buffer_streams.h"
|
|
||||||
#include "include/flutter/standard_codec_serializer.h"
|
|
||||||
#include "include/flutter/standard_message_codec.h"
|
|
||||||
#include "include/flutter/standard_method_codec.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// ===== standard_codec_serializer.h =====
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
// The order/values here must match the constants in message_codecs.dart.
|
|
||||||
enum class EncodedType {
|
|
||||||
kNull = 0,
|
|
||||||
kTrue,
|
|
||||||
kFalse,
|
|
||||||
kInt32,
|
|
||||||
kInt64,
|
|
||||||
kLargeInt, // No longer used. If encountered, treat as kString.
|
|
||||||
kFloat64,
|
|
||||||
kString,
|
|
||||||
kUInt8List,
|
|
||||||
kInt32List,
|
|
||||||
kInt64List,
|
|
||||||
kFloat64List,
|
|
||||||
kList,
|
|
||||||
kMap,
|
|
||||||
kFloat32List,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Returns the encoded type that should be written when serializing |value|.
|
|
||||||
EncodedType EncodedTypeForValue(const EncodableValue& value) {
|
|
||||||
switch (value.index()) {
|
|
||||||
case 0:
|
|
||||||
return EncodedType::kNull;
|
|
||||||
case 1:
|
|
||||||
return std::get<bool>(value) ? EncodedType::kTrue : EncodedType::kFalse;
|
|
||||||
case 2:
|
|
||||||
return EncodedType::kInt32;
|
|
||||||
case 3:
|
|
||||||
return EncodedType::kInt64;
|
|
||||||
case 4:
|
|
||||||
return EncodedType::kFloat64;
|
|
||||||
case 5:
|
|
||||||
return EncodedType::kString;
|
|
||||||
case 6:
|
|
||||||
return EncodedType::kUInt8List;
|
|
||||||
case 7:
|
|
||||||
return EncodedType::kInt32List;
|
|
||||||
case 8:
|
|
||||||
return EncodedType::kInt64List;
|
|
||||||
case 9:
|
|
||||||
return EncodedType::kFloat64List;
|
|
||||||
case 10:
|
|
||||||
return EncodedType::kList;
|
|
||||||
case 11:
|
|
||||||
return EncodedType::kMap;
|
|
||||||
case 13:
|
|
||||||
return EncodedType::kFloat32List;
|
|
||||||
}
|
|
||||||
assert(false);
|
|
||||||
return EncodedType::kNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
StandardCodecSerializer::StandardCodecSerializer() = default;
|
|
||||||
|
|
||||||
StandardCodecSerializer::~StandardCodecSerializer() = default;
|
|
||||||
|
|
||||||
const StandardCodecSerializer& StandardCodecSerializer::GetInstance() {
|
|
||||||
static StandardCodecSerializer sInstance;
|
|
||||||
return sInstance;
|
|
||||||
};
|
|
||||||
|
|
||||||
EncodableValue StandardCodecSerializer::ReadValue(
|
|
||||||
ByteStreamReader* stream) const {
|
|
||||||
uint8_t type = stream->ReadByte();
|
|
||||||
return ReadValueOfType(type, stream);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StandardCodecSerializer::WriteValue(const EncodableValue& value,
|
|
||||||
ByteStreamWriter* stream) const {
|
|
||||||
stream->WriteByte(static_cast<uint8_t>(EncodedTypeForValue(value)));
|
|
||||||
// TODO(cbracken): Consider replacing this with std::visit.
|
|
||||||
switch (value.index()) {
|
|
||||||
case 0:
|
|
||||||
case 1:
|
|
||||||
// Null and bool are encoded directly in the type.
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
stream->WriteInt32(std::get<int32_t>(value));
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
stream->WriteInt64(std::get<int64_t>(value));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
stream->WriteAlignment(8);
|
|
||||||
stream->WriteDouble(std::get<double>(value));
|
|
||||||
break;
|
|
||||||
case 5: {
|
|
||||||
const auto& string_value = std::get<std::string>(value);
|
|
||||||
size_t size = string_value.size();
|
|
||||||
WriteSize(size, stream);
|
|
||||||
if (size > 0) {
|
|
||||||
stream->WriteBytes(
|
|
||||||
reinterpret_cast<const uint8_t*>(string_value.data()), size);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 6:
|
|
||||||
WriteVector(std::get<std::vector<uint8_t>>(value), stream);
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
WriteVector(std::get<std::vector<int32_t>>(value), stream);
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
WriteVector(std::get<std::vector<int64_t>>(value), stream);
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
WriteVector(std::get<std::vector<double>>(value), stream);
|
|
||||||
break;
|
|
||||||
case 10: {
|
|
||||||
const auto& list = std::get<EncodableList>(value);
|
|
||||||
WriteSize(list.size(), stream);
|
|
||||||
for (const auto& item : list) {
|
|
||||||
WriteValue(item, stream);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 11: {
|
|
||||||
const auto& map = std::get<EncodableMap>(value);
|
|
||||||
WriteSize(map.size(), stream);
|
|
||||||
for (const auto& pair : map) {
|
|
||||||
WriteValue(pair.first, stream);
|
|
||||||
WriteValue(pair.second, stream);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 12:
|
|
||||||
std::cerr
|
|
||||||
<< "Unhandled custom type in StandardCodecSerializer::WriteValue. "
|
|
||||||
<< "Custom types require codec extensions." << std::endl;
|
|
||||||
break;
|
|
||||||
case 13: {
|
|
||||||
WriteVector(std::get<std::vector<float>>(value), stream);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EncodableValue StandardCodecSerializer::ReadValueOfType(
|
|
||||||
uint8_t type,
|
|
||||||
ByteStreamReader* stream) const {
|
|
||||||
switch (static_cast<EncodedType>(type)) {
|
|
||||||
case EncodedType::kNull:
|
|
||||||
return EncodableValue();
|
|
||||||
case EncodedType::kTrue:
|
|
||||||
return EncodableValue(true);
|
|
||||||
case EncodedType::kFalse:
|
|
||||||
return EncodableValue(false);
|
|
||||||
case EncodedType::kInt32:
|
|
||||||
return EncodableValue(stream->ReadInt32());
|
|
||||||
case EncodedType::kInt64:
|
|
||||||
return EncodableValue(stream->ReadInt64());
|
|
||||||
case EncodedType::kFloat64:
|
|
||||||
stream->ReadAlignment(8);
|
|
||||||
return EncodableValue(stream->ReadDouble());
|
|
||||||
case EncodedType::kLargeInt:
|
|
||||||
case EncodedType::kString: {
|
|
||||||
size_t size = ReadSize(stream);
|
|
||||||
std::string string_value;
|
|
||||||
string_value.resize(size);
|
|
||||||
stream->ReadBytes(reinterpret_cast<uint8_t*>(&string_value[0]), size);
|
|
||||||
return EncodableValue(string_value);
|
|
||||||
}
|
|
||||||
case EncodedType::kUInt8List:
|
|
||||||
return ReadVector<uint8_t>(stream);
|
|
||||||
case EncodedType::kInt32List:
|
|
||||||
return ReadVector<int32_t>(stream);
|
|
||||||
case EncodedType::kInt64List:
|
|
||||||
return ReadVector<int64_t>(stream);
|
|
||||||
case EncodedType::kFloat64List:
|
|
||||||
return ReadVector<double>(stream);
|
|
||||||
case EncodedType::kList: {
|
|
||||||
size_t length = ReadSize(stream);
|
|
||||||
EncodableList list_value;
|
|
||||||
list_value.reserve(length);
|
|
||||||
for (size_t i = 0; i < length; ++i) {
|
|
||||||
list_value.push_back(ReadValue(stream));
|
|
||||||
}
|
|
||||||
return EncodableValue(list_value);
|
|
||||||
}
|
|
||||||
case EncodedType::kMap: {
|
|
||||||
size_t length = ReadSize(stream);
|
|
||||||
EncodableMap map_value;
|
|
||||||
for (size_t i = 0; i < length; ++i) {
|
|
||||||
EncodableValue key = ReadValue(stream);
|
|
||||||
EncodableValue value = ReadValue(stream);
|
|
||||||
map_value.emplace(std::move(key), std::move(value));
|
|
||||||
}
|
|
||||||
return EncodableValue(map_value);
|
|
||||||
}
|
|
||||||
case EncodedType::kFloat32List: {
|
|
||||||
return ReadVector<float>(stream);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
std::cerr << "Unknown type in StandardCodecSerializer::ReadValueOfType: "
|
|
||||||
<< static_cast<int>(type) << std::endl;
|
|
||||||
return EncodableValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t StandardCodecSerializer::ReadSize(ByteStreamReader* stream) const {
|
|
||||||
uint8_t byte = stream->ReadByte();
|
|
||||||
if (byte < 254) {
|
|
||||||
return byte;
|
|
||||||
} else if (byte == 254) {
|
|
||||||
uint16_t value = 0;
|
|
||||||
stream->ReadBytes(reinterpret_cast<uint8_t*>(&value), 2);
|
|
||||||
return value;
|
|
||||||
} else {
|
|
||||||
uint32_t value = 0;
|
|
||||||
stream->ReadBytes(reinterpret_cast<uint8_t*>(&value), 4);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StandardCodecSerializer::WriteSize(size_t size,
|
|
||||||
ByteStreamWriter* stream) const {
|
|
||||||
if (size < 254) {
|
|
||||||
stream->WriteByte(static_cast<uint8_t>(size));
|
|
||||||
} else if (size <= 0xffff) {
|
|
||||||
stream->WriteByte(254);
|
|
||||||
uint16_t value = static_cast<uint16_t>(size);
|
|
||||||
stream->WriteBytes(reinterpret_cast<uint8_t*>(&value), 2);
|
|
||||||
} else {
|
|
||||||
stream->WriteByte(255);
|
|
||||||
uint32_t value = static_cast<uint32_t>(size);
|
|
||||||
stream->WriteBytes(reinterpret_cast<uint8_t*>(&value), 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
EncodableValue StandardCodecSerializer::ReadVector(
|
|
||||||
ByteStreamReader* stream) const {
|
|
||||||
size_t count = ReadSize(stream);
|
|
||||||
std::vector<T> vector;
|
|
||||||
vector.resize(count);
|
|
||||||
uint8_t type_size = static_cast<uint8_t>(sizeof(T));
|
|
||||||
if (type_size > 1) {
|
|
||||||
stream->ReadAlignment(type_size);
|
|
||||||
}
|
|
||||||
stream->ReadBytes(reinterpret_cast<uint8_t*>(vector.data()),
|
|
||||||
count * type_size);
|
|
||||||
return EncodableValue(vector);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void StandardCodecSerializer::WriteVector(const std::vector<T> vector,
|
|
||||||
ByteStreamWriter* stream) const {
|
|
||||||
size_t count = vector.size();
|
|
||||||
WriteSize(count, stream);
|
|
||||||
if (count == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
uint8_t type_size = static_cast<uint8_t>(sizeof(T));
|
|
||||||
if (type_size > 1) {
|
|
||||||
stream->WriteAlignment(type_size);
|
|
||||||
}
|
|
||||||
stream->WriteBytes(reinterpret_cast<const uint8_t*>(vector.data()),
|
|
||||||
count * type_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== standard_message_codec.h =====
|
|
||||||
|
|
||||||
// static
|
|
||||||
const StandardMessageCodec& StandardMessageCodec::GetInstance(
|
|
||||||
const StandardCodecSerializer* serializer) {
|
|
||||||
if (!serializer) {
|
|
||||||
serializer = &StandardCodecSerializer::GetInstance();
|
|
||||||
}
|
|
||||||
static auto* sInstances = new std::map<const StandardCodecSerializer*,
|
|
||||||
std::unique_ptr<StandardMessageCodec>>;
|
|
||||||
auto it = sInstances->find(serializer);
|
|
||||||
if (it == sInstances->end()) {
|
|
||||||
// Uses new due to private constructor (to prevent API clients from
|
|
||||||
// accidentally passing temporary codec instances to channels).
|
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
|
||||||
auto emplace_result = sInstances->emplace(
|
|
||||||
serializer, std::unique_ptr<StandardMessageCodec>(
|
|
||||||
new StandardMessageCodec(serializer)));
|
|
||||||
it = emplace_result.first;
|
|
||||||
}
|
|
||||||
return *(it->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
StandardMessageCodec::StandardMessageCodec(
|
|
||||||
const StandardCodecSerializer* serializer)
|
|
||||||
: serializer_(serializer) {}
|
|
||||||
|
|
||||||
StandardMessageCodec::~StandardMessageCodec() = default;
|
|
||||||
|
|
||||||
std::unique_ptr<EncodableValue> StandardMessageCodec::DecodeMessageInternal(
|
|
||||||
const uint8_t* binary_message,
|
|
||||||
size_t message_size) const {
|
|
||||||
if (!binary_message) {
|
|
||||||
return std::make_unique<EncodableValue>();
|
|
||||||
}
|
|
||||||
ByteBufferStreamReader stream(binary_message, message_size);
|
|
||||||
return std::make_unique<EncodableValue>(serializer_->ReadValue(&stream));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<std::vector<uint8_t>>
|
|
||||||
StandardMessageCodec::EncodeMessageInternal(
|
|
||||||
const EncodableValue& message) const {
|
|
||||||
auto encoded = std::make_unique<std::vector<uint8_t>>();
|
|
||||||
ByteBufferStreamWriter stream(encoded.get());
|
|
||||||
serializer_->WriteValue(message, &stream);
|
|
||||||
return encoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ===== standard_method_codec.h =====
|
|
||||||
|
|
||||||
// static
|
|
||||||
const StandardMethodCodec& StandardMethodCodec::GetInstance(
|
|
||||||
const StandardCodecSerializer* serializer) {
|
|
||||||
if (!serializer) {
|
|
||||||
serializer = &StandardCodecSerializer::GetInstance();
|
|
||||||
}
|
|
||||||
static auto* sInstances = new std::map<const StandardCodecSerializer*,
|
|
||||||
std::unique_ptr<StandardMethodCodec>>;
|
|
||||||
auto it = sInstances->find(serializer);
|
|
||||||
if (it == sInstances->end()) {
|
|
||||||
// Uses new due to private constructor (to prevent API clients from
|
|
||||||
// accidentally passing temporary codec instances to channels).
|
|
||||||
// NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks)
|
|
||||||
auto emplace_result = sInstances->emplace(
|
|
||||||
serializer, std::unique_ptr<StandardMethodCodec>(
|
|
||||||
new StandardMethodCodec(serializer)));
|
|
||||||
it = emplace_result.first;
|
|
||||||
}
|
|
||||||
return *(it->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
StandardMethodCodec::StandardMethodCodec(
|
|
||||||
const StandardCodecSerializer* serializer)
|
|
||||||
: serializer_(serializer) {}
|
|
||||||
|
|
||||||
StandardMethodCodec::~StandardMethodCodec() = default;
|
|
||||||
|
|
||||||
std::unique_ptr<MethodCall<EncodableValue>>
|
|
||||||
StandardMethodCodec::DecodeMethodCallInternal(const uint8_t* message,
|
|
||||||
size_t message_size) const {
|
|
||||||
ByteBufferStreamReader stream(message, message_size);
|
|
||||||
EncodableValue method_name_value = serializer_->ReadValue(&stream);
|
|
||||||
const auto* method_name = std::get_if<std::string>(&method_name_value);
|
|
||||||
if (!method_name) {
|
|
||||||
std::cerr << "Invalid method call; method name is not a string."
|
|
||||||
<< std::endl;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
auto arguments =
|
|
||||||
std::make_unique<EncodableValue>(serializer_->ReadValue(&stream));
|
|
||||||
return std::make_unique<MethodCall<EncodableValue>>(*method_name,
|
|
||||||
std::move(arguments));
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<std::vector<uint8_t>>
|
|
||||||
StandardMethodCodec::EncodeMethodCallInternal(
|
|
||||||
const MethodCall<EncodableValue>& method_call) const {
|
|
||||||
auto encoded = std::make_unique<std::vector<uint8_t>>();
|
|
||||||
ByteBufferStreamWriter stream(encoded.get());
|
|
||||||
serializer_->WriteValue(EncodableValue(method_call.method_name()), &stream);
|
|
||||||
if (method_call.arguments()) {
|
|
||||||
serializer_->WriteValue(*method_call.arguments(), &stream);
|
|
||||||
} else {
|
|
||||||
serializer_->WriteValue(EncodableValue(), &stream);
|
|
||||||
}
|
|
||||||
return encoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<std::vector<uint8_t>>
|
|
||||||
StandardMethodCodec::EncodeSuccessEnvelopeInternal(
|
|
||||||
const EncodableValue* result) const {
|
|
||||||
auto encoded = std::make_unique<std::vector<uint8_t>>();
|
|
||||||
ByteBufferStreamWriter stream(encoded.get());
|
|
||||||
stream.WriteByte(0);
|
|
||||||
if (result) {
|
|
||||||
serializer_->WriteValue(*result, &stream);
|
|
||||||
} else {
|
|
||||||
serializer_->WriteValue(EncodableValue(), &stream);
|
|
||||||
}
|
|
||||||
return encoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<std::vector<uint8_t>>
|
|
||||||
StandardMethodCodec::EncodeErrorEnvelopeInternal(
|
|
||||||
const std::string& error_code,
|
|
||||||
const std::string& error_message,
|
|
||||||
const EncodableValue* error_details) const {
|
|
||||||
auto encoded = std::make_unique<std::vector<uint8_t>>();
|
|
||||||
ByteBufferStreamWriter stream(encoded.get());
|
|
||||||
stream.WriteByte(1);
|
|
||||||
serializer_->WriteValue(EncodableValue(error_code), &stream);
|
|
||||||
if (error_message.empty()) {
|
|
||||||
serializer_->WriteValue(EncodableValue(), &stream);
|
|
||||||
} else {
|
|
||||||
serializer_->WriteValue(EncodableValue(error_message), &stream);
|
|
||||||
}
|
|
||||||
if (error_details) {
|
|
||||||
serializer_->WriteValue(*error_details, &stream);
|
|
||||||
} else {
|
|
||||||
serializer_->WriteValue(EncodableValue(), &stream);
|
|
||||||
}
|
|
||||||
return encoded;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StandardMethodCodec::DecodeAndProcessResponseEnvelopeInternal(
|
|
||||||
const uint8_t* response,
|
|
||||||
size_t response_size,
|
|
||||||
MethodResult<EncodableValue>* result) const {
|
|
||||||
ByteBufferStreamReader stream(response, response_size);
|
|
||||||
uint8_t flag = stream.ReadByte();
|
|
||||||
switch (flag) {
|
|
||||||
case 0: {
|
|
||||||
EncodableValue value = serializer_->ReadValue(&stream);
|
|
||||||
if (value.IsNull()) {
|
|
||||||
result->Success();
|
|
||||||
} else {
|
|
||||||
result->Success(value);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case 1: {
|
|
||||||
EncodableValue code = serializer_->ReadValue(&stream);
|
|
||||||
EncodableValue message = serializer_->ReadValue(&stream);
|
|
||||||
EncodableValue details = serializer_->ReadValue(&stream);
|
|
||||||
const std::string& message_string =
|
|
||||||
message.IsNull() ? "" : std::get<std::string>(message);
|
|
||||||
if (details.IsNull()) {
|
|
||||||
result->Error(std::get<std::string>(code), message_string);
|
|
||||||
} else {
|
|
||||||
result->Error(std::get<std::string>(code), message_string, details);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_TEXTURE_REGISTRAR_IMPL_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_TEXTURE_REGISTRAR_IMPL_H_
|
|
||||||
|
|
||||||
#include "include/flutter/texture_registrar.h"
|
|
||||||
|
|
||||||
namespace flutter {
|
|
||||||
|
|
||||||
// Wrapper around a FlutterDesktopTextureRegistrarRef that implements the
|
|
||||||
// TextureRegistrar API.
|
|
||||||
class TextureRegistrarImpl : public TextureRegistrar {
|
|
||||||
public:
|
|
||||||
explicit TextureRegistrarImpl(
|
|
||||||
FlutterDesktopTextureRegistrarRef texture_registrar_ref);
|
|
||||||
virtual ~TextureRegistrarImpl();
|
|
||||||
|
|
||||||
// Prevent copying.
|
|
||||||
TextureRegistrarImpl(TextureRegistrarImpl const&) = delete;
|
|
||||||
TextureRegistrarImpl& operator=(TextureRegistrarImpl const&) = delete;
|
|
||||||
|
|
||||||
// |flutter::TextureRegistrar|
|
|
||||||
int64_t RegisterTexture(TextureVariant* texture) override;
|
|
||||||
|
|
||||||
// |flutter::TextureRegistrar|
|
|
||||||
bool MarkTextureFrameAvailable(int64_t texture_id) override;
|
|
||||||
|
|
||||||
// |flutter::TextureRegistrar|
|
|
||||||
void UnregisterTexture(int64_t texture_id,
|
|
||||||
std::function<void()> callback) override;
|
|
||||||
|
|
||||||
// |flutter::TextureRegistrar|
|
|
||||||
bool UnregisterTexture(int64_t texture_id) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Handle for interacting with the C API.
|
|
||||||
FlutterDesktopTextureRegistrarRef texture_registrar_ref_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace flutter
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_TEXTURE_REGISTRAR_IMPL_H_
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_EXPORT_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_EXPORT_H_
|
|
||||||
|
|
||||||
#ifdef FLUTTER_DESKTOP_LIBRARY
|
|
||||||
|
|
||||||
// Add visibility/export annotations when building the library.
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define FLUTTER_EXPORT __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define FLUTTER_EXPORT __attribute__((visibility("default")))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else // FLUTTER_DESKTOP_LIBRARY
|
|
||||||
|
|
||||||
// Add import annotations when consuming the library.
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define FLUTTER_EXPORT __declspec(dllimport)
|
|
||||||
#else
|
|
||||||
#define FLUTTER_EXPORT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // FLUTTER_DESKTOP_LIBRARY
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_EXPORT_H_
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MESSENGER_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MESSENGER_H_
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "flutter_export.h"
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif // defined(__cplusplus)
|
|
||||||
|
|
||||||
// Opaque reference to a Flutter engine messenger.
|
|
||||||
typedef struct FlutterDesktopMessenger* FlutterDesktopMessengerRef;
|
|
||||||
|
|
||||||
// Opaque handle for tracking responses to messages.
|
|
||||||
typedef struct _FlutterPlatformMessageResponseHandle
|
|
||||||
FlutterDesktopMessageResponseHandle;
|
|
||||||
|
|
||||||
// The callback expected as a response of a binary message.
|
|
||||||
typedef void (*FlutterDesktopBinaryReply)(const uint8_t* data,
|
|
||||||
size_t data_size,
|
|
||||||
void* user_data);
|
|
||||||
|
|
||||||
// A message received from Flutter.
|
|
||||||
typedef struct {
|
|
||||||
// Size of this struct as created by Flutter.
|
|
||||||
size_t struct_size;
|
|
||||||
// The name of the channel used for this message.
|
|
||||||
const char* channel;
|
|
||||||
// The raw message data.
|
|
||||||
const uint8_t* message;
|
|
||||||
// The length of |message|.
|
|
||||||
size_t message_size;
|
|
||||||
// The response handle. If non-null, the receiver of this message must call
|
|
||||||
// FlutterDesktopSendMessageResponse exactly once with this handle.
|
|
||||||
const FlutterDesktopMessageResponseHandle* response_handle;
|
|
||||||
} FlutterDesktopMessage;
|
|
||||||
|
|
||||||
// Function pointer type for message handler callback registration.
|
|
||||||
//
|
|
||||||
// The user data will be whatever was passed to FlutterDesktopSetMessageHandler
|
|
||||||
// for the channel the message is received on.
|
|
||||||
typedef void (*FlutterDesktopMessageCallback)(
|
|
||||||
FlutterDesktopMessengerRef /* messenger */,
|
|
||||||
const FlutterDesktopMessage* /* message*/,
|
|
||||||
void* /* user data */);
|
|
||||||
|
|
||||||
// Sends a binary message to the Flutter side on the specified channel.
|
|
||||||
FLUTTER_EXPORT bool FlutterDesktopMessengerSend(
|
|
||||||
FlutterDesktopMessengerRef messenger,
|
|
||||||
const char* channel,
|
|
||||||
const uint8_t* message,
|
|
||||||
const size_t message_size);
|
|
||||||
|
|
||||||
// Sends a binary message to the Flutter side on the specified channel.
|
|
||||||
// The |reply| callback will be executed when a response is received.
|
|
||||||
FLUTTER_EXPORT bool FlutterDesktopMessengerSendWithReply(
|
|
||||||
FlutterDesktopMessengerRef messenger,
|
|
||||||
const char* channel,
|
|
||||||
const uint8_t* message,
|
|
||||||
const size_t message_size,
|
|
||||||
const FlutterDesktopBinaryReply reply,
|
|
||||||
void* user_data);
|
|
||||||
|
|
||||||
// Sends a reply to a FlutterDesktopMessage for the given response handle.
|
|
||||||
//
|
|
||||||
// Once this has been called, |handle| is invalid and must not be used again.
|
|
||||||
FLUTTER_EXPORT void FlutterDesktopMessengerSendResponse(
|
|
||||||
FlutterDesktopMessengerRef messenger,
|
|
||||||
const FlutterDesktopMessageResponseHandle* handle,
|
|
||||||
const uint8_t* data,
|
|
||||||
size_t data_length);
|
|
||||||
|
|
||||||
// Registers a callback function for incoming binary messages from the Flutter
|
|
||||||
// side on the specified channel.
|
|
||||||
//
|
|
||||||
// Replaces any existing callback. Provide a null handler to unregister the
|
|
||||||
// existing callback.
|
|
||||||
//
|
|
||||||
// If |user_data| is provided, it will be passed in |callback| calls.
|
|
||||||
FLUTTER_EXPORT void FlutterDesktopMessengerSetCallback(
|
|
||||||
FlutterDesktopMessengerRef messenger,
|
|
||||||
const char* channel,
|
|
||||||
FlutterDesktopMessageCallback callback,
|
|
||||||
void* user_data);
|
|
||||||
|
|
||||||
// Increments the reference count for the |messenger|.
|
|
||||||
//
|
|
||||||
// Operation is thread-safe.
|
|
||||||
//
|
|
||||||
// See also: |FlutterDesktopMessengerRelease|
|
|
||||||
FLUTTER_EXPORT FlutterDesktopMessengerRef
|
|
||||||
FlutterDesktopMessengerAddRef(FlutterDesktopMessengerRef messenger);
|
|
||||||
|
|
||||||
// Decrements the reference count for the |messenger|.
|
|
||||||
//
|
|
||||||
// Operation is thread-safe.
|
|
||||||
//
|
|
||||||
// See also: |FlutterDesktopMessengerAddRef|
|
|
||||||
FLUTTER_EXPORT void FlutterDesktopMessengerRelease(
|
|
||||||
FlutterDesktopMessengerRef messenger);
|
|
||||||
|
|
||||||
// Returns `true` if the |FlutterDesktopMessengerRef| still references a running
|
|
||||||
// engine.
|
|
||||||
//
|
|
||||||
// This check should be made inside of a |FlutterDesktopMessengerLock| and
|
|
||||||
// before any other calls are made to the FlutterDesktopMessengerRef when using
|
|
||||||
// it from a thread other than the platform thread.
|
|
||||||
FLUTTER_EXPORT bool FlutterDesktopMessengerIsAvailable(
|
|
||||||
FlutterDesktopMessengerRef messenger);
|
|
||||||
|
|
||||||
// Locks the `FlutterDesktopMessengerRef` ensuring that
|
|
||||||
// |FlutterDesktopMessengerIsAvailable| does not change while locked.
|
|
||||||
//
|
|
||||||
// All calls to the FlutterDesktopMessengerRef from threads other than the
|
|
||||||
// platform thread should happen inside of a lock.
|
|
||||||
//
|
|
||||||
// Operation is thread-safe.
|
|
||||||
//
|
|
||||||
// Returns the |messenger| value.
|
|
||||||
//
|
|
||||||
// See also: |FlutterDesktopMessengerUnlock|
|
|
||||||
FLUTTER_EXPORT FlutterDesktopMessengerRef
|
|
||||||
FlutterDesktopMessengerLock(FlutterDesktopMessengerRef messenger);
|
|
||||||
|
|
||||||
// Unlocks the `FlutterDesktopMessengerRef`.
|
|
||||||
//
|
|
||||||
// Operation is thread-safe.
|
|
||||||
//
|
|
||||||
// See also: |FlutterDesktopMessengerLock|
|
|
||||||
FLUTTER_EXPORT void FlutterDesktopMessengerUnlock(
|
|
||||||
FlutterDesktopMessengerRef messenger);
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_MESSENGER_H_
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_PLUGIN_REGISTRAR_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_PLUGIN_REGISTRAR_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "flutter_export.h"
|
|
||||||
#include "flutter_messenger.h"
|
|
||||||
#include "flutter_texture_registrar.h"
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif // defined(__cplusplus)
|
|
||||||
|
|
||||||
// Opaque reference to a plugin registrar.
|
|
||||||
typedef struct FlutterDesktopPluginRegistrar* FlutterDesktopPluginRegistrarRef;
|
|
||||||
|
|
||||||
// Function pointer type for registrar destruction callback.
|
|
||||||
typedef void (*FlutterDesktopOnPluginRegistrarDestroyed)(
|
|
||||||
FlutterDesktopPluginRegistrarRef);
|
|
||||||
|
|
||||||
// Returns the engine messenger associated with this registrar.
|
|
||||||
FLUTTER_EXPORT FlutterDesktopMessengerRef
|
|
||||||
FlutterDesktopPluginRegistrarGetMessenger(
|
|
||||||
FlutterDesktopPluginRegistrarRef registrar);
|
|
||||||
|
|
||||||
// Returns the texture registrar associated with this registrar.
|
|
||||||
FLUTTER_EXPORT FlutterDesktopTextureRegistrarRef
|
|
||||||
FlutterDesktopRegistrarGetTextureRegistrar(
|
|
||||||
FlutterDesktopPluginRegistrarRef registrar);
|
|
||||||
|
|
||||||
// Registers a callback to be called when the plugin registrar is destroyed.
|
|
||||||
FLUTTER_EXPORT void FlutterDesktopPluginRegistrarSetDestructionHandler(
|
|
||||||
FlutterDesktopPluginRegistrarRef registrar,
|
|
||||||
FlutterDesktopOnPluginRegistrarDestroyed callback);
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_PLUGIN_REGISTRAR_H_
|
|
||||||
@@ -1,187 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_TEXTURE_REGISTRAR_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_TEXTURE_REGISTRAR_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "flutter_export.h"
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct FlutterDesktopTextureRegistrar;
|
|
||||||
// Opaque reference to a texture registrar.
|
|
||||||
typedef struct FlutterDesktopTextureRegistrar*
|
|
||||||
FlutterDesktopTextureRegistrarRef;
|
|
||||||
|
|
||||||
// Possible values for the type specified in FlutterDesktopTextureInfo.
|
|
||||||
// Additional types may be added in the future.
|
|
||||||
typedef enum {
|
|
||||||
// A Pixel buffer-based texture.
|
|
||||||
kFlutterDesktopPixelBufferTexture,
|
|
||||||
// A platform-specific GPU surface-backed texture.
|
|
||||||
kFlutterDesktopGpuSurfaceTexture
|
|
||||||
} FlutterDesktopTextureType;
|
|
||||||
|
|
||||||
// Supported GPU surface types.
|
|
||||||
typedef enum {
|
|
||||||
// Uninitialized.
|
|
||||||
kFlutterDesktopGpuSurfaceTypeNone,
|
|
||||||
// A DXGI shared texture handle (Windows only).
|
|
||||||
// See
|
|
||||||
// https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgiresource-getsharedhandle
|
|
||||||
kFlutterDesktopGpuSurfaceTypeDxgiSharedHandle,
|
|
||||||
// A |ID3D11Texture2D| (Windows only).
|
|
||||||
kFlutterDesktopGpuSurfaceTypeD3d11Texture2D
|
|
||||||
} FlutterDesktopGpuSurfaceType;
|
|
||||||
|
|
||||||
// Supported pixel formats.
|
|
||||||
typedef enum {
|
|
||||||
// Uninitialized.
|
|
||||||
kFlutterDesktopPixelFormatNone,
|
|
||||||
// Represents a 32-bit RGBA color format with 8 bits each for red, green, blue
|
|
||||||
// and alpha.
|
|
||||||
kFlutterDesktopPixelFormatRGBA8888,
|
|
||||||
// Represents a 32-bit BGRA color format with 8 bits each for blue, green, red
|
|
||||||
// and alpha.
|
|
||||||
kFlutterDesktopPixelFormatBGRA8888
|
|
||||||
} FlutterDesktopPixelFormat;
|
|
||||||
|
|
||||||
// An image buffer object.
|
|
||||||
typedef struct {
|
|
||||||
// The pixel data buffer.
|
|
||||||
const uint8_t* buffer;
|
|
||||||
// Width of the pixel buffer.
|
|
||||||
size_t width;
|
|
||||||
// Height of the pixel buffer.
|
|
||||||
size_t height;
|
|
||||||
// An optional callback that gets invoked when the |buffer| can be released.
|
|
||||||
void (*release_callback)(void* release_context);
|
|
||||||
// Opaque data passed to |release_callback|.
|
|
||||||
void* release_context;
|
|
||||||
} FlutterDesktopPixelBuffer;
|
|
||||||
|
|
||||||
// A GPU surface descriptor.
|
|
||||||
typedef struct {
|
|
||||||
// The size of this struct. Must be
|
|
||||||
// sizeof(FlutterDesktopGpuSurfaceDescriptor).
|
|
||||||
size_t struct_size;
|
|
||||||
// The surface handle. The expected type depends on the
|
|
||||||
// |FlutterDesktopGpuSurfaceType|.
|
|
||||||
//
|
|
||||||
// Provide a |ID3D11Texture2D*| when using
|
|
||||||
// |kFlutterDesktopGpuSurfaceTypeD3d11Texture2D| or a |HANDLE| when using
|
|
||||||
// |kFlutterDesktopGpuSurfaceTypeDxgiSharedHandle|.
|
|
||||||
//
|
|
||||||
// The referenced resource needs to stay valid until it has been opened by
|
|
||||||
// Flutter. Consider incrementing the resource's reference count in the
|
|
||||||
// |FlutterDesktopGpuSurfaceTextureCallback| and registering a
|
|
||||||
// |release_callback| for decrementing the reference count once it has been
|
|
||||||
// opened.
|
|
||||||
void* handle;
|
|
||||||
// The physical width.
|
|
||||||
size_t width;
|
|
||||||
// The physical height.
|
|
||||||
size_t height;
|
|
||||||
// The visible width.
|
|
||||||
// It might be less or equal to the physical |width|.
|
|
||||||
size_t visible_width;
|
|
||||||
// The visible height.
|
|
||||||
// It might be less or equal to the physical |height|.
|
|
||||||
size_t visible_height;
|
|
||||||
// The pixel format which might be optional depending on the surface type.
|
|
||||||
FlutterDesktopPixelFormat format;
|
|
||||||
// An optional callback that gets invoked when the |handle| has been opened.
|
|
||||||
void (*release_callback)(void* release_context);
|
|
||||||
// Opaque data passed to |release_callback|.
|
|
||||||
void* release_context;
|
|
||||||
} FlutterDesktopGpuSurfaceDescriptor;
|
|
||||||
|
|
||||||
// The pixel buffer copy callback definition provided to
|
|
||||||
// the Flutter engine to copy the texture.
|
|
||||||
// It is invoked with the intended surface size specified by |width| and
|
|
||||||
// |height| and the |user_data| held by
|
|
||||||
// |FlutterDesktopPixelBufferTextureConfig|.
|
|
||||||
//
|
|
||||||
// As this is usually called from the render thread, the callee must take
|
|
||||||
// care of proper synchronization. It also needs to be ensured that the
|
|
||||||
// returned |FlutterDesktopPixelBuffer| isn't released prior to unregistering
|
|
||||||
// the corresponding texture.
|
|
||||||
typedef const FlutterDesktopPixelBuffer* (
|
|
||||||
*FlutterDesktopPixelBufferTextureCallback)(size_t width,
|
|
||||||
size_t height,
|
|
||||||
void* user_data);
|
|
||||||
|
|
||||||
// The GPU surface callback definition provided to the Flutter engine to obtain
|
|
||||||
// the surface. It is invoked with the intended surface size specified by
|
|
||||||
// |width| and |height| and the |user_data| held by
|
|
||||||
// |FlutterDesktopGpuSurfaceTextureConfig|.
|
|
||||||
typedef const FlutterDesktopGpuSurfaceDescriptor* (
|
|
||||||
*FlutterDesktopGpuSurfaceTextureCallback)(size_t width,
|
|
||||||
size_t height,
|
|
||||||
void* user_data);
|
|
||||||
|
|
||||||
// An object used to configure pixel buffer textures.
|
|
||||||
typedef struct {
|
|
||||||
// The callback used by the engine to copy the pixel buffer object.
|
|
||||||
FlutterDesktopPixelBufferTextureCallback callback;
|
|
||||||
// Opaque data that will get passed to the provided |callback|.
|
|
||||||
void* user_data;
|
|
||||||
} FlutterDesktopPixelBufferTextureConfig;
|
|
||||||
|
|
||||||
// An object used to configure GPU-surface textures.
|
|
||||||
typedef struct {
|
|
||||||
// The size of this struct. Must be
|
|
||||||
// sizeof(FlutterDesktopGpuSurfaceTextureConfig).
|
|
||||||
size_t struct_size;
|
|
||||||
// The concrete surface type (e.g.
|
|
||||||
// |kFlutterDesktopGpuSurfaceTypeDxgiSharedHandle|)
|
|
||||||
FlutterDesktopGpuSurfaceType type;
|
|
||||||
// The callback used by the engine to obtain the surface descriptor.
|
|
||||||
FlutterDesktopGpuSurfaceTextureCallback callback;
|
|
||||||
// Opaque data that will get passed to the provided |callback|.
|
|
||||||
void* user_data;
|
|
||||||
} FlutterDesktopGpuSurfaceTextureConfig;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FlutterDesktopTextureType type;
|
|
||||||
union {
|
|
||||||
FlutterDesktopPixelBufferTextureConfig pixel_buffer_config;
|
|
||||||
FlutterDesktopGpuSurfaceTextureConfig gpu_surface_config;
|
|
||||||
};
|
|
||||||
} FlutterDesktopTextureInfo;
|
|
||||||
|
|
||||||
// Registers a new texture with the Flutter engine and returns the texture ID.
|
|
||||||
// This function can be called from any thread.
|
|
||||||
FLUTTER_EXPORT int64_t FlutterDesktopTextureRegistrarRegisterExternalTexture(
|
|
||||||
FlutterDesktopTextureRegistrarRef texture_registrar,
|
|
||||||
const FlutterDesktopTextureInfo* info);
|
|
||||||
|
|
||||||
// Asynchronously unregisters the texture identified by |texture_id| from the
|
|
||||||
// Flutter engine.
|
|
||||||
// An optional |callback| gets invoked upon completion.
|
|
||||||
// This function can be called from any thread.
|
|
||||||
FLUTTER_EXPORT void FlutterDesktopTextureRegistrarUnregisterExternalTexture(
|
|
||||||
FlutterDesktopTextureRegistrarRef texture_registrar,
|
|
||||||
int64_t texture_id,
|
|
||||||
void (*callback)(void* user_data),
|
|
||||||
void* user_data);
|
|
||||||
|
|
||||||
// Marks that a new texture frame is available for a given |texture_id|.
|
|
||||||
// Returns true on success or false if the specified texture doesn't exist.
|
|
||||||
// This function can be called from any thread.
|
|
||||||
FLUTTER_EXPORT bool
|
|
||||||
FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable(
|
|
||||||
FlutterDesktopTextureRegistrarRef texture_registrar,
|
|
||||||
int64_t texture_id);
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_TEXTURE_REGISTRAR_H_
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,332 +0,0 @@
|
|||||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_PUBLIC_FLUTTER_WINDOWS_H_
|
|
||||||
#define FLUTTER_SHELL_PLATFORM_WINDOWS_PUBLIC_FLUTTER_WINDOWS_H_
|
|
||||||
|
|
||||||
#include <dxgi.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "flutter_export.h"
|
|
||||||
#include "flutter_messenger.h"
|
|
||||||
#include "flutter_plugin_registrar.h"
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef void (*VoidCallback)(void* /* user data */);
|
|
||||||
|
|
||||||
// Opaque reference to a Flutter view controller.
|
|
||||||
struct FlutterDesktopViewController;
|
|
||||||
typedef struct FlutterDesktopViewController* FlutterDesktopViewControllerRef;
|
|
||||||
|
|
||||||
// Opaque reference to a Flutter window.
|
|
||||||
struct FlutterDesktopView;
|
|
||||||
typedef struct FlutterDesktopView* FlutterDesktopViewRef;
|
|
||||||
|
|
||||||
// Opaque reference to a Flutter engine instance.
|
|
||||||
struct FlutterDesktopEngine;
|
|
||||||
typedef struct FlutterDesktopEngine* FlutterDesktopEngineRef;
|
|
||||||
|
|
||||||
// The unique identifier for a view.
|
|
||||||
typedef int64_t FlutterDesktopViewId;
|
|
||||||
|
|
||||||
// Configures how the Flutter engine selects a GPU.
|
|
||||||
typedef enum {
|
|
||||||
// No preference.
|
|
||||||
NoPreference,
|
|
||||||
// Prefer energy efficiency over performance, such as an integrated GPU.
|
|
||||||
// This falls back to a high performance GPU if no low power GPU is
|
|
||||||
// available.
|
|
||||||
LowPowerPreference,
|
|
||||||
} FlutterDesktopGpuPreference;
|
|
||||||
|
|
||||||
// Configures the thread policy for running the UI isolate.
|
|
||||||
typedef enum {
|
|
||||||
// Default value. Currently will run the UI isolate on separate thread,
|
|
||||||
// later will be changed to running the UI isolate on platform thread.
|
|
||||||
Default,
|
|
||||||
// Run the UI isolate on platform thread.
|
|
||||||
RunOnPlatformThread,
|
|
||||||
// Run the UI isolate on a separate thread.
|
|
||||||
RunOnSeparateThread,
|
|
||||||
} FlutterDesktopUIThreadPolicy;
|
|
||||||
|
|
||||||
// Properties for configuring a Flutter engine instance.
|
|
||||||
typedef struct {
|
|
||||||
// The path to the flutter_assets folder for the application to be run.
|
|
||||||
// This can either be an absolute path or a path relative to the directory
|
|
||||||
// containing the executable.
|
|
||||||
const wchar_t* assets_path;
|
|
||||||
|
|
||||||
// The path to the icudtl.dat file for the version of Flutter you are using.
|
|
||||||
// This can either be an absolute path or a path relative to the directory
|
|
||||||
// containing the executable.
|
|
||||||
const wchar_t* icu_data_path;
|
|
||||||
|
|
||||||
// The path to the AOT library file for your application, if any.
|
|
||||||
// This can either be an absolute path or a path relative to the directory
|
|
||||||
// containing the executable. This can be nullptr for a non-AOT build, as
|
|
||||||
// it will be ignored in that case.
|
|
||||||
const wchar_t* aot_library_path;
|
|
||||||
|
|
||||||
// The name of the top-level Dart entrypoint function. If null or the empty
|
|
||||||
// string, 'main' is assumed. If a custom entrypoint is used, this parameter
|
|
||||||
// must specifiy the name of a top-level function in the same Dart library as
|
|
||||||
// the app's main() function. Custom entrypoint functions must be decorated
|
|
||||||
// with `@pragma('vm:entry-point')` to ensure the method is not tree-shaken
|
|
||||||
// by the Dart compiler.
|
|
||||||
const char* dart_entrypoint;
|
|
||||||
|
|
||||||
// Number of elements in the array passed in as dart_entrypoint_argv.
|
|
||||||
int dart_entrypoint_argc;
|
|
||||||
|
|
||||||
// Array of Dart entrypoint arguments. This is deep copied during the call
|
|
||||||
// to FlutterDesktopEngineCreate.
|
|
||||||
const char** dart_entrypoint_argv;
|
|
||||||
|
|
||||||
// GPU choice preference
|
|
||||||
FlutterDesktopGpuPreference gpu_preference;
|
|
||||||
|
|
||||||
// Policy for the thread that runs UI isolate.
|
|
||||||
FlutterDesktopUIThreadPolicy ui_thread_policy;
|
|
||||||
} FlutterDesktopEngineProperties;
|
|
||||||
|
|
||||||
// ========== View Controller ==========
|
|
||||||
|
|
||||||
// Creates a view that hosts and displays the given engine instance.
|
|
||||||
//
|
|
||||||
// This takes ownership of |engine|, so FlutterDesktopEngineDestroy should no
|
|
||||||
// longer be called on it, as it will be called internally when the view
|
|
||||||
// controller is destroyed. If creating the view controller fails, the engine
|
|
||||||
// will be destroyed immediately.
|
|
||||||
//
|
|
||||||
// If |engine| is not already running, the view controller will start running
|
|
||||||
// it automatically before displaying the window.
|
|
||||||
//
|
|
||||||
// The caller owns the returned reference, and is responsible for calling
|
|
||||||
// FlutterDesktopViewControllerDestroy. Returns a null pointer in the event of
|
|
||||||
// an error.
|
|
||||||
//
|
|
||||||
// The Win32 implementation accepts width, height with view hookup explicitly
|
|
||||||
// performed using the caller using HWND parenting.
|
|
||||||
FLUTTER_EXPORT FlutterDesktopViewControllerRef
|
|
||||||
FlutterDesktopViewControllerCreate(int width,
|
|
||||||
int height,
|
|
||||||
FlutterDesktopEngineRef engine);
|
|
||||||
|
|
||||||
// Shuts down the engine instance associated with |controller|, and cleans up
|
|
||||||
// associated state.
|
|
||||||
//
|
|
||||||
// |controller| is no longer valid after this call.
|
|
||||||
FLUTTER_EXPORT void FlutterDesktopViewControllerDestroy(
|
|
||||||
FlutterDesktopViewControllerRef controller);
|
|
||||||
|
|
||||||
// Returns the view controller's view ID.
|
|
||||||
FLUTTER_EXPORT FlutterDesktopViewId FlutterDesktopViewControllerGetViewId(
|
|
||||||
FlutterDesktopViewControllerRef view_controller);
|
|
||||||
|
|
||||||
// Returns the handle for the engine running in FlutterDesktopViewControllerRef.
|
|
||||||
//
|
|
||||||
// Its lifetime is the same as the |controller|'s.
|
|
||||||
FLUTTER_EXPORT FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine(
|
|
||||||
FlutterDesktopViewControllerRef controller);
|
|
||||||
|
|
||||||
// Returns the view managed by the given controller.
|
|
||||||
FLUTTER_EXPORT FlutterDesktopViewRef
|
|
||||||
FlutterDesktopViewControllerGetView(FlutterDesktopViewControllerRef controller);
|
|
||||||
|
|
||||||
// Requests new frame from the engine and repaints the view.
|
|
||||||
FLUTTER_EXPORT void FlutterDesktopViewControllerForceRedraw(
|
|
||||||
FlutterDesktopViewControllerRef controller);
|
|
||||||
|
|
||||||
// Allows the Flutter engine and any interested plugins an opportunity to
|
|
||||||
// handle the given message.
|
|
||||||
//
|
|
||||||
// If the WindowProc was handled and further handling should stop, this returns
|
|
||||||
// true and |result| will be populated. |result| is not set if returning false.
|
|
||||||
FLUTTER_EXPORT bool FlutterDesktopViewControllerHandleTopLevelWindowProc(
|
|
||||||
FlutterDesktopViewControllerRef controller,
|
|
||||||
HWND hwnd,
|
|
||||||
UINT message,
|
|
||||||
WPARAM wparam,
|
|
||||||
LPARAM lparam,
|
|
||||||
LRESULT* result);
|
|
||||||
|
|
||||||
// ========== Engine ==========
|
|
||||||
|
|
||||||
// Creates a Flutter engine with the given properties.
|
|
||||||
//
|
|
||||||
// The caller owns the returned reference, and is responsible for calling
|
|
||||||
// FlutterDesktopEngineDestroy. The lifetime of |engine_properties| is required
|
|
||||||
// to extend only until the end of this call.
|
|
||||||
FLUTTER_EXPORT FlutterDesktopEngineRef FlutterDesktopEngineCreate(
|
|
||||||
const FlutterDesktopEngineProperties* engine_properties);
|
|
||||||
|
|
||||||
// Shuts down and destroys the given engine instance. Returns true if the
|
|
||||||
// shutdown was successful, or if the engine was not running.
|
|
||||||
//
|
|
||||||
// |engine| is no longer valid after this call.
|
|
||||||
FLUTTER_EXPORT bool FlutterDesktopEngineDestroy(FlutterDesktopEngineRef engine);
|
|
||||||
|
|
||||||
// Starts running the given engine instance.
|
|
||||||
//
|
|
||||||
// The entry_point parameter is deprecated but preserved for
|
|
||||||
// backward-compatibility. If desired, a custom Dart entrypoint function can be
|
|
||||||
// set in the dart_entrypoint field of the FlutterDesktopEngineProperties
|
|
||||||
// struct passed to FlutterDesktopEngineCreate.
|
|
||||||
//
|
|
||||||
// If specified, entry_point must be the name of a top-level function from the
|
|
||||||
// same Dart library that contains the app's main() function, and must be
|
|
||||||
// decorated with `@pragma(vm:entry-point)` to ensure the method is not
|
|
||||||
// tree-shaken by the Dart compiler. If conflicting non-null values are passed
|
|
||||||
// to this function and via the FlutterDesktopEngineProperties struct, the run
|
|
||||||
// will fail.
|
|
||||||
//
|
|
||||||
// Returns false if running the engine failed.
|
|
||||||
FLUTTER_EXPORT bool FlutterDesktopEngineRun(FlutterDesktopEngineRef engine,
|
|
||||||
const char* entry_point);
|
|
||||||
|
|
||||||
// DEPRECATED: This is no longer necessary to call, Flutter will take care of
|
|
||||||
// processing engine messages transparently through DispatchMessage.
|
|
||||||
//
|
|
||||||
// Processes any pending events in the Flutter engine, and returns the
|
|
||||||
// number of nanoseconds until the next scheduled event (or max, if none).
|
|
||||||
//
|
|
||||||
// This should be called on every run of the application-level runloop, and
|
|
||||||
// a wait for native events in the runloop should never be longer than the
|
|
||||||
// last return value from this function.
|
|
||||||
FLUTTER_EXPORT uint64_t
|
|
||||||
FlutterDesktopEngineProcessMessages(FlutterDesktopEngineRef engine);
|
|
||||||
|
|
||||||
FLUTTER_EXPORT void FlutterDesktopEngineReloadSystemFonts(
|
|
||||||
FlutterDesktopEngineRef engine);
|
|
||||||
|
|
||||||
// Returns the plugin registrar handle for the plugin with the given name.
|
|
||||||
//
|
|
||||||
// The name must be unique across the application.
|
|
||||||
FLUTTER_EXPORT FlutterDesktopPluginRegistrarRef
|
|
||||||
FlutterDesktopEngineGetPluginRegistrar(FlutterDesktopEngineRef engine,
|
|
||||||
const char* plugin_name);
|
|
||||||
|
|
||||||
// Returns the messenger associated with the engine.
|
|
||||||
//
|
|
||||||
// This does not provide an owning reference, so should *not* be balanced with a
|
|
||||||
// call to |FlutterDesktopMessengerRelease|.
|
|
||||||
//
|
|
||||||
// Callers should use |FlutterDesktopMessengerAddRef| if the returned pointer
|
|
||||||
// will potentially outlive 'engine', such as when passing it to another thread.
|
|
||||||
FLUTTER_EXPORT FlutterDesktopMessengerRef
|
|
||||||
FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine);
|
|
||||||
|
|
||||||
// Returns the texture registrar associated with the engine.
|
|
||||||
FLUTTER_EXPORT FlutterDesktopTextureRegistrarRef
|
|
||||||
FlutterDesktopEngineGetTextureRegistrar(FlutterDesktopEngineRef engine);
|
|
||||||
|
|
||||||
// Schedule a callback to be called after the next frame is drawn.
|
|
||||||
//
|
|
||||||
// This must be called from the platform thread. The callback is executed only
|
|
||||||
// once on the platform thread.
|
|
||||||
FLUTTER_EXPORT void FlutterDesktopEngineSetNextFrameCallback(
|
|
||||||
FlutterDesktopEngineRef engine,
|
|
||||||
VoidCallback callback,
|
|
||||||
void* user_data);
|
|
||||||
|
|
||||||
// ========== View ==========
|
|
||||||
|
|
||||||
// Returns the backing HWND for manipulation in host application.
|
|
||||||
FLUTTER_EXPORT HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view);
|
|
||||||
|
|
||||||
// Returns the DXGI adapter used for rendering or nullptr in case of error.
|
|
||||||
FLUTTER_EXPORT IDXGIAdapter* FlutterDesktopViewGetGraphicsAdapter(
|
|
||||||
FlutterDesktopViewRef view);
|
|
||||||
|
|
||||||
// Called to pass an external window message to the engine for lifecycle
|
|
||||||
// state updates. Non-Flutter windows must call this method in their WndProc
|
|
||||||
// in order to be included in the logic for application lifecycle state
|
|
||||||
// updates. Returns a result if the message should be consumed.
|
|
||||||
FLUTTER_EXPORT bool FlutterDesktopEngineProcessExternalWindowMessage(
|
|
||||||
FlutterDesktopEngineRef engine,
|
|
||||||
HWND hwnd,
|
|
||||||
UINT message,
|
|
||||||
WPARAM wparam,
|
|
||||||
LPARAM lparam,
|
|
||||||
LRESULT* result);
|
|
||||||
|
|
||||||
// ========== Plugin Registrar (extensions) ==========
|
|
||||||
// These are Windows-specific extensions to flutter_plugin_registrar.h
|
|
||||||
|
|
||||||
// Function pointer type for top level WindowProc delegate registration.
|
|
||||||
//
|
|
||||||
// The user data will be whatever was passed to
|
|
||||||
// FlutterDesktopRegisterTopLevelWindowProcHandler.
|
|
||||||
//
|
|
||||||
// Implementations should populate |result| and return true if the WindowProc
|
|
||||||
// was handled and further handling should stop. |result| is ignored if the
|
|
||||||
// function returns false.
|
|
||||||
typedef bool (*FlutterDesktopWindowProcCallback)(HWND /* hwnd */,
|
|
||||||
UINT /* uMsg */,
|
|
||||||
WPARAM /*wParam*/,
|
|
||||||
LPARAM /* lParam*/,
|
|
||||||
void* /* user data */,
|
|
||||||
LRESULT* result);
|
|
||||||
|
|
||||||
// Returns the implicit view associated with this registrar's engine instance,
|
|
||||||
// or null if there is no implicit view.
|
|
||||||
//
|
|
||||||
// See:
|
|
||||||
// https://api.flutter.dev/flutter/dart-ui/PlatformDispatcher/implicitView.html
|
|
||||||
//
|
|
||||||
// DEPRECATED: Use |FlutterDesktopPluginRegistrarGetViewById| instead.
|
|
||||||
FLUTTER_EXPORT FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView(
|
|
||||||
FlutterDesktopPluginRegistrarRef registrar);
|
|
||||||
|
|
||||||
// Returns the view associated with the registrar's engine instance, or null if
|
|
||||||
// the view does not exist.
|
|
||||||
FLUTTER_EXPORT FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetViewById(
|
|
||||||
FlutterDesktopPluginRegistrarRef registrar,
|
|
||||||
FlutterDesktopViewId view_id);
|
|
||||||
|
|
||||||
FLUTTER_EXPORT void
|
|
||||||
FlutterDesktopPluginRegistrarRegisterTopLevelWindowProcDelegate(
|
|
||||||
FlutterDesktopPluginRegistrarRef registrar,
|
|
||||||
FlutterDesktopWindowProcCallback delegate,
|
|
||||||
void* user_data);
|
|
||||||
|
|
||||||
FLUTTER_EXPORT void
|
|
||||||
FlutterDesktopPluginRegistrarUnregisterTopLevelWindowProcDelegate(
|
|
||||||
FlutterDesktopPluginRegistrarRef registrar,
|
|
||||||
FlutterDesktopWindowProcCallback delegate);
|
|
||||||
|
|
||||||
// ========== Freestanding Utilities ==========
|
|
||||||
|
|
||||||
// Gets the DPI for a given |hwnd|, depending on the supported APIs per
|
|
||||||
// windows version and DPI awareness mode. If nullptr is passed, returns the DPI
|
|
||||||
// of the primary monitor.
|
|
||||||
//
|
|
||||||
// This uses the same logic and fallback for older Windows versions that is used
|
|
||||||
// internally by Flutter to determine the DPI to use for displaying Flutter
|
|
||||||
// content, so should be used by any code (e.g., in plugins) that translates
|
|
||||||
// between Windows and Dart sizes/offsets.
|
|
||||||
FLUTTER_EXPORT UINT FlutterDesktopGetDpiForHWND(HWND hwnd);
|
|
||||||
|
|
||||||
// Gets the DPI for a given |monitor|. If the API is not available, a default
|
|
||||||
// DPI of 96 is returned.
|
|
||||||
//
|
|
||||||
// See FlutterDesktopGetDpiForHWND for more information.
|
|
||||||
FLUTTER_EXPORT UINT FlutterDesktopGetDpiForMonitor(HMONITOR monitor);
|
|
||||||
|
|
||||||
// Reopens stdout and stderr and resysncs the standard library output streams.
|
|
||||||
// Should be called if output is being directed somewhere in the runner process
|
|
||||||
// (e.g., after an AllocConsole call).
|
|
||||||
FLUTTER_EXPORT void FlutterDesktopResyncOutputStreams();
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
} // extern "C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_PUBLIC_FLUTTER_WINDOWS_H_
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
# Generated code do not commit.
|
|
||||||
file(TO_CMAKE_PATH "C:\\flutter" FLUTTER_ROOT)
|
|
||||||
file(TO_CMAKE_PATH "C:\\Users\\Jacques\\Git\\xtremflow" PROJECT_DIR)
|
|
||||||
|
|
||||||
set(FLUTTER_VERSION "1.0.0+1" PARENT_SCOPE)
|
|
||||||
set(FLUTTER_VERSION_MAJOR 1 PARENT_SCOPE)
|
|
||||||
set(FLUTTER_VERSION_MINOR 0 PARENT_SCOPE)
|
|
||||||
set(FLUTTER_VERSION_PATCH 0 PARENT_SCOPE)
|
|
||||||
set(FLUTTER_VERSION_BUILD 1 PARENT_SCOPE)
|
|
||||||
|
|
||||||
# Environment variables to pass to tool_backend.sh
|
|
||||||
list(APPEND FLUTTER_TOOL_ENVIRONMENT
|
|
||||||
"FLUTTER_ROOT=C:\\flutter"
|
|
||||||
"PROJECT_DIR=C:\\Users\\Jacques\\Git\\xtremflow"
|
|
||||||
"FLUTTER_ROOT=C:\\flutter"
|
|
||||||
"FLUTTER_EPHEMERAL_DIR=C:\\Users\\Jacques\\Git\\xtremflow\\windows\\flutter\\ephemeral"
|
|
||||||
"PROJECT_DIR=C:\\Users\\Jacques\\Git\\xtremflow"
|
|
||||||
"FLUTTER_TARGET=lib\\main.dart"
|
|
||||||
"DART_DEFINES=RkxVVFRFUl9WRVJTSU9OPTMuMzguNQ==,RkxVVFRFUl9DSEFOTkVMPXN0YWJsZQ==,RkxVVFRFUl9HSVRfVVJMPWh0dHBzOi8vZ2l0aHViLmNvbS9mbHV0dGVyL2ZsdXR0ZXIuZ2l0,RkxVVFRFUl9GUkFNRVdPUktfUkVWSVNJT049ZjZmZjE1MjlmZA==,RkxVVFRFUl9FTkdJTkVfUkVWSVNJT049MTUyN2FlMGVjNQ==,RkxVVFRFUl9EQVJUX1ZFUlNJT049My4xMC40"
|
|
||||||
"DART_OBFUSCATION=false"
|
|
||||||
"TRACK_WIDGET_CREATION=true"
|
|
||||||
"TREE_SHAKE_ICONS=true"
|
|
||||||
"PACKAGE_CONFIG=C:\\Users\\Jacques\\Git\\xtremflow\\.dart_tool\\package_config.json"
|
|
||||||
)
|
|
||||||
Binary file not shown.
@@ -1,14 +0,0 @@
|
|||||||
//
|
|
||||||
// Generated file. Do not edit.
|
|
||||||
//
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
|
||||||
|
|
||||||
#include <video_player_win/video_player_win_plugin_c_api.h>
|
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
|
||||||
VideoPlayerWinPluginCApiRegisterWithRegistrar(
|
|
||||||
registry->GetRegistrarForPlugin("VideoPlayerWinPluginCApi"));
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
//
|
|
||||||
// Generated file. Do not edit.
|
|
||||||
//
|
|
||||||
|
|
||||||
// clang-format off
|
|
||||||
|
|
||||||
#ifndef GENERATED_PLUGIN_REGISTRANT_
|
|
||||||
#define GENERATED_PLUGIN_REGISTRANT_
|
|
||||||
|
|
||||||
#include <flutter/plugin_registry.h>
|
|
||||||
|
|
||||||
// Registers Flutter plugins.
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry);
|
|
||||||
|
|
||||||
#endif // GENERATED_PLUGIN_REGISTRANT_
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#
|
|
||||||
# Generated file, do not edit.
|
|
||||||
#
|
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
|
||||||
video_player_win
|
|
||||||
)
|
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
|
||||||
)
|
|
||||||
|
|
||||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
|
||||||
|
|
||||||
foreach(plugin ${FLUTTER_PLUGIN_LIST})
|
|
||||||
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
|
|
||||||
target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
|
|
||||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
|
|
||||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
|
|
||||||
endforeach(plugin)
|
|
||||||
|
|
||||||
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
|
|
||||||
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
|
|
||||||
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
|
|
||||||
endforeach(ffi_plugin)
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.14)
|
|
||||||
project(runner LANGUAGES CXX)
|
|
||||||
|
|
||||||
# Define the application target. To change its name, change BINARY_NAME in the
|
|
||||||
# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
|
|
||||||
# work.
|
|
||||||
#
|
|
||||||
# Any new source files that you add to the application should be added here.
|
|
||||||
add_executable(${BINARY_NAME} WIN32
|
|
||||||
"flutter_window.cpp"
|
|
||||||
"main.cpp"
|
|
||||||
"utils.cpp"
|
|
||||||
"win32_window.cpp"
|
|
||||||
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
|
|
||||||
"Runner.rc"
|
|
||||||
"runner.exe.manifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Apply the standard set of build settings. This can be removed for applications
|
|
||||||
# that need different build settings.
|
|
||||||
apply_standard_settings(${BINARY_NAME})
|
|
||||||
|
|
||||||
# Add preprocessor definitions for the build version.
|
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"")
|
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}")
|
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}")
|
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}")
|
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}")
|
|
||||||
|
|
||||||
# Disable Windows macros that collide with C++ standard library functions.
|
|
||||||
target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
|
|
||||||
|
|
||||||
# Add dependency libraries and include directories. Add any application-specific
|
|
||||||
# dependencies here.
|
|
||||||
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
|
|
||||||
target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib")
|
|
||||||
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
|
|
||||||
|
|
||||||
# Run the Flutter tool portions of the build. This must not be removed.
|
|
||||||
add_dependencies(${BINARY_NAME} flutter_assemble)
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
// Microsoft Visual C++ generated resource script.
|
|
||||||
//
|
|
||||||
#pragma code_page(65001)
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "winres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (United States) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
|
||||||
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// TEXTINCLUDE
|
|
||||||
//
|
|
||||||
|
|
||||||
1 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"resource.h\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
2 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"#include ""winres.h""\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
3 TEXTINCLUDE
|
|
||||||
BEGIN
|
|
||||||
"\r\n"
|
|
||||||
"\0"
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // APSTUDIO_INVOKED
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
IDI_APP_ICON ICON "resources\\app_icon.ico"
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Version
|
|
||||||
//
|
|
||||||
|
|
||||||
#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
|
|
||||||
#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
|
|
||||||
#else
|
|
||||||
#define VERSION_AS_NUMBER 1,0,0,0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(FLUTTER_VERSION)
|
|
||||||
#define VERSION_AS_STRING FLUTTER_VERSION
|
|
||||||
#else
|
|
||||||
#define VERSION_AS_STRING "1.0.0"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
|
||||||
FILEVERSION VERSION_AS_NUMBER
|
|
||||||
PRODUCTVERSION VERSION_AS_NUMBER
|
|
||||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FILEFLAGS VS_FF_DEBUG
|
|
||||||
#else
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
#endif
|
|
||||||
FILEOS VOS__WINDOWS32
|
|
||||||
FILETYPE VFT_APP
|
|
||||||
FILESUBTYPE 0x0L
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040904e4"
|
|
||||||
BEGIN
|
|
||||||
VALUE "CompanyName", "com.example" "\0"
|
|
||||||
VALUE "FileDescription", "xtremflow" "\0"
|
|
||||||
VALUE "FileVersion", VERSION_AS_STRING "\0"
|
|
||||||
VALUE "InternalName", "xtremflow" "\0"
|
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2025 com.example. All rights reserved." "\0"
|
|
||||||
VALUE "OriginalFilename", "xtremflow.exe" "\0"
|
|
||||||
VALUE "ProductName", "xtremflow" "\0"
|
|
||||||
VALUE "ProductVersion", VERSION_AS_STRING "\0"
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x409, 1252
|
|
||||||
END
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // English (United States) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef APSTUDIO_INVOKED
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 3 resource.
|
|
||||||
//
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#endif // not APSTUDIO_INVOKED
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
#include "flutter_window.h"
|
|
||||||
|
|
||||||
#include <optional>
|
|
||||||
|
|
||||||
#include "flutter/generated_plugin_registrant.h"
|
|
||||||
|
|
||||||
FlutterWindow::FlutterWindow(const flutter::DartProject& project)
|
|
||||||
: project_(project) {}
|
|
||||||
|
|
||||||
FlutterWindow::~FlutterWindow() {}
|
|
||||||
|
|
||||||
bool FlutterWindow::OnCreate() {
|
|
||||||
if (!Win32Window::OnCreate()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RECT frame = GetClientArea();
|
|
||||||
|
|
||||||
// The size here must match the window dimensions to avoid unnecessary surface
|
|
||||||
// creation / destruction in the startup path.
|
|
||||||
flutter_controller_ = std::make_unique<flutter::FlutterViewController>(
|
|
||||||
frame.right - frame.left, frame.bottom - frame.top, project_);
|
|
||||||
// Ensure that basic setup of the controller was successful.
|
|
||||||
if (!flutter_controller_->engine() || !flutter_controller_->view()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
RegisterPlugins(flutter_controller_->engine());
|
|
||||||
SetChildContent(flutter_controller_->view()->GetNativeWindow());
|
|
||||||
|
|
||||||
flutter_controller_->engine()->SetNextFrameCallback([&]() {
|
|
||||||
this->Show();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Flutter can complete the first frame before the "show window" callback is
|
|
||||||
// registered. The following call ensures a frame is pending to ensure the
|
|
||||||
// window is shown. It is a no-op if the first frame hasn't completed yet.
|
|
||||||
flutter_controller_->ForceRedraw();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlutterWindow::OnDestroy() {
|
|
||||||
if (flutter_controller_) {
|
|
||||||
flutter_controller_ = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Win32Window::OnDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT
|
|
||||||
FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
|
|
||||||
WPARAM const wparam,
|
|
||||||
LPARAM const lparam) noexcept {
|
|
||||||
// Give Flutter, including plugins, an opportunity to handle window messages.
|
|
||||||
if (flutter_controller_) {
|
|
||||||
std::optional<LRESULT> result =
|
|
||||||
flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
|
|
||||||
lparam);
|
|
||||||
if (result) {
|
|
||||||
return *result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (message) {
|
|
||||||
case WM_FONTCHANGE:
|
|
||||||
flutter_controller_->engine()->ReloadSystemFonts();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
#ifndef RUNNER_FLUTTER_WINDOW_H_
|
|
||||||
#define RUNNER_FLUTTER_WINDOW_H_
|
|
||||||
|
|
||||||
#include <flutter/dart_project.h>
|
|
||||||
#include <flutter/flutter_view_controller.h>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "win32_window.h"
|
|
||||||
|
|
||||||
// A window that does nothing but host a Flutter view.
|
|
||||||
class FlutterWindow : public Win32Window {
|
|
||||||
public:
|
|
||||||
// Creates a new FlutterWindow hosting a Flutter view running |project|.
|
|
||||||
explicit FlutterWindow(const flutter::DartProject& project);
|
|
||||||
virtual ~FlutterWindow();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Win32Window:
|
|
||||||
bool OnCreate() override;
|
|
||||||
void OnDestroy() override;
|
|
||||||
LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
|
|
||||||
LPARAM const lparam) noexcept override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
// The project to run.
|
|
||||||
flutter::DartProject project_;
|
|
||||||
|
|
||||||
// The Flutter instance hosted by this window.
|
|
||||||
std::unique_ptr<flutter::FlutterViewController> flutter_controller_;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RUNNER_FLUTTER_WINDOW_H_
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
#include <flutter/dart_project.h>
|
|
||||||
#include <flutter/flutter_view_controller.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "flutter_window.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
|
|
||||||
_In_ wchar_t *command_line, _In_ int show_command) {
|
|
||||||
// Attach to console when present (e.g., 'flutter run') or create a
|
|
||||||
// new console when running with a debugger.
|
|
||||||
if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
|
|
||||||
CreateAndAttachConsole();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize COM, so that it is available for use in the library and/or
|
|
||||||
// plugins.
|
|
||||||
::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
|
|
||||||
|
|
||||||
flutter::DartProject project(L"data");
|
|
||||||
|
|
||||||
std::vector<std::string> command_line_arguments =
|
|
||||||
GetCommandLineArguments();
|
|
||||||
|
|
||||||
project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
|
|
||||||
|
|
||||||
FlutterWindow window(project);
|
|
||||||
Win32Window::Point origin(10, 10);
|
|
||||||
Win32Window::Size size(1280, 720);
|
|
||||||
if (!window.Create(L"xtremflow", origin, size)) {
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
window.SetQuitOnClose(true);
|
|
||||||
|
|
||||||
::MSG msg;
|
|
||||||
while (::GetMessage(&msg, nullptr, 0, 0)) {
|
|
||||||
::TranslateMessage(&msg);
|
|
||||||
::DispatchMessage(&msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
::CoUninitialize();
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Visual C++ generated include file.
|
|
||||||
// Used by Runner.rc
|
|
||||||
//
|
|
||||||
#define IDI_APP_ICON 101
|
|
||||||
|
|
||||||
// Next default values for new objects
|
|
||||||
//
|
|
||||||
#ifdef APSTUDIO_INVOKED
|
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 102
|
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 33 KiB |
@@ -1,14 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
|
||||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
|
||||||
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
|
||||||
<windowsSettings>
|
|
||||||
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
|
||||||
</windowsSettings>
|
|
||||||
</application>
|
|
||||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
|
||||||
<application>
|
|
||||||
<!-- Windows 10 and Windows 11 -->
|
|
||||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
|
|
||||||
</application>
|
|
||||||
</compatibility>
|
|
||||||
</assembly>
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#include <flutter_windows.h>
|
|
||||||
#include <io.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
void CreateAndAttachConsole() {
|
|
||||||
if (::AllocConsole()) {
|
|
||||||
FILE *unused;
|
|
||||||
if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
|
|
||||||
_dup2(_fileno(stdout), 1);
|
|
||||||
}
|
|
||||||
if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
|
|
||||||
_dup2(_fileno(stdout), 2);
|
|
||||||
}
|
|
||||||
std::ios::sync_with_stdio();
|
|
||||||
FlutterDesktopResyncOutputStreams();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> GetCommandLineArguments() {
|
|
||||||
// Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
|
|
||||||
int argc;
|
|
||||||
wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
|
|
||||||
if (argv == nullptr) {
|
|
||||||
return std::vector<std::string>();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> command_line_arguments;
|
|
||||||
|
|
||||||
// Skip the first argument as it's the binary name.
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
command_line_arguments.push_back(Utf8FromUtf16(argv[i]));
|
|
||||||
}
|
|
||||||
|
|
||||||
::LocalFree(argv);
|
|
||||||
|
|
||||||
return command_line_arguments;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Utf8FromUtf16(const wchar_t* utf16_string) {
|
|
||||||
if (utf16_string == nullptr) {
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
unsigned int target_length = ::WideCharToMultiByte(
|
|
||||||
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
|
|
||||||
-1, nullptr, 0, nullptr, nullptr)
|
|
||||||
-1; // remove the trailing null character
|
|
||||||
int input_length = (int)wcslen(utf16_string);
|
|
||||||
std::string utf8_string;
|
|
||||||
if (target_length == 0 || target_length > utf8_string.max_size()) {
|
|
||||||
return utf8_string;
|
|
||||||
}
|
|
||||||
utf8_string.resize(target_length);
|
|
||||||
int converted_length = ::WideCharToMultiByte(
|
|
||||||
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
|
|
||||||
input_length, utf8_string.data(), target_length, nullptr, nullptr);
|
|
||||||
if (converted_length == 0) {
|
|
||||||
return std::string();
|
|
||||||
}
|
|
||||||
return utf8_string;
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
#ifndef RUNNER_UTILS_H_
|
|
||||||
#define RUNNER_UTILS_H_
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// Creates a console for the process, and redirects stdout and stderr to
|
|
||||||
// it for both the runner and the Flutter library.
|
|
||||||
void CreateAndAttachConsole();
|
|
||||||
|
|
||||||
// Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
|
|
||||||
// encoded in UTF-8. Returns an empty std::string on failure.
|
|
||||||
std::string Utf8FromUtf16(const wchar_t* utf16_string);
|
|
||||||
|
|
||||||
// Gets the command line arguments passed in as a std::vector<std::string>,
|
|
||||||
// encoded in UTF-8. Returns an empty std::vector<std::string> on failure.
|
|
||||||
std::vector<std::string> GetCommandLineArguments();
|
|
||||||
|
|
||||||
#endif // RUNNER_UTILS_H_
|
|
||||||
@@ -1,288 +0,0 @@
|
|||||||
#include "win32_window.h"
|
|
||||||
|
|
||||||
#include <dwmapi.h>
|
|
||||||
#include <flutter_windows.h>
|
|
||||||
|
|
||||||
#include "resource.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
/// Window attribute that enables dark mode window decorations.
|
|
||||||
///
|
|
||||||
/// Redefined in case the developer's machine has a Windows SDK older than
|
|
||||||
/// version 10.0.22000.0.
|
|
||||||
/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
|
|
||||||
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
|
|
||||||
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
|
|
||||||
#endif
|
|
||||||
|
|
||||||
constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
|
|
||||||
|
|
||||||
/// Registry key for app theme preference.
|
|
||||||
///
|
|
||||||
/// A value of 0 indicates apps should use dark mode. A non-zero or missing
|
|
||||||
/// value indicates apps should use light mode.
|
|
||||||
constexpr const wchar_t kGetPreferredBrightnessRegKey[] =
|
|
||||||
L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
|
|
||||||
constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme";
|
|
||||||
|
|
||||||
// The number of Win32Window objects that currently exist.
|
|
||||||
static int g_active_window_count = 0;
|
|
||||||
|
|
||||||
using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd);
|
|
||||||
|
|
||||||
// Scale helper to convert logical scaler values to physical using passed in
|
|
||||||
// scale factor
|
|
||||||
int Scale(int source, double scale_factor) {
|
|
||||||
return static_cast<int>(source * scale_factor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module.
|
|
||||||
// This API is only needed for PerMonitor V1 awareness mode.
|
|
||||||
void EnableFullDpiSupportIfAvailable(HWND hwnd) {
|
|
||||||
HMODULE user32_module = LoadLibraryA("User32.dll");
|
|
||||||
if (!user32_module) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto enable_non_client_dpi_scaling =
|
|
||||||
reinterpret_cast<EnableNonClientDpiScaling*>(
|
|
||||||
GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
|
|
||||||
if (enable_non_client_dpi_scaling != nullptr) {
|
|
||||||
enable_non_client_dpi_scaling(hwnd);
|
|
||||||
}
|
|
||||||
FreeLibrary(user32_module);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
// Manages the Win32Window's window class registration.
|
|
||||||
class WindowClassRegistrar {
|
|
||||||
public:
|
|
||||||
~WindowClassRegistrar() = default;
|
|
||||||
|
|
||||||
// Returns the singleton registrar instance.
|
|
||||||
static WindowClassRegistrar* GetInstance() {
|
|
||||||
if (!instance_) {
|
|
||||||
instance_ = new WindowClassRegistrar();
|
|
||||||
}
|
|
||||||
return instance_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the name of the window class, registering the class if it hasn't
|
|
||||||
// previously been registered.
|
|
||||||
const wchar_t* GetWindowClass();
|
|
||||||
|
|
||||||
// Unregisters the window class. Should only be called if there are no
|
|
||||||
// instances of the window.
|
|
||||||
void UnregisterWindowClass();
|
|
||||||
|
|
||||||
private:
|
|
||||||
WindowClassRegistrar() = default;
|
|
||||||
|
|
||||||
static WindowClassRegistrar* instance_;
|
|
||||||
|
|
||||||
bool class_registered_ = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr;
|
|
||||||
|
|
||||||
const wchar_t* WindowClassRegistrar::GetWindowClass() {
|
|
||||||
if (!class_registered_) {
|
|
||||||
WNDCLASS window_class{};
|
|
||||||
window_class.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
|
||||||
window_class.lpszClassName = kWindowClassName;
|
|
||||||
window_class.style = CS_HREDRAW | CS_VREDRAW;
|
|
||||||
window_class.cbClsExtra = 0;
|
|
||||||
window_class.cbWndExtra = 0;
|
|
||||||
window_class.hInstance = GetModuleHandle(nullptr);
|
|
||||||
window_class.hIcon =
|
|
||||||
LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON));
|
|
||||||
window_class.hbrBackground = 0;
|
|
||||||
window_class.lpszMenuName = nullptr;
|
|
||||||
window_class.lpfnWndProc = Win32Window::WndProc;
|
|
||||||
RegisterClass(&window_class);
|
|
||||||
class_registered_ = true;
|
|
||||||
}
|
|
||||||
return kWindowClassName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void WindowClassRegistrar::UnregisterWindowClass() {
|
|
||||||
UnregisterClass(kWindowClassName, nullptr);
|
|
||||||
class_registered_ = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Win32Window::Win32Window() {
|
|
||||||
++g_active_window_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
Win32Window::~Win32Window() {
|
|
||||||
--g_active_window_count;
|
|
||||||
Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Win32Window::Create(const std::wstring& title,
|
|
||||||
const Point& origin,
|
|
||||||
const Size& size) {
|
|
||||||
Destroy();
|
|
||||||
|
|
||||||
const wchar_t* window_class =
|
|
||||||
WindowClassRegistrar::GetInstance()->GetWindowClass();
|
|
||||||
|
|
||||||
const POINT target_point = {static_cast<LONG>(origin.x),
|
|
||||||
static_cast<LONG>(origin.y)};
|
|
||||||
HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST);
|
|
||||||
UINT dpi = FlutterDesktopGetDpiForMonitor(monitor);
|
|
||||||
double scale_factor = dpi / 96.0;
|
|
||||||
|
|
||||||
HWND window = CreateWindow(
|
|
||||||
window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
|
|
||||||
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
|
|
||||||
Scale(size.width, scale_factor), Scale(size.height, scale_factor),
|
|
||||||
nullptr, nullptr, GetModuleHandle(nullptr), this);
|
|
||||||
|
|
||||||
if (!window) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateTheme(window);
|
|
||||||
|
|
||||||
return OnCreate();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Win32Window::Show() {
|
|
||||||
return ShowWindow(window_handle_, SW_SHOWNORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
|
||||||
LRESULT CALLBACK Win32Window::WndProc(HWND const window,
|
|
||||||
UINT const message,
|
|
||||||
WPARAM const wparam,
|
|
||||||
LPARAM const lparam) noexcept {
|
|
||||||
if (message == WM_NCCREATE) {
|
|
||||||
auto window_struct = reinterpret_cast<CREATESTRUCT*>(lparam);
|
|
||||||
SetWindowLongPtr(window, GWLP_USERDATA,
|
|
||||||
reinterpret_cast<LONG_PTR>(window_struct->lpCreateParams));
|
|
||||||
|
|
||||||
auto that = static_cast<Win32Window*>(window_struct->lpCreateParams);
|
|
||||||
EnableFullDpiSupportIfAvailable(window);
|
|
||||||
that->window_handle_ = window;
|
|
||||||
} else if (Win32Window* that = GetThisFromHandle(window)) {
|
|
||||||
return that->MessageHandler(window, message, wparam, lparam);
|
|
||||||
}
|
|
||||||
|
|
||||||
return DefWindowProc(window, message, wparam, lparam);
|
|
||||||
}
|
|
||||||
|
|
||||||
LRESULT
|
|
||||||
Win32Window::MessageHandler(HWND hwnd,
|
|
||||||
UINT const message,
|
|
||||||
WPARAM const wparam,
|
|
||||||
LPARAM const lparam) noexcept {
|
|
||||||
switch (message) {
|
|
||||||
case WM_DESTROY:
|
|
||||||
window_handle_ = nullptr;
|
|
||||||
Destroy();
|
|
||||||
if (quit_on_close_) {
|
|
||||||
PostQuitMessage(0);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case WM_DPICHANGED: {
|
|
||||||
auto newRectSize = reinterpret_cast<RECT*>(lparam);
|
|
||||||
LONG newWidth = newRectSize->right - newRectSize->left;
|
|
||||||
LONG newHeight = newRectSize->bottom - newRectSize->top;
|
|
||||||
|
|
||||||
SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth,
|
|
||||||
newHeight, SWP_NOZORDER | SWP_NOACTIVATE);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
case WM_SIZE: {
|
|
||||||
RECT rect = GetClientArea();
|
|
||||||
if (child_content_ != nullptr) {
|
|
||||||
// Size and position the child window.
|
|
||||||
MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left,
|
|
||||||
rect.bottom - rect.top, TRUE);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
case WM_ACTIVATE:
|
|
||||||
if (child_content_ != nullptr) {
|
|
||||||
SetFocus(child_content_);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
case WM_DWMCOLORIZATIONCOLORCHANGED:
|
|
||||||
UpdateTheme(hwnd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return DefWindowProc(window_handle_, message, wparam, lparam);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win32Window::Destroy() {
|
|
||||||
OnDestroy();
|
|
||||||
|
|
||||||
if (window_handle_) {
|
|
||||||
DestroyWindow(window_handle_);
|
|
||||||
window_handle_ = nullptr;
|
|
||||||
}
|
|
||||||
if (g_active_window_count == 0) {
|
|
||||||
WindowClassRegistrar::GetInstance()->UnregisterWindowClass();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept {
|
|
||||||
return reinterpret_cast<Win32Window*>(
|
|
||||||
GetWindowLongPtr(window, GWLP_USERDATA));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win32Window::SetChildContent(HWND content) {
|
|
||||||
child_content_ = content;
|
|
||||||
SetParent(content, window_handle_);
|
|
||||||
RECT frame = GetClientArea();
|
|
||||||
|
|
||||||
MoveWindow(content, frame.left, frame.top, frame.right - frame.left,
|
|
||||||
frame.bottom - frame.top, true);
|
|
||||||
|
|
||||||
SetFocus(child_content_);
|
|
||||||
}
|
|
||||||
|
|
||||||
RECT Win32Window::GetClientArea() {
|
|
||||||
RECT frame;
|
|
||||||
GetClientRect(window_handle_, &frame);
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
HWND Win32Window::GetHandle() {
|
|
||||||
return window_handle_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win32Window::SetQuitOnClose(bool quit_on_close) {
|
|
||||||
quit_on_close_ = quit_on_close;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Win32Window::OnCreate() {
|
|
||||||
// No-op; provided for subclasses.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win32Window::OnDestroy() {
|
|
||||||
// No-op; provided for subclasses.
|
|
||||||
}
|
|
||||||
|
|
||||||
void Win32Window::UpdateTheme(HWND const window) {
|
|
||||||
DWORD light_mode;
|
|
||||||
DWORD light_mode_size = sizeof(light_mode);
|
|
||||||
LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey,
|
|
||||||
kGetPreferredBrightnessRegValue,
|
|
||||||
RRF_RT_REG_DWORD, nullptr, &light_mode,
|
|
||||||
&light_mode_size);
|
|
||||||
|
|
||||||
if (result == ERROR_SUCCESS) {
|
|
||||||
BOOL enable_dark_mode = light_mode == 0;
|
|
||||||
DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE,
|
|
||||||
&enable_dark_mode, sizeof(enable_dark_mode));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,102 +0,0 @@
|
|||||||
#ifndef RUNNER_WIN32_WINDOW_H_
|
|
||||||
#define RUNNER_WIN32_WINDOW_H_
|
|
||||||
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
// A class abstraction for a high DPI-aware Win32 Window. Intended to be
|
|
||||||
// inherited from by classes that wish to specialize with custom
|
|
||||||
// rendering and input handling
|
|
||||||
class Win32Window {
|
|
||||||
public:
|
|
||||||
struct Point {
|
|
||||||
unsigned int x;
|
|
||||||
unsigned int y;
|
|
||||||
Point(unsigned int x, unsigned int y) : x(x), y(y) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Size {
|
|
||||||
unsigned int width;
|
|
||||||
unsigned int height;
|
|
||||||
Size(unsigned int width, unsigned int height)
|
|
||||||
: width(width), height(height) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
Win32Window();
|
|
||||||
virtual ~Win32Window();
|
|
||||||
|
|
||||||
// Creates a win32 window with |title| that is positioned and sized using
|
|
||||||
// |origin| and |size|. New windows are created on the default monitor. Window
|
|
||||||
// sizes are specified to the OS in physical pixels, hence to ensure a
|
|
||||||
// consistent size this function will scale the inputted width and height as
|
|
||||||
// as appropriate for the default monitor. The window is invisible until
|
|
||||||
// |Show| is called. Returns true if the window was created successfully.
|
|
||||||
bool Create(const std::wstring& title, const Point& origin, const Size& size);
|
|
||||||
|
|
||||||
// Show the current window. Returns true if the window was successfully shown.
|
|
||||||
bool Show();
|
|
||||||
|
|
||||||
// Release OS resources associated with window.
|
|
||||||
void Destroy();
|
|
||||||
|
|
||||||
// Inserts |content| into the window tree.
|
|
||||||
void SetChildContent(HWND content);
|
|
||||||
|
|
||||||
// Returns the backing Window handle to enable clients to set icon and other
|
|
||||||
// window properties. Returns nullptr if the window has been destroyed.
|
|
||||||
HWND GetHandle();
|
|
||||||
|
|
||||||
// If true, closing this window will quit the application.
|
|
||||||
void SetQuitOnClose(bool quit_on_close);
|
|
||||||
|
|
||||||
// Return a RECT representing the bounds of the current client area.
|
|
||||||
RECT GetClientArea();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Processes and route salient window messages for mouse handling,
|
|
||||||
// size change and DPI. Delegates handling of these to member overloads that
|
|
||||||
// inheriting classes can handle.
|
|
||||||
virtual LRESULT MessageHandler(HWND window,
|
|
||||||
UINT const message,
|
|
||||||
WPARAM const wparam,
|
|
||||||
LPARAM const lparam) noexcept;
|
|
||||||
|
|
||||||
// Called when CreateAndShow is called, allowing subclass window-related
|
|
||||||
// setup. Subclasses should return false if setup fails.
|
|
||||||
virtual bool OnCreate();
|
|
||||||
|
|
||||||
// Called when Destroy is called.
|
|
||||||
virtual void OnDestroy();
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class WindowClassRegistrar;
|
|
||||||
|
|
||||||
// OS callback called by message pump. Handles the WM_NCCREATE message which
|
|
||||||
// is passed when the non-client area is being created and enables automatic
|
|
||||||
// non-client DPI scaling so that the non-client area automatically
|
|
||||||
// responds to changes in DPI. All other messages are handled by
|
|
||||||
// MessageHandler.
|
|
||||||
static LRESULT CALLBACK WndProc(HWND const window,
|
|
||||||
UINT const message,
|
|
||||||
WPARAM const wparam,
|
|
||||||
LPARAM const lparam) noexcept;
|
|
||||||
|
|
||||||
// Retrieves a class instance pointer for |window|
|
|
||||||
static Win32Window* GetThisFromHandle(HWND const window) noexcept;
|
|
||||||
|
|
||||||
// Update the window frame's theme to match the system theme.
|
|
||||||
static void UpdateTheme(HWND const window);
|
|
||||||
|
|
||||||
bool quit_on_close_ = false;
|
|
||||||
|
|
||||||
// window handle for top level window.
|
|
||||||
HWND window_handle_ = nullptr;
|
|
||||||
|
|
||||||
// window handle for hosted content.
|
|
||||||
HWND child_content_ = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // RUNNER_WIN32_WINDOW_H_
|
|
||||||
Reference in new issue
Block a user