C
Christ Kennedy
Guest
I have a MouseWheel Event and a semaphore. The semaphore is there to ensure that the work that event does is not interrupted by another MouseWheelEvent before that work is completed.
The app I'm working on is a SpriteEditor . Specifically dealing with the order in which a sprite's limbs are drawn(or not drawn). When the MouseWheel is used gingerly(slowly and carefully) the moving up and down of selected limbs works correctly. However, when the MouseWheel is turned more aggressively, the semaphore that is there to prevent this from being a problem, is completely ignored and problems ensue. see Video demonstration
public System.Threading.Semaphore semChangeList = new System.Threading.Semaphore(1, 1);
private void Event_MouseWheel(object sender, MouseEventArgs e)
{
semChangeList.WaitOne();
if (CanMoveSelection && lstButtonsSelected.Count > 0)
{
CanMoveSelection = false;
int intIndexSelected_High = -1;
int intIndexSelected_Low = cMap.lstElements.Count;
List<classMultiButtonPic.classButton> lstButtons = new List<classButton>();
for (int intCounter = 0; intCounter < cMap.lstElements.Count; intCounter++)
{
classMultiButtonPic.classButton cBtn = (classMultiButtonPic.classButton)cMap.lstElements[intCounter].obj;
lstButtons.Add(cBtn);
if (lstButtonsSelected.Contains(cBtn))
{
if (intCounter < intIndexSelected_Low)
intIndexSelected_Low = intCounter;
if (intCounter > intIndexSelected_High)
intIndexSelected_High = intCounter;
}
}
intIndexSelected_Low--;
intIndexSelected_High++;
ClearButtons();
if (e.Delta > 0)
{ // move Up
// move buttons from front of list that are before the lowest selected button index
for (int intCounter = 0; intCounter < intIndexSelected_Low; intCounter++)
{
classMultiButtonPic.classButton cBtn = lstButtons[0];
lstButtons.Remove(cBtn);
Button_Add(ref cBtn);
}
// move buttons that are selected
for (int intCounter = 0; intCounter < lstButtonsSelected.Count; intCounter++)
{
classMultiButtonPic.classButton cBtn = lstButtonsSelected[intCounter];
lstButtons.Remove(cBtn);
Button_Add(ref cBtn);
}
// move remaining buttons
while (lstButtons.Count > 0)
{
classMultiButtonPic.classButton cBtn = lstButtons[0];
lstButtons.Remove(cBtn);
Button_Add(ref cBtn);
}
}
else
{
List<classMultiButtonPic.classButton> lstTemp = new List<classButton>();
// remove buttons from the end that are after the highest selected button
for (int intCounter = lstButtons.Count - 1; intCounter > intIndexSelected_High; intCounter--)
{
classMultiButtonPic.classButton cBtn = lstButtons[lstButtons.Count - 1];
lstButtons.Remove(cBtn);
lstTemp.Insert(0, cBtn);
}
// move buttons that are selected
for (int intCounter = 0; intCounter < lstButtonsSelected.Count; intCounter++)
{
classMultiButtonPic.classButton cBtn = lstButtonsSelected[intCounter];
lstButtons.Remove(cBtn);
lstTemp.Insert(0, cBtn);
}
// move remaining buttons
while (lstButtons.Count > 0)
{
classMultiButtonPic.classButton cBtn = lstButtons[lstButtons.Count - 1];
lstButtons.Remove(cBtn);
lstTemp.Insert(0, cBtn);
}
Button_Add_Array(ref lstTemp);
}
placeButtons();
CanMoveSelection = true;
}
semChangeList.Release();
}
You can see that there is a semaphore at the top of this MouseWheelEventHandler telling the program-flow to wait there until that same semaphore is released at the end of the MouseWheelEventHandler. The only difference between this working and not working is the speed at which the mouse is being turned and the e.Delta value tested to determine whether to move limbs up/down the list only has its sign tested (not its magnitude). So ... WTF?
Christ
my code is perfect until i don't find a bug
Continue reading...
The app I'm working on is a SpriteEditor . Specifically dealing with the order in which a sprite's limbs are drawn(or not drawn). When the MouseWheel is used gingerly(slowly and carefully) the moving up and down of selected limbs works correctly. However, when the MouseWheel is turned more aggressively, the semaphore that is there to prevent this from being a problem, is completely ignored and problems ensue. see Video demonstration
public System.Threading.Semaphore semChangeList = new System.Threading.Semaphore(1, 1);
private void Event_MouseWheel(object sender, MouseEventArgs e)
{
semChangeList.WaitOne();
if (CanMoveSelection && lstButtonsSelected.Count > 0)
{
CanMoveSelection = false;
int intIndexSelected_High = -1;
int intIndexSelected_Low = cMap.lstElements.Count;
List<classMultiButtonPic.classButton> lstButtons = new List<classButton>();
for (int intCounter = 0; intCounter < cMap.lstElements.Count; intCounter++)
{
classMultiButtonPic.classButton cBtn = (classMultiButtonPic.classButton)cMap.lstElements[intCounter].obj;
lstButtons.Add(cBtn);
if (lstButtonsSelected.Contains(cBtn))
{
if (intCounter < intIndexSelected_Low)
intIndexSelected_Low = intCounter;
if (intCounter > intIndexSelected_High)
intIndexSelected_High = intCounter;
}
}
intIndexSelected_Low--;
intIndexSelected_High++;
ClearButtons();
if (e.Delta > 0)
{ // move Up
// move buttons from front of list that are before the lowest selected button index
for (int intCounter = 0; intCounter < intIndexSelected_Low; intCounter++)
{
classMultiButtonPic.classButton cBtn = lstButtons[0];
lstButtons.Remove(cBtn);
Button_Add(ref cBtn);
}
// move buttons that are selected
for (int intCounter = 0; intCounter < lstButtonsSelected.Count; intCounter++)
{
classMultiButtonPic.classButton cBtn = lstButtonsSelected[intCounter];
lstButtons.Remove(cBtn);
Button_Add(ref cBtn);
}
// move remaining buttons
while (lstButtons.Count > 0)
{
classMultiButtonPic.classButton cBtn = lstButtons[0];
lstButtons.Remove(cBtn);
Button_Add(ref cBtn);
}
}
else
{
List<classMultiButtonPic.classButton> lstTemp = new List<classButton>();
// remove buttons from the end that are after the highest selected button
for (int intCounter = lstButtons.Count - 1; intCounter > intIndexSelected_High; intCounter--)
{
classMultiButtonPic.classButton cBtn = lstButtons[lstButtons.Count - 1];
lstButtons.Remove(cBtn);
lstTemp.Insert(0, cBtn);
}
// move buttons that are selected
for (int intCounter = 0; intCounter < lstButtonsSelected.Count; intCounter++)
{
classMultiButtonPic.classButton cBtn = lstButtonsSelected[intCounter];
lstButtons.Remove(cBtn);
lstTemp.Insert(0, cBtn);
}
// move remaining buttons
while (lstButtons.Count > 0)
{
classMultiButtonPic.classButton cBtn = lstButtons[lstButtons.Count - 1];
lstButtons.Remove(cBtn);
lstTemp.Insert(0, cBtn);
}
Button_Add_Array(ref lstTemp);
}
placeButtons();
CanMoveSelection = true;
}
semChangeList.Release();
}
You can see that there is a semaphore at the top of this MouseWheelEventHandler telling the program-flow to wait there until that same semaphore is released at the end of the MouseWheelEventHandler. The only difference between this working and not working is the speed at which the mouse is being turned and the e.Delta value tested to determine whether to move limbs up/down the list only has its sign tested (not its magnitude). So ... WTF?
Christ
my code is perfect until i don't find a bug
Continue reading...