Skip to main content
GameDev.net gamedev.net
🔒 Locked

foreach list always uses last value

Started by jadendecar May 27, 2013 at 12:48 AM 12 replies 2.5k views
Original Post
jadendecar
jadendecar

So, I'm using a foreach to update all the Button objects I place on the screen at once. They are all placed in a list and are executed as so:


foreach(Button button in Buttons)
    button.update(activeMouse);

the method checks if the button is being clicked and if so changes it's text. For some reason, when I click on any button, it always changes the text of the last Button object in the list.

tharealjohn
tharealjohn

Try this:


foreach(Button button in Buttons)
{
    Button b = button; // add this to "copy" the current button
    b.update(activeMouse);
}
jmillerdev.com Follow me @jmillerdev
Dave Hunt
Dave Hunt

Show the code that adds the buttons to the list. I suspect that you aren't allocating a new instance for each button, but are reusing a single button instance.

@tharealjohn - that code would make no difference at all.

jadendecar
jadendecar

@tharealjohn I had already tried that as well as a regular for loop to no avail.

@Dave Hunt

Edit: Notcied the Button constructor was missing the arguments.

This is how I add a button (inside of a method);


Button button = new Button(this, rectangle, title);
Buttons.Add(button);
Dave Hunt
Dave Hunt

I think we'll need to see the constructor and the update method for your Button class.

jadendecar
jadendecar

The Button constructor:


        public Button(Object obj, Rectangle relativeRectangle, string title)
            : base()
        {
            Rectangle = obj.Rectangle;
            RelativeRectangle = relativeRectangle;
            Visible = true;
            Title = title;
        }

and the update method:


        public void Update(Object obj, Mouse activeMouse)
        {
            Rectangle = obj.Rectangle;
            base.Update(activeMouse);
        }
Dave Hunt
Dave Hunt

Deeper and deeper...

The code that actually uses the mouse information and updates the button's text appears to be somewhere in a base class. That's the code we need to see.

Also, the code you show for calling Button.Update doesn't match the signature of the Button.Update method. Your Button.Update method takes an Object and a Mouse, but your calling function only shows passing a Mouse...

jadendecar
jadendecar

Fixed the update call in the foreach (no change). The base update code is as follows:


public void Update(Mouse activeMouse)
        {
            bool intersect = activeMouse.Rectangle.Intersects(Rectangle);

            if (intersect || (ActiveMouse != null && (LeftState != ObjectClickedState.Normal || RightState != ObjectClickedState.Normal)))
            {
                ActiveMouse = activeMouse;
                ActiveMouse.ClickedObject = this;
                if (intersect)
                    OnHover();
                if (ActiveMouse.LeftPress && (LeftState == ObjectClickedState.Normal || LeftState == ObjectClickedState.Released))
                {
                    LeftState = ObjectClickedState.Clicked;
                    OnLeftClick();
                }
                else if (ActiveMouse.LeftPress && LeftState == ObjectClickedState.Clicked)
                    OnLeftPress();
                else if (ActiveMouse.LeftRelease && LeftState == ObjectClickedState.Clicked)
                {
                    LeftState = ObjectClickedState.Released;
                    OnLeftRelease();
                }
                else if (!ActiveMouse.LeftPress && LeftState == ObjectClickedState.Released)
                {
                    LeftState = ObjectClickedState.Normal;
                    OnLeftNormal();
                }

                if (ActiveMouse.RightPress && (RightState == ObjectClickedState.Normal || RightState == ObjectClickedState.Released))
                {
                    RightState = ObjectClickedState.Clicked;
                    OnRightClick();
                }
                else if (ActiveMouse.RightPress && RightState == ObjectClickedState.Clicked)
                    OnRightPress();
                else if (ActiveMouse.RightRelease && RightState == ObjectClickedState.Clicked)
                {
                    RightState = ObjectClickedState.Released;
                    OnRightRelease();
                }
                else if (!ActiveMouse.RightPress && RightState == ObjectClickedState.Released)
                {
                    RightState = ObjectClickedState.Normal;
                    OnRightNormal();
                }
            }
            else
            {
                if (ActiveMouse != null)
                {
                    ActiveMouse.ClickedObject = null;
                    ActiveMouse = null;
                    OnLeave();
                }
            }
        }
Dave Hunt
Dave Hunt

Is Mouse a struct or a class? If it's a class, then all the changes you make to ActiveMouse are actually changing the values in activeMouse that gets passed on to the Update methods for all the rest of the buttons. That might explain why subsequent buttons think they've been clicked.

jadendecar
jadendecar

It's a class. Is there any way to fix that while keeping the mouse object the same for each button?

Dave Hunt
Dave Hunt

Not really. Unless your Button class really needs everything in the Mouse class, I would suggest just extracting the values you need and storing them individually in the Button.

tharealjohn
tharealjohn

I was thinking it could be a Closure problem. Perhaps it's not. Sorry for the mislead.

jmillerdev.com Follow me @jmillerdev
tharealjohn
tharealjohn


@tharealjohn - that code would make no difference at all.

I was thinking it could have been a Closure issue. Perhaps its not, sorry for the misleading information.

jmillerdev.com Follow me @jmillerdev
jadendecar
jadendecar

@Dave Hunt: You have been tremendously helpful, thank you so much. Sorry to ask one more thing, but is there any chance you could show me an example of that? I tried to do so on my own but I got nowhere.

@tharealjohn: No problem man, thanks for the help regardless =)

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.