2014-04-12 16 views
8

Próbuję renderować przeglądarkę w boku mojego projektu monogame, do rysowania niektórych elementów interfejsu &. Zrobiłem to w przeszłości ze starszymi wersjami awesomium bez żadnych problemów. Ale nie mogę wymyślić, jak poprawnie zainicjować awesomium w tej nowej wersji, pojawia się błąd, bez względu na to, jak próbuję go rozwiązać. Jak rozumiem, muszę zadzwonić do WebCore.Run() tylko raz, zamiast WebCore.Update(), ale dostaję różne wyjątki od tej metody.Jak zaimplementować Awesomium 1.7.4.2 w projekcie Monogame?

Oto kroki, które I już po tej pory:

  1. Install Awesomium 1.7.4.2
  2. Refrenced \1.7.4.2\wrappers\Awesomium.NET\Assemblies\Packed\Awesomium.Core.dll w moim projekcie

Oto niektóre z moich prób:

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.. 

Mam również udało się błędy NullRefrence i gdybym czekać Thread.Sleep (400) przed wywołaniem WebCore.Run(), to po prostu wchodzi do WebCore.Run() i nigdy nie kończy tej linii.

Jak to ustawić? Nie można znaleźć żadnych przykładów w dowolnym miejscu. Wszystkie przykłady online nadal mówią, że należy użyć Aktualizacji, która jest Obsolete

+0

Walczę z tym samym. –

+0

Tak, nigdy go nie rozwiązałem ... Zdegradowałem do wersji 1.7.3.0 Ta wersja działa dobrze. Jeśli masz z nim jakiś związek, z chęcią Ci pomogę. – BjarkeCK

Odpowiedz

13

Właśnie to działało, musisz utworzyć nowy wątek, a następnie wywołać polecenie Uruchom, a następnie nasłuchiwać zdarzenia, które zostanie utworzone przez aplikację WebCore, która utworzy do tego czasu nowy Kontekst Synchronizacji. Następnie chcesz zachować odniesienie do tej sytuacji na głównym wątku ...

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() { }); 

... można następnie połączyć wszystkie swoje metody Webview użyciem że SynchronizationContext ...

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

będę posprzątaj to z przyszłą edycją, ale żebyście zaczęli, oto mój komponent ...

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

Awesome! Nigdy bym tego nie rozgryzł. Czy mogę zapytać, gdzie znalazłeś te informacje? – BjarkeCK

+0

Przeczytałem uwagi dotyczące metody Run i odhakowałem je, dopóki nie zadziałało. Aby wyświetlić uwagi, przejdź do GoToDefinition w metodzie Run, a następnie rozwiń zwinięty komentarz. –

+0

Świetne dzieło Dean. Chciałbym dać ci 1000 głosów za to. – ZafarYousafi

Powiązane problemy