Reputation: 732
UI Elements can subscribe events like press, hold or release. Therefore, I created an object variable to store those information
private Dictionary<TouchListenerType, List<Action<int, float, Vector2>>> touchData = new Dictionary<TouchListenerType, List<Action<int, float, Vector2>>>();
Every update cycle I iterate over every provided input and delegate it to the subscribers.
try
{
for (int currentTouchIndex = touchCollections.Count - 1; currentTouchIndex >= 0; currentTouchIndex--)
{
Vector2 position = MapInput(touchCollections[currentTouchIndex].Position);
if (touchCollections[currentTouchIndex].State == TouchLocationState.Moved &&
touchData[TouchListenerType.Move].Count > 0)
touchData[TouchListenerType.Move].ForEach(d => d.Invoke(touchCollections[currentTouchIndex].Id, touchCollections[currentTouchIndex].Pressure, position));
else if (touchCollections[currentTouchIndex].State == TouchLocationState.Pressed &&
touchData[TouchListenerType.Press].Count > 0)
touchData[TouchListenerType.Press].ForEach(d => d.Invoke(touchCollections[currentTouchIndex].Id, touchCollections[currentTouchIndex].Pressure, position));
else if (touchCollections[currentTouchIndex].State == TouchLocationState.Released &&
touchData[TouchListenerType.Release].Count > 0)
touchData[TouchListenerType.Release].ForEach(d => d.Invoke(touchCollections[currentTouchIndex].Id, touchCollections[currentTouchIndex].Pressure, position));
}
} catch { } //Enumeration could have been changed
If a subscriber decides to unsubscribe or to add another subscription based on the provided input, the exception System.InvalidOperationException will be thrown, because the event subscriber count has been changed. Till now I just put a try-catch around the block. But I would like to avoid the original problem.
Based on the fact that every subscriber is able to unsubscribe/subscribe in the delegate, I can't work with semaphores. Also I would like to avoid to create a copy of the event every update cycle, since this application is running on mobile devices. How am I able to solve this problem?
Upvotes: 1
Views: 111
Reputation: 158
Perhaps a Concurrent Dictionary is sufficient?
You may also need to implement Custom Event Accessors.
Edit:
The error is generated by the List<T>.ForEach
statement, where the collection is changed during iteration. A for
loop should be used to allow for this.
Upvotes: 1