From where the voud pong acquire pulse? - c#

This example, i have commented the monitor.pulse()+monitor.wait in void ping,but when i run the code it still run void pong for one time, althought it's lock!! Beside that i tried to run thr thread without join so they run separatly...but still void pong run for one time....i want to know what is the cause, why it run when there is no pulse and it's lock
using System;
using System.Threading;
namespace WaitndPulesMethod
{
class PingPong   
{
        public void ping(bool running)
        {
            lock (this)
            {
                if (!running)
                {
                    //ball halts.              
Monitor.Pulse(this); // notify any waiting threads
     return;
                }
                Console.Write("Ping ");
                //Monitor.Pulse(this); // let pong() run
               Monitor.Wait(this); // wait for pong() to complete            }
        }
        public void pong(bool running)
        {
            lock (this)
            {
                if (!running)
                {
                    //ball halts.
                    Monitor.Pulse(this); // notify any waiting threads
                    return;
                }
                Console.WriteLine("Pong ");
                Monitor.Pulse(this); // let ping() run
                Monitor.Wait(this); // wait for ping() to complete
            }
        }
    }
    class MyThread    {
        public Thread thread;
        PingPong pingpongObject;
        //construct a new thread.
        public MyThread(string name, PingPong pp)
        {
            thread = new Thread(new ThreadStart(this.run));
            pingpongObject = pp;
            thread.Name = name;
            thread.Start();
        }
        //Begin execution of new thread.
        void run()
        {
            if (thread.Name == "Ping")
            {
                for (int i = 0; i < 5; i++)
                    pingpongObject.ping(true);
                pingpongObject.ping(false);
            }
            else            {
                for (int i = 0; i < 5; i++)
                    pingpongObject.pong(true);
                pingpongObject.pong(false);
            }
        }
    }
    class BouncingBall    {
        public static void Main()
        {
            PingPong pp = new PingPong();
            Console.WriteLine("The Ball is dropped... \n");
            MyThread mythread1 = new MyThread("Ping", pp);
            MyThread mythread2 = new MyThread("Pong", pp); 
            mythread1.thread.Join();
            mythread2.thread.Join();
            Console.WriteLine("\nThe Ball Stops Bouncing.");
            Console.Read();
        }
    }
}
nd function still working
Output shown is, ping pong ping
While it shoulf be pong ping or pong

Related

C# Datagridview - Row back colour not working per row

I have three checkboxes on my access database and depending on which ones are checked, I want each row within the Datagridview to be a specific colour.
True, False, False - Row should be Blue
False, False, False - Row should be Yellow
True, True, False - Row should be Red
True, False, True - Row should be Green
My code below seems to work properly when I filter my database but not when I view all entries (it just makes all rows one colour [yellow]).
Here is the code I've written so far:
private void sJDataGridView_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
        {
            Color viewModeColour = Color.White; // Default Colour
            Color viewModeColourRGB = Color.FromArgb(viewModeColour.R, viewModeColour.G, viewModeColour.B);
            foreach (DataGridViewRow row in sJDataGridView.Rows)
            {
                if (Convert.ToBoolean(row.Cells[14].Value) == true)
                {
                    if (Convert.ToBoolean(row.Cells[15].Value) == true)
                    {
                        viewModeColour = Color.FromArgb(0xFF8787); // Red
                    }
                    else
                    {
                        if (Convert.ToBoolean(row.Cells[16].Value) == false)
                        {
                            viewModeColour = Color.FromArgb(0xE3F7FF); // Blue
                        }
                        else
                        {
                            viewModeColour = Color.FromArgb(0xE5FFCC); // Green
                        }
                    }
                }
                else
                {
                    if (Convert.ToBoolean(row.Cells[15].Value) == false)
                    {
                        if (Convert.ToBoolean(row.Cells[16].Value) == false)
                        {
                            viewModeColour = Color.FromArgb(0xFFFDCC); // Yellow
                        }
                    }
                }
                viewModeColourRGB = Color.FromArgb(viewModeColour.R, viewModeColour.G, viewModeColour.B);
            }
 
            for (int i = 0; i < sJDataGridView.Rows.Count; i++)
            {
                sJDataGridView.Rows[i].DefaultCellStyle.BackColor = viewModeColourRGB;
            }    
             
        }
    }
Try to check each of your condition in different if statement block.
And apply DefaultCellStyle inside your foreach block.
foreach (DataGridViewRow row in sJDataGridView.Rows)
{
bool a = Convert.ToBoolean(row.Cells[14].Value);
bool b = Convert.ToBoolean(row.Cells[15].Value);
bool c = Convert.ToBoolean(row.Cells[16].Value);
if (a == true && b == false && c == false)
viewModeColour = Color.FromArgb(0xE3F7FF); // Blue
if (a == false && b == false && c == false)
viewModeColour = Color.FromArgb(0xFFFDCC); // Yellow
if (a == true && b == true && c == false)
viewModeColour = Color.FromArgb(0xFF8787); // Red
if (a == true && b == false && c == true)
viewModeColour = Color.FromArgb(0xE5FFCC); // Green
viewModeColourRGB = Color.FromArgb(viewModeColour.R, viewModeColour.G, viewModeColour.B);
row.DefaultCellStyle.BackColor = viewModeColourRGB;
}

timer stop activating during while statement

I have a timer and it pull data from a PLC. I have a part where I write data to a PLC and then I write for a reply from the PLC.
there a flag and I am waiting for it to change to true.
my timer is reading the flag...
but when I get to my while statement, the timer stops firing up.
why ?
here is my code :
void movePixalLinkCam(int pos)
{
bool flag;
if (state == 2)
{
flag = true;
tcClient.WriteAny(Pos0number, Convert.ToDouble(pos));
tcClient.WriteAny(Axis0MoveStartnumber, flag);
while(!Axis0MoveFlag)
{
}
flag = false;
tcClient.WriteAny(Axis0MoveStartnumber, flag);
}
}
the timer seem to stop during the while statement .
why?
should I put this function on a different thread or something ?
Update
private void timer1_Tick(object sender, EventArgs e)
{
try
{
dataStream.Position = 0;
tcClient.Read(Axis0MoveFlagnumber, dataStream);
Axis0MoveFlag = binRead.ReadBoolean();
dataStream.Position = 0;}
catch (Exception err)
{
MessageBox.Show(err.Message.ToString());
}

A pause menu using a button and click

I'd like to know how I can pause and unpause menu from the same button using the mouse pointer when I click on it.
Lets say I have this. C#
void Update () {
if (Button_Pause.OnPointerClick()) {
if(!active){
PauseGame();
}
else{
ResumeGame();
}
active = !active;
}
}
public void PauseGame()
{
Button_Pause = Button_Pause.GetComponent<Button> ();
Canvas_PauseMenu.enabled = true;
Button_Exit.enabled = true;
Button_Pause.enabled = true;
}
public void ResumeGame()
{
Canvas_PauseMenu.enabled = false;
Button_Exit.enabled = false;
Button_Pause.enabled = false;
}
In the first line, where I call the OnPointerClick I'm just guessing because I don't know what to do. What I've searched around, using click to show something it's having a TimeScale or something like that.
¿Can anyone help moi? Please.
Add a listener for your button and in your pause script set timescale to zero to pause the game
[SerializeField] private Button MyButton = null; // assign in the editor
void Start() { MyButton.onClick.AddListener(() => { pause();});
}
void pause(){
if (Time.timeScale == 1)
{
Time.timeScale = 0;
}
else
{
Time.timeScale = 1;
}
}
I managed to solve the issue. It might not be efficient but it does what I need.
I created 2 buttons in the same place. Those buttons are represented with different sprites (Pause & Play). "Pause" is visible since the start. When I click on it, the menu pops up, the "Pause" stop being active and the "Play" sprite button activates and pops up too. When I click on it, I unpause and goes back to the "Pause" sprite visible in the screen.
void Start () {
Canvas_PauseMenu = Canvas_PauseMenu.GetComponent<Canvas> ();
Button_Pause = Button_Pause.GetComponent<Button> ();
Button_Resume = Button_Resume.GetComponent<Button> ();
Canvas_PauseMenu.enabled = false;
Button_Resume.enabled = false;
Button_Resume.gameObject.SetActive (false);
}
// Update is called once per frame
public void PauseTest () {
if(!active){
PauseGame();
}
else{
ResumeGame();
}
}
public void BackToMainMenu()
{
Application.LoadLevel (0);
}
public void PauseGame()
{
Canvas_PauseMenu.enabled = true;
Button_Exit.enabled = true;
Button_Pause.enabled = false;
Button_Pause.gameObject.SetActive (false);
Button_Resume.enabled = true;
Button_Resume.gameObject.SetActive (true);
active = true;
Time.timeScale = 0;
}
public void ResumeGame()
{
Canvas_PauseMenu.enabled = false;
Button_Exit.enabled = false;
Button_Pause.enabled = true;
Button_Pause.gameObject.SetActive (true);
Button_Resume.enabled = false;
Button_Resume.gameObject.SetActive (false);
active = false;
Time.timeScale = 1;
}

C# lambda call in for loop references to last object

I've researched this problem and I've tried fixing the code as instructed in a few questions before (such as this one) but it still won't work. Though I must say that all the answers I checked were from 2009-2010 so they might be obsolete.
This is the culprit code:
foreach(Entity player in players)
{
if(player.actions.Count > 0)
{
Entity temp = player;
player.isDoingAction = true;
Debug.Log(player.name + " started action");
player.actions.Dequeue().Execute(() => { temp.isDoingAction = false; Debug.Log(temp.name + " finished"); });
}
}
This prints the following:
Player1 started action
Player2 started action
Player2 finished
Player2 finished
When it should print:
Player1 started action
Player2 started action
Player1 finished
Player2 finished
Or something similar.
This code runs in a Unity coroutine function.
A bit larger snip from the code:
GameManager.cs
private IEnumerator RunTurn()
{
...
...
...
for(int i = 0; i < phases; i++)
{
//Assign action to each player
foreach(Entity player in players)
{
if(player.actions.Count > 0)
{
Entity temp = player;
player.isDoingAction = true;
Debug.Log(player.name + " started action");
player.actions.Dequeue().Execute(() => { temp.isDoingAction = false; Debug.Log(temp.name + " finished"); });
}
}
//Wait for each player to finish action
foreach(Entity player in players)
{
while(player.isDoingAction == true)
{
Debug.Log("Waiting for " + player.name);
yield return null;
}
}
}
...
...
...
}
Action.cs
public override void Execute(System.Action callback)
{
Move(callback);
}
private void Move(System.Action callback)
{
...
...
...
//Move target entity
target.MoveToPosition(newPosition, mSpeed, callback);
target.location = newLocation;
...
...
...
}
Entity.cs
public void MoveToPosition(Vector3 position, float speed, System.Action callback)
{
StartCoroutine(CoMoveToPosition(position, speed, callback));
}
//Move to position
private IEnumerator CoMoveToPosition(Vector3 position, float speed, System.Action callback)
{
while(position != transform.position)
{
transform.position = Vector3.MoveTowards(transform.position, position, speed * Time.deltaTime);
yield return null;
}
//Move finished so use callback
callback();
}
Solution
It turns out there is a bug in Unity with coroutines and anonymous lambda callbacks. Check this link for more.
Working piece of code:
foreach(Entity player in players)
{
if(player.actions.Count > 0)
{
player.isDoingAction = true;
Debug.Log(player.name + " started action");
System.Func<Entity, System.Action> action = new System.Func<Entity,System.Action>(p =>
new System.Action(() => { p.isDoingAction = false; Debug.Log(p.name + " finished"); }));
player.actions.Dequeue().Execute(action(player));
}
}
You can capture the value the following way:
var action = new Func<Entity, Action>(p =>
new Action(() => { p.isDoingAction = false; Debug.Log(p.name + " finished")); })(player);
player.actions.Dequeue().Execute(action);
Try
player.actions.Dequeue().Execute(temp =>
{ temp.isDoingAction = false;
Debug.Log(temp.name + " finished");
});

Make GUI.Box stay for 3 seconds

I'm working on a project in Unity using C# scripting. The GUI.Box will appear at the top the screen. The box will disappear when the player leaves the spot. How can I make the box stay there for an additional 3 seconds after the player leaves the designated spot?
Danpe's code corrected (working code):
bool shown = false;
void OnGUI () {
if (car.transform.position.y>=43 && car.transform.position.y<=44)
{
shown = true;
}
else if (shown)
{
StartCoroutine(DisapearBoxAfter(3.0f));
}
if(shown)
{
GUI.Box(new Rect((Screen.width/2)-200,0,400,30) , "King of the hill");
}
}
IEnumerator DisapearBoxAfter(float waitTime) {
// suspend execution for waitTime seconds
yield return new WaitForSeconds(waitTime);
shown = false;
}
void Update () {
OnGUI ();
}
bool shown = false;
void OnGUI () {
if (car.transform.position.y>=43 && car.transform.position.y<=44)
{
shown = true;
}
else if (shown)
{
StartCoroutine(DisapearBoxAfter(3.0));
}
if(shown) {
GUI.Box(new Rect((Screen.width/2)-200,0,400,30) , "King of the hill");
}
}
IEnumerator DisapearBoxAfter(float waitTime) {
// suspend execution for waitTime seconds
return yield WaitForSeconds (waitTime);
shown = false;
}
void Update () {
OnGUI ();
}
function Start ()
{
ShowBox ();
}
function ShowBox ()
{
// show label
show = true;
// cancel invoking method if already set to call after 3 seconds
CancelInvoke("HideBox");
// will call HideBox () after 3 sec
Invoke ("HideBox", 3.0F);
}
function HideBox ()
{
// dont show label
show = false;
}
function Update ()
{
if (car.transform.position.y>=43 && car.transform.position.y<=44)
{
ShowBox ();
}
}
function OnGUI ()
{
if(shown)
{
GUI.Box(new Rect((Screen.width/2)-200,0,400,30) , "King of the hill");
}
}

Categories

Resources