public virtual IControlToken TakeControl(int priority = 1, [System.Runtime.CompilerServices.CallerMemberName] string name = "")
{
lock (this)
{
var ownerCandidate = new ControlledDevice(
name,
priority,
populate => BuildDefaultData(populate),
cToken =>
{
IData restoreData;
IControlToken nextOwner;
lock (this)
{
this.owners.Remove(cToken);
nextOwner = this.owners.LastOrDefault();
if (nextOwner != null)
restoreData = nextOwner.GetDataForDevice(this);
else
restoreData = GetOwnerlessData();
restoreData = restoreData.Copy();
this.currentOwner = nextOwner;
Executor.Current.SetControlToken(this, nextOwner);
}
SetData(nextOwner, restoreData.Select(x => Tuple.Create(x.Key, x.Value)).ToArray());
});
// Insert new owner
lock (this)
{
int pos = -1;
for (int i = 0; i < this.owners.Count; i++)
{
if (this.owners[i].Priority < priority)
continue;
pos = i;
break;
}
if (pos == -1)
this.owners.Add(ownerCandidate);
else
this.owners.Insert(pos, ownerCandidate);
}
// Grab the owner with the highest priority (doesn't have to be the candidate)
var newOwner = this.owners.Last();
this.currentOwner = newOwner;
Executor.Current.SetControlToken(this, newOwner);
return ownerCandidate;
}
}