Last active
December 19, 2015 03:12
-
-
Save Marenz/34f7e85b2f938c840783 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SyncedArray ( T ) | |
{ | |
import std.typecons; | |
/*************************************************************************** | |
Data | |
***************************************************************************/ | |
private Nullable!(T)[] data; | |
/*************************************************************************** | |
Flag set to true when a potentially suspending function is iterating | |
***************************************************************************/ | |
private bool iteration_in_progress; | |
/*************************************************************************** | |
Ctor | |
***************************************************************************/ | |
this ( ) | |
{ | |
assumeSafeAppend(this.data); | |
} | |
/*************************************************************************** | |
Provide a fiber safe iterator that checks the length before each element | |
***************************************************************************/ | |
int opApply ( int delegate ( ref T element ) dg ) | |
{ | |
int result = 0; | |
this.iteration_in_progress= true; | |
scope(exit) this.iteration_in_progress = false; | |
for ( size_t i = 0; i < this.data.length; i++ ) | |
{ | |
if (this.data[i].isNull) | |
continue; | |
result = dg(this.data[i]); | |
if (result) | |
break; | |
} | |
return result; | |
} | |
/*************************************************************************** | |
Provide a fiber safe iterator that checks the length before each element | |
***************************************************************************/ | |
int opApply ( int delegate ( size_t i, ref Player p ) dg ) | |
{ | |
int result = 0; | |
this.iteration_in_progress= true; | |
scope(exit) this.iteration_in_progress = false; | |
for ( size_t i = 0; i < this.data.length; i++ ) | |
{ | |
if (this.data[i].isNull) | |
continue; | |
result = dg(i, this.data[i]); | |
if (result) | |
break; | |
} | |
return result; | |
} | |
/*************************************************************************** | |
Finds and removes the given element from the array | |
Params: | |
element = element to remove | |
***************************************************************************/ | |
void remove ( inout T element ) | |
{ | |
if (this.iteration_in_progress) | |
{ | |
// If an iteration is ongoing, replace element with dummy | |
foreach ( ref it_el ; this.data ) | |
if ( element is it_el ) | |
{ | |
it_el.nullify(); | |
break; | |
} | |
} | |
else | |
// Else, remove the player and all dummies | |
this.data = this.data.remove!( | |
a=>a is element || a.isNull )(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment