Skip to content

Instantly share code, notes, and snippets.

@Marenz
Last active December 19, 2015 03:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Marenz/34f7e85b2f938c840783 to your computer and use it in GitHub Desktop.
Save Marenz/34f7e85b2f938c840783 to your computer and use it in GitHub Desktop.
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