Results 1 to 3 of 3

Thread: [RESOLVED] [2.0] Calling thread events

  1. #1

    Thread Starter
    Not NoteMe SLH's Avatar
    Join Date
    Mar 2002
    Location
    192.168.0.1 Preferred Animal: Penguin Reason for errors: Line#38
    Posts
    3,051

    [RESOLVED] [2.0] Calling thread events

    I'm creating a card game. I've got a GUIControl Class and a GameControl Class.
    The easiest (i think) way for me to get the functionallity i want is to have a perminant thread running in the GameControl class that purely acts upon events raised by the GUIControl class, performs game logic, then fires various GUIControl events.

    For example.
    The user clicks a card, which fires an event in the GameControl Class. The GUIControl thread then goes back to it's automatic message pumping, waiting for any events.
    The GameControl acts upon the card clicked event, perhaps to remove the card from play. It fires an event in the GUIControl indicating that a card has been destroyed. Then it resumes waiting for events.
    The GUIControl acts upon the card destroyed event, but removing the card control from the GUI.
    Both the GUIControl (thread) and the GameControl wait to deal with another event.

    I've seen many, many examples of raising an event in the GUI from a worker thread (the thread in my GameControl), but i just can't work out how i fire an event (asynchronously) on a worker thread, from the main GUI thread.

    Any help would be greatly appreciated!
    Last edited by SLH; Nov 30th, 2006 at 07:30 PM.
    Quotes:
    "I am getting better then you guys.." NoteMe, on his leet english skills.
    "And I am going to meat her again later on tonight." NoteMe
    "I think you should change your name to QuoteMe" Shaggy Hiker, regarding NoteMe
    "my sweet lord jesus. I've decided never to have breast implants" Tom Gibbons
    Have I helped you? Please Rate my posts.


  2. #2

    Thread Starter
    Not NoteMe SLH's Avatar
    Join Date
    Mar 2002
    Location
    192.168.0.1 Preferred Animal: Penguin Reason for errors: Line#38
    Posts
    3,051

    Re: [2.0] Calling thread events

    I've created a little test app to see if i can get that working first. I'm using several AutoResetEvents which a thread (my game thread) checks in a loop. From my GUI click events i set the AutoResetEvent, which the game thread acts upon.

    The trouble i'm having is that i can't use this same method in reverse (Having the GUI form watch for an AutoResetEvent being set) since it doesnt have a loop or anything. I guess it has a message pump internally, but trying to fiddle with that isn't the right way of doing this is it?

    So in order to get the GUI to act upon events that are caused by my game thread i'm using delegates and events declared in the same class as the game thread. When i create this game thread class in my form's load function i do a += with a method of the form. The trouble i'm now having is that it appears to be the game thread that runs the code when the event is fired, since i'm getting cross-thread operation not valid when i try and change any controls on the form. I know i could use Invoke etc. but isn't there a way of simply telling the GUI to run a method as a result of another thread's action?

    Anyway, here's the code, i've highlighted all the event/delegate stuff.

    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    
    namespace ThreadEvents
    {
        public partial class frmMain : Form
        {
            public frmMain()
            {
                InitializeComponent();
                GameControl GC = new GameControl();
                GameControl.OnGameNumberChanged += new GameControl.GameNumberChanged(GameControl_OnGameNumberChanged);
                GC.Init();
            }
    
            void GameControl_OnGameNumberChanged(object Sender, EventArgs e)
            {
                //How do i get this to run in the form's thread??
                lblOutput.Text = "Number Changed"; //Cross thread operation not valid
            }
    
            private void cmdGo_Click(object sender, EventArgs e)
            {
                CEvents.Go.Set();
            }
    
            private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
            {
                CEvents.EndGame.Set();
            }
        }
    
        public class GameControl
        {
            public delegate void GameNumberChanged(object Sender, EventArgs e);
            public static event GameNumberChanged OnGameNumberChanged;
    
            private Thread GameThread = new Thread(new ThreadStart(GameLoop));
            public void Init()
            {
                GameThread.Start();
            }
            public static void GameLoop()
            {
                while (!CEvents.EndGame.WaitOne(1, false))
                {
                    if (CEvents.Go.WaitOne(1, false))
                    {
                        if (OnGameNumberChanged != null)
                            OnGameNumberChanged(new object(), new EventArgs());
                    }
                }
                MessageBox.Show("Done!");
            }
        }
    
        public static class CEvents
        {
            public static AutoResetEvent Go = new AutoResetEvent(false);
            public static AutoResetEvent EndGame = new AutoResetEvent(false);
        }
    }
    Quotes:
    "I am getting better then you guys.." NoteMe, on his leet english skills.
    "And I am going to meat her again later on tonight." NoteMe
    "I think you should change your name to QuoteMe" Shaggy Hiker, regarding NoteMe
    "my sweet lord jesus. I've decided never to have breast implants" Tom Gibbons
    Have I helped you? Please Rate my posts.


  3. #3

    Thread Starter
    Not NoteMe SLH's Avatar
    Join Date
    Mar 2002
    Location
    192.168.0.1 Preferred Animal: Penguin Reason for errors: Line#38
    Posts
    3,051

    Re: [2.0] Calling thread events

    Managed to finally get it sorted, using the form's InvokeBegin method in the GameControl thread.
    For reference, here's the working code:

    Code:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Threading;
    
    namespace ThreadEvents
    {
        public partial class frmMain : Form
        {
            public frmMain()
            {
                Thread.CurrentThread.Name = "Form Thread";
                InitializeComponent();
                GameControl GC = new GameControl(this, OnNumberChanged);
                GC.Init();
            }
    
            void OnNumberChanged(int Number)
            {
                lblOutput.Text = "Set to " + Number.ToString() + " in the " + Thread.CurrentThread.Name;
            }
    
            private void cmdGo_Click(object sender, EventArgs e)
            {
                CEvents.Go.Set();
            }
    
            private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
            {
                CEvents.EndGame.Set();
            }
        }
    
        public class GameControl
        {
            public delegate void CallBack(int Number);
            static public CallBack CBMethod;
            static private Form F;
    
            public GameControl(frmMain Form, CallBack frmCallBack)
            {
                F = Form;
                CBMethod = frmCallBack;
            }
    
            private Thread GameThread = new Thread(new ThreadStart(GameLoop));
            public void Init()
            {
                GameThread.Name = "Game Thread";
                GameThread.Start();
            }
            public static void GameLoop()
            {
                while (!CEvents.EndGame.WaitOne(1, false))
                {
                    if (CEvents.Go.WaitOne(1, false))
                    {
                        F.BeginInvoke(CBMethod,10);
                    }
                }
                MessageBox.Show("Finished in the " + Thread.CurrentThread.Name);
            }
        }
    
        public static class CEvents
        {
            public static AutoResetEvent Go = new AutoResetEvent(false);
            public static AutoResetEvent EndGame = new AutoResetEvent(false);
        }
    }
    Quotes:
    "I am getting better then you guys.." NoteMe, on his leet english skills.
    "And I am going to meat her again later on tonight." NoteMe
    "I think you should change your name to QuoteMe" Shaggy Hiker, regarding NoteMe
    "my sweet lord jesus. I've decided never to have breast implants" Tom Gibbons
    Have I helped you? Please Rate my posts.


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width