2014-04-12 11 views
8

Ich versuche, einen Browser in Seite mein Monogame-Projekt zu rendern, zum Zeichnen einer Schnittstelle & Zeug. Ich habe dies in der Vergangenheit mit älteren Versionen von Awesomium ohne Probleme getan. Aber ich kann nicht herausfinden, wie Awesomium in dieser neuen Version richtig zu initialisieren, ich bekomme einen Fehler, egal wie ich es versuche. Wie ich es verstehe, muss ich WebCore.Run() einmal aufrufen, anstelle von WebCore.Update(), aber ich bekomme verschiedene Ausnahmen von dieser Methode.Wie implementiere ich Awesomium 1.7.4.2 in einem Monogame-Projekt?

Hier sind die Schritte, die ich bisher verfolgt hat:

  1. Installieren Awesomium 1.7.4.2
  2. Refrenced \1.7.4.2\wrappers\Awesomium.NET\Assemblies\Packed\Awesomium.Core.dll in meinem Projekt

Hier einige meiner Versuche:

WebCore.Initialize(new WebConfig()); 
    WebCore.Run(); 
    //Error: Starting an update loop on a thread with an existing message loop, is not supported. 

WebCore.Initialized += (sender, e) => 
    { 
     WebCore.Run(); 
    }; 
    WebCore.Initialize(new WebConfig()); 
    WebView WebView = WebCore.CreateWebView(500, 400); 
    //Error: Starting an update loop on a thread with an existing message loop, is not supported. 

WebCore.Initialize(new WebConfig()); 
    WebView WebView = WebCore.CreateWebView(500, 400); 
    WebView.Source = new Uri("http://www.google.com"); 
    WebView.DocumentReady += (sender, e) => 
    { 
     JSObject js = WebView.CreateGlobalJavascriptObject("w"); 
    }; 
    // No errors, but DocumentReady is never fired.. 

Ich habe es auch geschafft, NullRefrence Fehler zu bekommen, und wenn ich Thread.Sleep warten (400) vor dem Aufruf WebCore.Run(), es tritt nur die WebCore.Run() und schließt diese Zeile nie ab.

Wie richte ich das ein? Kann nirgendwo Beispiele finden. Alle Beispiele online sagen immer noch, dass Sie Update verwenden, was veraltet ist

+0

Ich kämpfe mit der gleichen Sache. –

+0

Ja, ich habe es nie gelöst ... Ich habe die Version 1.7.3.0 heruntergestuft. Diese Version funktioniert gut. Wenn Sie ein Problem damit haben, werde ich Ihnen gerne helfen. – BjarkeCK

Antwort

13

Ich habe gerade funktioniert, müssen Sie einen neuen Thread erstellen, dann rufen Sie Run, dann auf ein Ereignis von WebCore ausgelöst werden, die erstellt haben ein neuer SynchronizationContext bis dahin. Sie wollen dann in diesem Zusammenhang auf Ihrem Haupt-Thread eine Referenz halten ...

Thread awesomiumThread = new System.Threading.Thread(new System.Threading.ThreadStart(() => 
{ 
    WebCore.Started += (s, e) => { 
     awesomiumContext = SynchronizationContext.Current; 
    }; 

    WebCore.Run(); 
})); 

awesomiumThread.Start(); 

WebCore.Initialize(new WebConfig() { }); 

... können Sie dann alle Methoden WebView rufen mit, dass SynchronizationContext ...

awesomiumContext.Post(state => 
{ 
    this.WebView.Source = "http://www.google.com"; 
}, null); 

werde ich Ordne das mit einer zukünftigen Bearbeitung auf, aber um euch zu fangen, hier ist meine Komponente ...

using Awesomium.Core; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 

namespace AwesomiumComponent 
{ 
    public class BasicAwesomiumComponent : DrawableGameComponent 
    { 
     private Byte[] imageBytes; 
     private Rectangle area; 
     private Rectangle? newArea; 
     private Boolean resizing; 
     private SpriteBatch spriteBatch; 
     private Texture2D WebViewTexture { get; set; } 
     private SynchronizationContext awesomiumContext = null; 
     private WebView WebView { get; set; } 
     private BitmapSurface Surface { get; set; } 
     private MouseState lastMouseState; 
     private MouseState currentMouseState; 
     private Keys[] lastPressedKeys; 
     private Keys[] currentPressedKeys = new Keys[0]; 
     private static ManualResetEvent awesomiumReady = new ManualResetEvent(false); 

     public Rectangle Area 
     { 
      get { return this.area; } 
      set 
      { 
       this.newArea = value; 
      } 
     } 

     public BasicAwesomiumComponent(Game game, Rectangle area) 
      : base(game) 
     { 
      this.area = area; 

      this.spriteBatch = new SpriteBatch(game.GraphicsDevice); 


      Thread awesomiumThread = new System.Threading.Thread(new System.Threading.ThreadStart(() => 
      { 
       WebCore.Started += (s, e) => { 
        awesomiumContext = SynchronizationContext.Current; 
        awesomiumReady.Set(); 
       }; 

       WebCore.Run(); 
      })); 

      awesomiumThread.Start(); 

      WebCore.Initialize(new WebConfig() { }); 

      awesomiumReady.WaitOne(); 

      awesomiumContext.Post(state => 
      { 
       this.WebView = WebCore.CreateWebView(this.area.Width, this.area.Height, WebViewType.Offscreen); 

       this.WebView.IsTransparent = true; 
       this.WebView.CreateSurface += (s, e) => 
       { 
        this.Surface = new BitmapSurface(this.area.Width, this.area.Height); 
        e.Surface = this.Surface; 
       }; 
      }, null); 
     } 

     public void SetResourceInterceptor(IResourceInterceptor interceptor) 
     { 
      awesomiumContext.Post(state => 
      { 
       WebCore.ResourceInterceptor = interceptor; 
      }, null); 
     } 

     public void Execute(string method, params object[] args) 
     { 
      string script = string.Format("viewModel.{0}({1})", method, string.Join(",", args.Select(x => "\"" + x.ToString() + "\""))); 
      this.WebView.ExecuteJavascript(script); 
     } 

     public void RegisterFunction(string methodName, Action<object, CancelEventArgs> handler) 
     { 
      // Create and acquire a Global Javascript object. 
      // These object persist for the lifetime of the web-view. 
      using (JSObject myGlobalObject = this.WebView.CreateGlobalJavascriptObject("game")) 
      { 
       // The handler is of type JavascriptMethodEventHandler. Here we define it 
       // using a lambda expression. 

       myGlobalObject.Bind(methodName, true, (s, e) => 
       { 
        handler(s, e); 
        // Provide a response. 
        e.Result = "My response"; 
       }); 
      } 
     } 

     public void Load() 
     { 
      LoadContent(); 
     } 

     protected override void LoadContent() 
     { 
      if (this.area.IsEmpty) 
      { 
       this.area = this.GraphicsDevice.Viewport.Bounds; 
       this.newArea = this.GraphicsDevice.Viewport.Bounds; 
      } 
      this.WebViewTexture = new Texture2D(this.Game.GraphicsDevice, this.area.Width, this.area.Height, false, SurfaceFormat.Color); 

      this.imageBytes = new Byte[this.area.Width * 4 * this.area.Height]; 
     } 

     public override void Update(GameTime gameTime) 
     { 
      awesomiumContext.Post(state => 
      { 
       if (this.newArea.HasValue && !this.resizing && gameTime.TotalGameTime.TotalSeconds > 0.10f) 
       { 
        this.area = this.newArea.Value; 
        if (this.area.IsEmpty) 
         this.area = this.GraphicsDevice.Viewport.Bounds; 

        this.WebView.Resize(this.area.Width, this.area.Height); 
        this.WebViewTexture = new Texture2D(this.Game.GraphicsDevice, this.area.Width, this.area.Height, false, SurfaceFormat.Color); 
        this.imageBytes = new Byte[this.area.Width * 4 * this.area.Height]; 
        this.resizing = true; 

        this.newArea = null; 
       } 

       lastMouseState = currentMouseState; 
       currentMouseState = Mouse.GetState(); 

       this.WebView.InjectMouseMove(currentMouseState.X - this.area.X, currentMouseState.Y - this.area.Y); 

       if (currentMouseState.LeftButton == ButtonState.Pressed && lastMouseState.LeftButton == ButtonState.Released) 
       { 
        this.WebView.InjectMouseDown(MouseButton.Left); 
       } 
       if (currentMouseState.LeftButton == ButtonState.Released && lastMouseState.LeftButton == ButtonState.Pressed) 
       { 
        this.WebView.InjectMouseUp(MouseButton.Left); 
       } 
       if (currentMouseState.RightButton == ButtonState.Pressed && lastMouseState.RightButton == ButtonState.Released) 
       { 
        this.WebView.InjectMouseDown(MouseButton.Right); 
       } 
       if (currentMouseState.RightButton == ButtonState.Released && lastMouseState.RightButton == ButtonState.Pressed) 
       { 
        this.WebView.InjectMouseUp(MouseButton.Right); 
       } 
       if (currentMouseState.MiddleButton == ButtonState.Pressed && lastMouseState.MiddleButton == ButtonState.Released) 
       { 
        this.WebView.InjectMouseDown(MouseButton.Middle); 
       } 
       if (currentMouseState.MiddleButton == ButtonState.Released && lastMouseState.MiddleButton == ButtonState.Pressed) 
       { 
        this.WebView.InjectMouseUp(MouseButton.Middle); 
       } 

       if (currentMouseState.ScrollWheelValue != lastMouseState.ScrollWheelValue) 
       { 
        this.WebView.InjectMouseWheel((currentMouseState.ScrollWheelValue - lastMouseState.ScrollWheelValue), 0); 
       } 

       lastPressedKeys = currentPressedKeys; 
       currentPressedKeys = Keyboard.GetState().GetPressedKeys(); 

       // Key Down 
       foreach (var key in currentPressedKeys) 
       { 
        if (!lastPressedKeys.Contains(key)) 
        { 
         this.WebView.InjectKeyboardEvent(new WebKeyboardEvent() 
         { 
          Type = WebKeyboardEventType.KeyDown, 
          VirtualKeyCode = (VirtualKey)(int)key, 
          NativeKeyCode = (int)key 
         }); 

         if ((int)key >= 65 && (int)key <= 90) 
         { 
          this.WebView.InjectKeyboardEvent(new WebKeyboardEvent() 
          { 
           Type = WebKeyboardEventType.Char, 
           Text = key.ToString().ToLower() 
          }); 
         } 
         else if (key == Keys.Space) 
         { 
          this.WebView.InjectKeyboardEvent(new WebKeyboardEvent() 
          { 
           Type = WebKeyboardEventType.Char, 
           Text = " " 
          }); 
         } 
        } 
       } 

       // Key Up 
       foreach (var key in lastPressedKeys) 
       { 
        if (!currentPressedKeys.Contains(key)) 
        { 
         this.WebView.InjectKeyboardEvent(new WebKeyboardEvent() 
         { 
          Type = WebKeyboardEventType.KeyUp, 
          VirtualKeyCode = (VirtualKey)(int)key, 
          NativeKeyCode = (int)key 
         }); 
        } 
       } 

      }, null); 

      base.Update(gameTime); 
     } 

     public override void Draw(GameTime gameTime) 
     { 
      awesomiumContext.Post(state => 
      { 
       if (Surface != null && Surface.IsDirty && !resizing) 
       { 
        unsafe 
        { 
         // This part saves us from double copying everything. 
         fixed (Byte* imagePtr = this.imageBytes) 
         { 
          Surface.CopyTo((IntPtr)imagePtr, Surface.Width * 4, 4, true, false); 
         } 
        } 
        this.WebViewTexture.SetData(this.imageBytes); 
       } 
      }, null); 

      Vector2 pos = new Vector2(0, 0); 
      spriteBatch.Begin(); 
      spriteBatch.Draw(this.WebViewTexture, pos, Color.White); 
      spriteBatch.End(); 
      GraphicsDevice.Textures[0] = null; 

      base.Draw(gameTime); 
     } 

     public Uri Source 
     { 
      get 
      { 
       return this.WebView.Source; 
      } 
      set 
      { 
       awesomiumContext.Post(state => 
       { 
        this.WebView.Source = value; 
       }, null); 
      } 
     } 

     public void Resize(int width, int height) 
     { 
      this.newArea = new Rectangle(0, 0, width, height); ; 
     } 
    } 
} 
+0

Super! Das hätte ich nie herausgefunden. Kann ich fragen, wo Sie diese Informationen gefunden haben? – BjarkeCK

+0

Ich las die Bemerkungen zur Run-Methode und hackte davon ab, bis ich es funktionierte. Um die Anmerkungen anzuzeigen, GoToDefinition für die Methode Run, erweitern Sie dann den minimierten Kommentar. –

+0

Großartige Arbeit Dean. Ich wünschte, ich könnte dir dafür 1000 Stimmen geben. – ZafarYousafi

Verwandte Themen