mirror of
https://gitee.com/energye/energy.git
synced 2024-11-29 18:28:06 +08:00
Fix: #32 The rendering process ipc listens for adding a frameId group.
Add a frame object to implement the ipc target.IWindow interface
This commit is contained in:
parent
8a7cedb131
commit
70c2fb82e1
@ -13,6 +13,7 @@
|
||||
package cef
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/energye/energy/v2/cef/internal/ipc"
|
||||
"github.com/energye/energy/v2/cef/internal/process"
|
||||
"github.com/energye/energy/v2/consts"
|
||||
@ -21,11 +22,12 @@ import (
|
||||
|
||||
// 创建应用上下文 - 默认实现
|
||||
func appOnContextCreated(browser *ICefBrowser, frame *ICefFrame, context *ICefV8Context) {
|
||||
fmt.Println("appOnContextCreated browserId:", browser.Identifier(), " frameId:", frame.Identifier(), "IsMain:", frame.IsMain())
|
||||
process.Current.SetBrowserId(browser.Identifier()) // 当前进程 browserID
|
||||
process.Current.SetFrameId(frame.Identifier()) // 当前进程 frameId
|
||||
ipc.RenderChan().SetRealityChannel(browser.Identifier(), frame.Identifier()) // 设置并更新真实的通道ID
|
||||
ipcRender.registerGoWaitReplayEvent() // render ipc
|
||||
ipcRender.makeIPC(context) // render ipc make
|
||||
ipcRender.makeIPC(frame.Identifier(), context) // render ipc make
|
||||
makeProcess(browser, frame, context) // process make
|
||||
}
|
||||
|
||||
|
@ -654,6 +654,7 @@ func init() {
|
||||
dllimports.NewEnergyImport("CEFBrowser_StopLoad", 0),
|
||||
dllimports.NewEnergyImport("CEFBrowser_FrameCount", 0),
|
||||
dllimports.NewEnergyImport("CEFBrowser_GetFrameNames", 0),
|
||||
dllimports.NewEnergyImport("CEFBrowser_GetFrameIdentifiers", 0),
|
||||
dllimports.NewEnergyImport("CEFBrowser_Find", 0),
|
||||
dllimports.NewEnergyImport("CEFBrowser_StopFinding", 0),
|
||||
dllimports.NewEnergyImport("CEFBrowser_GetRequestContext", 0),
|
||||
|
@ -654,6 +654,7 @@ const (
|
||||
CEFBrowser_StopLoad
|
||||
CEFBrowser_FrameCount
|
||||
CEFBrowser_GetFrameNames
|
||||
CEFBrowser_GetFrameIdentifiers
|
||||
CEFBrowser_Find
|
||||
CEFBrowser_StopFinding
|
||||
CEFBrowser_GetRequestContext
|
||||
|
38
cef/ipc.go
38
cef/ipc.go
@ -52,7 +52,7 @@ var (
|
||||
ipcBrowser *ipcBrowserProcess // 主进程 IPC
|
||||
)
|
||||
|
||||
// ipcEmitHandler ipc.emit 处理器
|
||||
// ipc.emit 处理器
|
||||
type ipcEmitHandler struct {
|
||||
handler *ICefV8Handler // ipc.emit handler
|
||||
handlerSync *ICefV8Handler // ipc.emitSync handler
|
||||
@ -61,14 +61,14 @@ type ipcEmitHandler struct {
|
||||
callbackLock sync.Mutex // ipc.emit lock
|
||||
}
|
||||
|
||||
// ipcOnHandler ipc.on 处理器
|
||||
// ipc.on 处理器
|
||||
type ipcOnHandler struct {
|
||||
handler *ICefV8Handler // ipc.on handler
|
||||
callbackList map[string]*ipcCallback // ipc.on callbackList
|
||||
callbackLock sync.Mutex // ipc.emit lock
|
||||
}
|
||||
|
||||
// ipcCallback ipc.emit 回调结果
|
||||
// ipc.emit 回调结果
|
||||
type ipcCallback struct {
|
||||
isSync bool //同否同步 true:同步 false:异步, 默认false
|
||||
resultType result_type //返回值类型 0:function 1:variable 默认:0
|
||||
@ -77,7 +77,7 @@ type ipcCallback struct {
|
||||
name *ICefV8Value //事件名称
|
||||
}
|
||||
|
||||
// isIPCInternalKey IPC 内部定义使用 key 不允许使用
|
||||
// IPC 内部定义使用 key 不允许使用
|
||||
func isIPCInternalKey(key string) bool {
|
||||
return key == internalIPC || key == internalIPCEmit || key == internalIPCOn || key == internalIPCDRAG || key == internalIPCEmitWait ||
|
||||
key == internalIPCJSExecuteGoEvent || key == internalIPCJSExecuteGoEventReplay ||
|
||||
@ -86,15 +86,15 @@ func isIPCInternalKey(key string) bool {
|
||||
|
||||
}
|
||||
|
||||
// ipcInit 初始化
|
||||
// 初始化
|
||||
func ipcInit() {
|
||||
isSingleProcess := application.SingleProcess()
|
||||
if isSingleProcess {
|
||||
ipcBrowser = &ipcBrowserProcess{}
|
||||
ipcRender = &ipcRenderProcess{
|
||||
waitChan: &ipc.WaitChan{Pending: new(sync.Map)},
|
||||
emitHandler: &ipcEmitHandler{callbackList: make(map[int32]*ipcCallback)},
|
||||
onHandler: &ipcOnHandler{callbackList: make(map[string]*ipcCallback)},
|
||||
waitChan: &ipc.WaitChan{Pending: new(sync.Map)},
|
||||
emitHandler: &ipcEmitHandler{callbackList: make(map[int32]*ipcCallback)},
|
||||
onFrameHandler: make(map[int64]*ipcOnHandler),
|
||||
}
|
||||
ipc.CreateBrowserIPC() // Go IPC browser
|
||||
ipc.CreateRenderIPC(0, time.Now().UnixNano()/1e6) // Go IPC render
|
||||
@ -104,16 +104,16 @@ func ipcInit() {
|
||||
ipc.CreateBrowserIPC() // Go IPC browser
|
||||
} else if process.Args.IsRender() {
|
||||
ipcRender = &ipcRenderProcess{
|
||||
waitChan: &ipc.WaitChan{Pending: new(sync.Map)},
|
||||
emitHandler: &ipcEmitHandler{callbackList: make(map[int32]*ipcCallback)},
|
||||
onHandler: &ipcOnHandler{callbackList: make(map[string]*ipcCallback)},
|
||||
waitChan: &ipc.WaitChan{Pending: new(sync.Map)},
|
||||
emitHandler: &ipcEmitHandler{callbackList: make(map[int32]*ipcCallback)},
|
||||
onFrameHandler: make(map[int64]*ipcOnHandler),
|
||||
}
|
||||
ipc.CreateRenderIPC(0, time.Now().UnixNano()/1e6) // Go IPC render
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// addCallback
|
||||
// 添加一个回调函数
|
||||
func (m *ipcEmitHandler) addCallback(callback *ipcCallback) int32 {
|
||||
//return uintptr(unsafe.Pointer(m.callbackList.PushBack(callback)))
|
||||
m.callbackLock.Lock()
|
||||
@ -122,7 +122,7 @@ func (m *ipcEmitHandler) addCallback(callback *ipcCallback) int32 {
|
||||
return m.callbackMessageId
|
||||
}
|
||||
|
||||
// nextMessageId 获取下一个消息ID
|
||||
// 获取下一个消息ID
|
||||
func (m *ipcEmitHandler) nextMessageId() int32 {
|
||||
m.callbackMessageId++
|
||||
if m.callbackMessageId == -1 {
|
||||
@ -131,7 +131,7 @@ func (m *ipcEmitHandler) nextMessageId() int32 {
|
||||
return m.callbackMessageId
|
||||
}
|
||||
|
||||
// getCallback 返回回调函数
|
||||
// 返回回调函数
|
||||
func (m *ipcEmitHandler) getCallback(messageId int32) *ipcCallback {
|
||||
//return (*list.Element)(unsafe.Pointer(ptr)).Value.(*ipcCallback)
|
||||
m.callbackLock.Lock()
|
||||
@ -143,7 +143,7 @@ func (m *ipcEmitHandler) getCallback(messageId int32) *ipcCallback {
|
||||
return nil
|
||||
}
|
||||
|
||||
// clear 清空所有回调函数
|
||||
// 清空所有回调函数
|
||||
func (m *ipcEmitHandler) clear() {
|
||||
for _, v := range m.callbackList {
|
||||
v.function.SetCanNotFree(false)
|
||||
@ -154,7 +154,7 @@ func (m *ipcEmitHandler) clear() {
|
||||
m.callbackList = make(map[int32]*ipcCallback)
|
||||
}
|
||||
|
||||
// addCallback 根据事件名添加回调函数
|
||||
// 根据事件名添加回调函数
|
||||
func (m *ipcOnHandler) addCallback(eventName string, callback *ipcCallback) {
|
||||
//return uintptr(unsafe.Pointer(m.callbackList.PushBack(callback)))
|
||||
m.callbackLock.Lock()
|
||||
@ -168,7 +168,7 @@ func (m *ipcOnHandler) addCallback(eventName string, callback *ipcCallback) {
|
||||
m.callbackList[eventName] = callback
|
||||
}
|
||||
|
||||
// removeCallback 根据事件名移除回调函数
|
||||
// 根据事件名移除回调函数
|
||||
func (m *ipcOnHandler) removeCallback(eventName string) {
|
||||
//m.callbackList.Remove((*list.Element)(unsafe.Pointer(ptr)))
|
||||
m.callbackLock.Lock()
|
||||
@ -176,7 +176,7 @@ func (m *ipcOnHandler) removeCallback(eventName string) {
|
||||
delete(m.callbackList, eventName)
|
||||
}
|
||||
|
||||
// getCallback 根据事件名返回回调函数
|
||||
// 根据事件名返回回调函数
|
||||
func (m *ipcOnHandler) getCallback(eventName string) *ipcCallback {
|
||||
//return (*list.Element)(unsafe.Pointer(ptr)).Value.(*ipcCallback)
|
||||
m.callbackLock.Lock()
|
||||
@ -184,7 +184,7 @@ func (m *ipcOnHandler) getCallback(eventName string) *ipcCallback {
|
||||
return m.callbackList[eventName]
|
||||
}
|
||||
|
||||
// clear 清空所有回调函数
|
||||
// 清空所有回调函数
|
||||
func (m *ipcOnHandler) clear() {
|
||||
for _, v := range m.callbackList {
|
||||
v.function.SetCanNotFree(false)
|
||||
|
@ -26,24 +26,27 @@ import (
|
||||
// ipcRenderProcess 渲染进程
|
||||
type ipcRenderProcess struct {
|
||||
isInitRenderIPC bool
|
||||
ipcObject *ICefV8Value // ipc object
|
||||
emitHandler *ipcEmitHandler // ipc.emit handler
|
||||
onHandler *ipcOnHandler // ipc.on handler
|
||||
ipcObject *ICefV8Value // ipc object
|
||||
emitHandler *ipcEmitHandler // ipc.emit handler
|
||||
onHandler map[int64]*ipcOnHandler // ipc.on handler
|
||||
waitChan *ipc.WaitChan
|
||||
}
|
||||
|
||||
func (m *ipcRenderProcess) clear() {
|
||||
func (m *ipcRenderProcess) clear(frameId int64) {
|
||||
if m.ipcObject != nil {
|
||||
m.ipcObject.Free()
|
||||
m.ipcObject = nil
|
||||
}
|
||||
if m.onHandler != nil {
|
||||
m.onHandler.clear()
|
||||
if on, ok := m.onHandler[frameId]; ok {
|
||||
on.clear()
|
||||
delete(m.onHandler, frameId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// jsOnEvent JS ipc.on 监听事件
|
||||
func (m *ipcRenderProcess) jsOnEvent(name string, object *ICefV8Value, arguments *TCefV8ValueArray, retVal *ResultV8Value, exception *ResultString) (result bool) {
|
||||
// JS ipc.on 监听事件
|
||||
func (m *ipcOnHandler) jsOnEvent(name string, object *ICefV8Value, arguments *TCefV8ValueArray, retVal *ResultV8Value, exception *ResultString) (result bool) {
|
||||
if name != internalIPCOn {
|
||||
return
|
||||
} else if arguments.Size() != 2 { //必须是2个参数
|
||||
@ -74,13 +77,17 @@ func (m *ipcRenderProcess) jsOnEvent(name string, object *ICefV8Value, arguments
|
||||
onCallback.SetCanNotFree(true)
|
||||
onNameValue = onName.GetStringValue()
|
||||
//ipc on
|
||||
m.onHandler.addCallback(onNameValue, &ipcCallback{function: V8ValueRef.UnWrap(onCallback), name: V8ValueRef.UnWrap(onName)})
|
||||
m.addCallback(onNameValue, &ipcCallback{function: V8ValueRef.UnWrap(onCallback), name: V8ValueRef.UnWrap(onName)})
|
||||
result = true
|
||||
return
|
||||
}
|
||||
|
||||
// Go ipc.emit 执行JS事件
|
||||
func (m *ipcRenderProcess) ipcGoExecuteJSEvent(browser *ICefBrowser, frame *ICefFrame, sourceProcess consts.CefProcessId, message *ICefProcessMessage) (result bool) {
|
||||
on, ok := m.onHandler[frame.Identifier()]
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
result = true
|
||||
argumentListBytes := message.ArgumentList().GetBinary(0)
|
||||
//接收二进制数据失败
|
||||
@ -120,7 +127,7 @@ func (m *ipcRenderProcess) ipcGoExecuteJSEvent(browser *ICefBrowser, frame *ICef
|
||||
}
|
||||
}()
|
||||
|
||||
if callback := ipcRender.onHandler.getCallback(emitName); callback != nil {
|
||||
if callback := on.getCallback(emitName); callback != nil {
|
||||
var callbackArgsBytes interface{}
|
||||
//enter v8context
|
||||
ctx := frame.V8Context()
|
||||
@ -737,10 +744,10 @@ func (m *ipcRenderProcess) ipcJSExecuteGoSyncEventMessageReply(messageId int32,
|
||||
}
|
||||
|
||||
// ipc
|
||||
func (m *ipcRenderProcess) makeIPC(context *ICefV8Context) {
|
||||
func (m *ipcRenderProcess) makeIPC(frameId int64, context *ICefV8Context) {
|
||||
if m.ipcObject != nil {
|
||||
// 刷新时释放掉
|
||||
m.clear()
|
||||
m.clear(frameId)
|
||||
}
|
||||
// ipc emit
|
||||
m.emitHandler.handler = V8HandlerRef.New()
|
||||
@ -751,14 +758,24 @@ func (m *ipcRenderProcess) makeIPC(context *ICefV8Context) {
|
||||
m.emitHandler.handlerSync.Execute(m.jsExecuteGoEvent)
|
||||
|
||||
// ipc on
|
||||
m.onHandler.handler = V8HandlerRef.New()
|
||||
m.onHandler.handler.Execute(m.jsOnEvent)
|
||||
var on *ipcOnHandler
|
||||
if handler, ok := m.onHandler[frameId]; ok {
|
||||
on = handler
|
||||
} else {
|
||||
on = &ipcOnHandler{handler: V8HandlerRef.New(), callbackList: make(map[string]*ipcCallback)}
|
||||
on.handler.Execute(on.jsOnEvent)
|
||||
m.onHandler[frameId] = on
|
||||
}
|
||||
|
||||
//m.onHandler.handler = V8HandlerRef.New()
|
||||
//m.onHandler.handler.Execute(m.jsOnEvent)
|
||||
//on.handler = V8HandlerRef.New()
|
||||
|
||||
// ipc object
|
||||
m.ipcObject = V8ValueRef.NewObject(nil)
|
||||
m.ipcObject.setValueByKey(internalIPCEmit, V8ValueRef.newFunction(internalIPCEmit, m.emitHandler.handler), consts.V8_PROPERTY_ATTRIBUTE_READONLY)
|
||||
m.ipcObject.setValueByKey(internalIPCEmitWait, V8ValueRef.newFunction(internalIPCEmitWait, m.emitHandler.handlerSync), consts.V8_PROPERTY_ATTRIBUTE_READONLY)
|
||||
m.ipcObject.setValueByKey(internalIPCOn, V8ValueRef.newFunction(internalIPCOn, m.onHandler.handler), consts.V8_PROPERTY_ATTRIBUTE_READONLY)
|
||||
m.ipcObject.setValueByKey(internalIPCOn, V8ValueRef.newFunction(internalIPCOn, on.handler), consts.V8_PROPERTY_ATTRIBUTE_READONLY)
|
||||
|
||||
// ipc key to v8 global
|
||||
context.Global().setValueByKey(internalIPC, m.ipcObject, consts.V8_PROPERTY_ATTRIBUTE_READONLY)
|
||||
|
@ -520,6 +520,15 @@ func (m *ICefBrowser) GetFrameNames() []*FrameNames {
|
||||
return frameNames
|
||||
}
|
||||
|
||||
func (m *ICefBrowser) GetFrameIdentifiers() []int64 {
|
||||
var list uintptr
|
||||
var count uint32
|
||||
var ids uintptr
|
||||
imports.Proc(def.CEFBrowser_GetFrameIdentifiers).Call(m.Instance(), uintptr(unsafe.Pointer(&list)), uintptr(unsafe.Pointer(&count)), uintptr(unsafe.Pointer(&ids)))
|
||||
// TODO 未取到正确结果
|
||||
return nil
|
||||
}
|
||||
|
||||
// Find 检索页面文本
|
||||
func (m *ICefBrowser) Find(searchText string, forward, matchCase, findNext bool) {
|
||||
if !m.IsValid() {
|
||||
|
@ -264,6 +264,28 @@ func (m *ICefFrame) Parent() *ICefFrame {
|
||||
return &ICefFrame{instance: unsafe.Pointer(result)}
|
||||
}
|
||||
|
||||
func (m *ICefFrame) Target(targetType ...target.Type) target.ITarget {
|
||||
if !m.IsValid() {
|
||||
return nil
|
||||
}
|
||||
browse := m.Browser()
|
||||
if !browse.IsValid() {
|
||||
return nil
|
||||
}
|
||||
return target.NewTarget(m, browse.Identifier(), m.Identifier(), targetType...)
|
||||
}
|
||||
|
||||
func (m *ICefFrame) IsClosing() bool {
|
||||
return false //Determine whether the window has been closed by oneself
|
||||
}
|
||||
|
||||
func (m *ICefFrame) ProcessMessage() target.IProcessMessage {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *ICefFrame) Free() {
|
||||
if !m.IsValid() {
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user