コード例 #1
0
ファイル: config.c プロジェクト: apprisi/foundation_lib
static real _config_string_to_real( const char* str )
{
	unsigned int length = string_length( str );
	unsigned int first_nonnumeric;
	unsigned int dot_position;
	if( length < 2 )
		return string_to_real( str );

	first_nonnumeric = string_find_first_not_of( str, "0123456789.", 0 );
	if( ( first_nonnumeric == ( length - 1 ) ) && ( ( str[ first_nonnumeric ] == 'm' ) || ( str[ first_nonnumeric ] == 'M' ) ) )
	{
		dot_position = string_find( str, '.', 0 );
		if( dot_position != STRING_NPOS )
		{
			if( string_find( str, '.', dot_position + 1 ) != STRING_NPOS )
				return string_to_real( str ); //More than one dot
		}
		return string_to_real( str ) * ( REAL_C( 1024.0 ) * REAL_C( 1024.0 ) );
	}
	if( ( first_nonnumeric == ( length - 1 ) ) && ( ( str[ first_nonnumeric ] == 'k' ) || ( str[ first_nonnumeric ] == 'K' ) ) )
	{
		dot_position = string_find( str, '.', 0 );
		if( dot_position != STRING_NPOS )
		{
			if( string_find( str, '.', dot_position + 1 ) != STRING_NPOS )
				return string_to_real( str ); //More than one dot
		}
		return string_to_real( str ) * REAL_C( 1024.0 );
	}

	return string_to_real( str );
}
コード例 #2
0
ファイル: config.c プロジェクト: apprisi/foundation_lib
void config_set_bool( hash_t section, hash_t key, bool value )
{
	config_key_t* key_val = config_key( section, key, true );
	if( !FOUNDATION_VALIDATE( key_val ) ) return;
	key_val->bval = value;
	key_val->ival = ( value ? 1 : 0 );
	key_val->rval = ( value ? REAL_C( 1.0 ) : REAL_C( 0.0 ) );
	if( key_val->expanded != key_val->sval )
		string_deallocate( key_val->expanded );
	if( ( key_val->type != CONFIGVALUE_STRING_CONST ) && ( key_val->type != CONFIGVALUE_STRING_CONST_VAR ) )
		string_deallocate( key_val->sval );
	key_val->sval = 0;
	key_val->expanded = 0;
	key_val->type = CONFIGVALUE_BOOL;
}
コード例 #3
0
ファイル: main.c プロジェクト: DanielTillett/foundation_lib
DECLARE_TEST( math, exponentials )
{
	EXPECT_REALONE( math_exp( REAL_ZERO ) );
	EXPECT_REALEQ( math_exp( REAL_ONE ), REAL_E );

	EXPECT_REALONE( math_pow( REAL_ONE, REAL_ONE ) );
	EXPECT_REALONE( math_pow( REAL_ONE, REAL_ZERO ) );
	EXPECT_REALONE( math_pow( REAL_THREE, REAL_ZERO ) );
	EXPECT_REALEQ( math_pow( REAL_SQRT2, REAL_TWO ), REAL_TWO );

	EXPECT_REALEQ( math_logn( REAL_TWO ), REAL_LOGN2 );
	EXPECT_REALEQ( math_logn( REAL_C( 10.0 ) ), REAL_LOGN10 );

	EXPECT_REALONE( math_log2( REAL_TWO ) );
	EXPECT_REALEQ( math_log2( REAL_TWO * REAL_TWO ), REAL_TWO );
	EXPECT_REALEQ( math_log2( REAL_TWO * REAL_TWO * REAL_TWO * REAL_TWO ), REAL_C( 4.0 ) );

	return 0;
}
コード例 #4
0
ファイル: config.c プロジェクト: apprisi/foundation_lib
static NOINLINE void _expand_string_val( hash_t section, config_key_t* key )
{
	bool is_true;
	FOUNDATION_ASSERT( key->sval );
	if( key->expanded != key->sval )
		string_deallocate( key->expanded );
	key->expanded = _expand_string( section, key->sval );

	is_true = string_equal( key->expanded, "true" );
	key->bval = ( string_equal( key->expanded, "false" ) || string_equal( key->expanded, "0" ) || !string_length( key->expanded ) ) ? false : true;
	key->ival = is_true ? 1 : _config_string_to_int( key->expanded );
	key->rval = is_true ? REAL_C(1.0) : _config_string_to_real( key->expanded );
}
コード例 #5
0
ファイル: client.c プロジェクト: harish-agr/network_lib
static void
blast_client_report_progress(blast_client_t* client, bool force) {
	int progress = (int)((real)((float64_t)((client->seq - array_size(client->pending)) *
	                                        PACKET_CHUNK_SIZE) / (float64_t)client->readers[client->current]->size) * REAL_C(100.0));
	if (force || (progress > (client->last_progress_percent + 5)) ||
	        (time_elapsed(client->last_progress) > 1.0f)) {
		if (client->packets_sent > 0) {
			real resend_rate = (real)((float64_t)client->packets_resent / (float64_t)client->packets_sent) *
			                   REAL_C(100.0);
			log_infof(HASH_BLAST, STRING_CONST("Progress: %.*s %d%% (resend rate %.2" PRIreal "%% %lld/%lld))"),
			          STRING_FORMAT(client->readers[client->current]->name), progress, resend_rate,
			          client->packets_resent,
			          client->packets_sent);
		}
		client->last_progress = time_current();
		client->last_progress_percent = progress;
	}
}
コード例 #6
0
ファイル: config.c プロジェクト: apprisi/foundation_lib
void config_set_string( hash_t section, hash_t key, const char* value )
{
	config_key_t* key_val = config_key( section, key, true );
	if( !FOUNDATION_VALIDATE( key_val ) ) return;
	if( key_val->expanded != key_val->sval )
		string_deallocate( key_val->expanded );
	if( ( key_val->type != CONFIGVALUE_STRING_CONST ) && ( key_val->type != CONFIGVALUE_STRING_CONST_VAR ) )
		string_deallocate( key_val->sval );

	key_val->sval = string_clone( value );
	key_val->expanded = 0;
	key_val->type = ( ( string_find_string( key_val->sval, "$(", 0 ) != STRING_NPOS ) ? CONFIGVALUE_STRING_VAR : CONFIGVALUE_STRING );

	if( key_val->type == CONFIGVALUE_STRING )
	{
		bool is_true = string_equal( key_val->sval, "true" );
		key_val->bval = ( string_equal( key_val->sval, "false" ) || string_equal( key_val->sval, "0" ) || !string_length( key_val->sval ) ) ? false : true;
		key_val->ival = is_true ? 1 : _config_string_to_int( key_val->sval );
		key_val->rval = is_true ? REAL_C(1.0) : _config_string_to_real( key_val->sval );
	}
}
コード例 #7
0
ファイル: config.c プロジェクト: apprisi/foundation_lib
void config_set_string_constant( hash_t section, hash_t key, const char* value )
{
	config_key_t* key_val = config_key( section, key, true );
	if( !FOUNDATION_VALIDATE( key_val ) ) return;
	if( !FOUNDATION_VALIDATE( value ) ) return;
	if( key_val->expanded != key_val->sval )
		string_deallocate( key_val->expanded );
	if( ( key_val->type != CONFIGVALUE_STRING_CONST ) && ( key_val->type != CONFIGVALUE_STRING_CONST_VAR ) )
		string_deallocate( key_val->sval );
	//key_val->sval = (char*)value;
	memcpy( &key_val->sval, &value, sizeof( char* ) ); //Yeah yeah, we're storing a const pointer in a non-const var
	key_val->expanded = 0;
	key_val->type = ( ( string_find_string( key_val->sval, "$(", 0 ) != STRING_NPOS ) ? CONFIGVALUE_STRING_CONST_VAR : CONFIGVALUE_STRING_CONST );

	if( key_val->type == CONFIGVALUE_STRING_CONST )
	{
		bool is_true = string_equal( key_val->sval, "true" );
		key_val->bval = ( string_equal( key_val->sval, "false" ) || string_equal( key_val->sval, "0" ) || !string_length( key_val->sval ) ) ? false : true;
		key_val->ival = is_true ? 1 : _config_string_to_int( key_val->sval );
		key_val->rval = is_true ? REAL_C(1.0) : _config_string_to_real( key_val->sval );
	}
}
コード例 #8
0
ファイル: main.c プロジェクト: DanielTillett/foundation_lib
DECLARE_TEST( math, comparison )
{
	real testreal, refreal;
	real onereal = REAL_ONE;
	real zeroreal = REAL_ZERO;

	testreal = REAL_C( 42.42 );
	refreal = testreal;

	EXPECT_EQ( testreal, refreal );
	EXPECT_TRUE( math_realeq( testreal, refreal, 0 ) );
	EXPECT_TRUE( math_realeqns( testreal, refreal, 0 ) );
	EXPECT_FALSE( math_realzero( testreal ) );
	EXPECT_FALSE( math_realone( testreal ) );
	EXPECT_FALSE( math_realisnan( testreal ) );
	EXPECT_FALSE( math_realisinf( testreal ) );
	EXPECT_FALSE( math_realisuninitialized( testreal ) );
	EXPECT_TRUE( math_realisfinite( testreal ) );

	testreal = math_realdec( testreal, 10 );
	EXPECT_NE( testreal, refreal );
	EXPECT_FALSE( math_realeq( testreal, refreal, 0 ) );
	EXPECT_FALSE( math_realeqns( testreal, refreal, 0 ) );
	EXPECT_TRUE( math_realeq( testreal, refreal, 10 ) );
	EXPECT_TRUE( math_realeqns( testreal, refreal, 10 ) );
	EXPECT_FALSE( math_realzero( testreal ) );
	EXPECT_FALSE( math_realone( testreal ) );
	EXPECT_FALSE( math_realisnan( testreal ) );
	EXPECT_FALSE( math_realisinf( testreal ) );
	EXPECT_FALSE( math_realisuninitialized( testreal ) );
	EXPECT_TRUE( math_realisfinite( testreal ) );

	testreal = math_realdec( testreal, 10 );
	EXPECT_NE( testreal, refreal );
	EXPECT_FALSE( math_realeq( testreal, refreal, 0 ) );
	EXPECT_FALSE( math_realeqns( testreal, refreal, 0 ) );
	EXPECT_FALSE( math_realeq( testreal, refreal, 10 ) );
	EXPECT_FALSE( math_realeqns( testreal, refreal, 10 ) );
	EXPECT_FALSE( math_realzero( testreal ) );
	EXPECT_FALSE( math_realone( testreal ) );
	EXPECT_FALSE( math_realisnan( testreal ) );
	EXPECT_FALSE( math_realisinf( testreal ) );
	EXPECT_FALSE( math_realisuninitialized( testreal ) );
	EXPECT_TRUE( math_realisfinite( testreal ) );

	testreal = math_realinc( testreal, 20 );
	EXPECT_EQ( testreal, refreal );
	EXPECT_TRUE( math_realeq( testreal, refreal, 0 ) );
	EXPECT_TRUE( math_realeqns( testreal, refreal, 0 ) );
	EXPECT_FALSE( math_realzero( testreal ) );
	EXPECT_FALSE( math_realone( testreal ) );
	EXPECT_FALSE( math_realisnan( testreal ) );
	EXPECT_FALSE( math_realisinf( testreal ) );
	EXPECT_FALSE( math_realisuninitialized( testreal ) );
	EXPECT_TRUE( math_realisfinite( testreal ) );

	testreal = math_realinc( testreal, 10 );
	EXPECT_NE( testreal, refreal );
	EXPECT_FALSE( math_realeq( testreal, refreal, 0 ) );
	EXPECT_FALSE( math_realeqns( testreal, refreal, 0 ) );
	EXPECT_TRUE( math_realeq( testreal, refreal, 10 ) );
	EXPECT_TRUE( math_realeqns( testreal, refreal, 10 ) );
	EXPECT_FALSE( math_realzero( testreal ) );
	EXPECT_FALSE( math_realone( testreal ) );
	EXPECT_FALSE( math_realisnan( testreal ) );
	EXPECT_FALSE( math_realisinf( testreal ) );
	EXPECT_FALSE( math_realisuninitialized( testreal ) );
	EXPECT_TRUE( math_realisfinite( testreal ) );

	testreal = math_realinc( testreal, 10 );
	EXPECT_NE( testreal, refreal );
	EXPECT_FALSE( math_realeq( testreal, refreal, 0 ) );
	EXPECT_FALSE( math_realeqns( testreal, refreal, 0 ) );
	EXPECT_FALSE( math_realeq( testreal, refreal, 10 ) );
	EXPECT_FALSE( math_realeqns( testreal, refreal, 10 ) );
	EXPECT_FALSE( math_realzero( testreal ) );
	EXPECT_FALSE( math_realone( testreal ) );
	EXPECT_FALSE( math_realisnan( testreal ) );
	EXPECT_FALSE( math_realisinf( testreal ) );
	EXPECT_FALSE( math_realisuninitialized( testreal ) );
	EXPECT_TRUE( math_realisfinite( testreal ) );

	EXPECT_TRUE( math_realisnan( math_sqrt( REAL_C( -1.0 ) ) ) );
	EXPECT_TRUE( math_realisinf( onereal / zeroreal ) );
	EXPECT_TRUE( math_realisnan( -math_sqrt( REAL_C( -1.0 ) ) ) );
	EXPECT_TRUE( math_realisinf( -onereal / zeroreal ) );

	testreal = REAL_ONE / REAL_MAX;
	EXPECT_REALNE( testreal, REAL_ZERO );
	EXPECT_TRUE( math_realisdenormalized( testreal ) );
	EXPECT_REALZERO( math_realundenormalize( testreal ) );
	EXPECT_FALSE( math_realisdenormalized( REAL_ONE ) );
	EXPECT_REALONE( math_realundenormalize( REAL_ONE ) );

	return 0;
}
コード例 #9
0
ファイル: main.c プロジェクト: DanielTillett/foundation_lib
DECLARE_TEST( math, utility )
{
	int i;
	
	EXPECT_REALONE( math_abs( REAL_ONE ) );
	EXPECT_REALONE( math_abs( -REAL_ONE ) );
	EXPECT_REALZERO( math_abs( REAL_ZERO ) );
	EXPECT_REALEQ( math_abs( REAL_MAX ), REAL_MAX );
	EXPECT_REALEQ( math_abs( -REAL_MAX ), REAL_MAX );
	EXPECT_REALEQ( math_abs( REAL_MIN ), REAL_MIN );
	EXPECT_REALEQ( math_abs( -REAL_MIN ), REAL_MIN );

	EXPECT_REALZERO( math_mod( REAL_ZERO, REAL_ONE ) );
	EXPECT_REALZERO( math_mod( REAL_ONE, REAL_ONE ) );
	EXPECT_REALZERO( math_mod( REAL_MAX, REAL_ONE ) );
	EXPECT_REALONE( math_mod( REAL_THREE, REAL_TWO ) );
	EXPECT_REALONE( -math_mod( -REAL_THREE, -REAL_TWO ) );

	EXPECT_EQ( math_floor( REAL_ZERO ), 0 );
	EXPECT_EQ( math_floor( REAL_C( 0.999 ) ), 0 );
	EXPECT_EQ( math_floor( REAL_C( -0.1 ) ), -1 );
	EXPECT_EQ( math_floor( REAL_C( 42.5 ) ), 42 );

	EXPECT_EQ( math_ceil( REAL_ZERO ), 0 );
	EXPECT_EQ( math_ceil( REAL_C( 0.999 ) ), 1 );
	EXPECT_EQ( math_ceil( REAL_C( -0.1 ) ), 0 );
	EXPECT_EQ( math_ceil( REAL_C( 42.5 ) ), 43 );
	EXPECT_EQ( math_ceil( REAL_C( 42.45 ) ), 43 );

	EXPECT_EQ( math_floor64( REAL_ZERO ), 0 );
	EXPECT_EQ( math_floor64( REAL_C( 0.999 ) ), 0 );
	EXPECT_EQ( math_floor64( REAL_C( -0.1 ) ), -1 );
	EXPECT_EQ( math_floor64( REAL_C( 42.5 ) ), 42 );

	EXPECT_EQ( math_ceil64( REAL_ZERO ), 0 );
	EXPECT_EQ( math_ceil64( REAL_C( 0.999 ) ), 1 );
	EXPECT_EQ( math_ceil64( REAL_C( -0.1 ) ), 0 );
	EXPECT_EQ( math_ceil64( REAL_C( 42.5 ) ), 43 );
	EXPECT_EQ( math_ceil64( REAL_C( 42.45 ) ), 43 );
	
	EXPECT_EQ( math_round( REAL_ZERO ), 0 );
	EXPECT_EQ( math_round( REAL_C( 0.999 ) ), 1 );
	EXPECT_EQ( math_round( REAL_C( -0.1 ) ), 0 );
	EXPECT_EQ( math_round( REAL_C( 42.5 ) ), 43 );
	EXPECT_EQ( math_round( REAL_C( 42.45 ) ), 42 );
	
	EXPECT_EQ( math_trunc( REAL_ZERO ), 0 );
	EXPECT_EQ( math_trunc( REAL_C( 0.999 ) ), 0 );
	EXPECT_EQ( math_trunc( REAL_C( -0.1 ) ), 0 );
	EXPECT_EQ( math_trunc( REAL_C( 42.5 ) ), 42 );

	EXPECT_EQ( math_align_poweroftwo( 2 ), 2 );
	EXPECT_EQ( math_align_poweroftwo( 3 ), 4 );
	EXPECT_EQ( math_align_poweroftwo( 4 ), 4 );
	EXPECT_EQ( math_align_poweroftwo( 33 ), 64 );
	EXPECT_EQ( math_align_poweroftwo( 134217729 ), 268435456 );

	for( i = 1; i < 31; ++i )
	{
		EXPECT_TRUE( math_is_poweroftwo( math_align_poweroftwo( ( 2 << i ) - 1 ) ) );
		EXPECT_TRUE( math_is_poweroftwo( math_align_poweroftwo( ( 2 << i )     ) ) );
		EXPECT_TRUE( math_is_poweroftwo( math_align_poweroftwo( ( 2 << i ) + 1 ) ) );

		EXPECT_FALSE( math_is_poweroftwo( ( 2 << i ) - 1 ) );
		EXPECT_TRUE( math_is_poweroftwo( ( 2 << i )     ) );
		EXPECT_FALSE( math_is_poweroftwo( ( 2 << i ) + 1 ) );
	}

	EXPECT_EQ( math_align_up( 1, 1 ), 1 );
	EXPECT_EQ( math_align_up( 1, 2 ), 2 );
	EXPECT_EQ( math_align_up( 17, 2 ), 18 );
	EXPECT_EQ( math_align_up( 43, 42 ), 84 );

	EXPECT_REALZERO( math_smoothstep( REAL_ZERO ) );
	EXPECT_REALONE( math_smoothstep( REAL_ONE ) );
	EXPECT_REALEQ( math_smoothstep( REAL_HALF ), REAL_HALF );
	
	EXPECT_REALZERO( math_smootherstep( REAL_ZERO ) );
	EXPECT_REALONE( math_smootherstep( REAL_ONE ) );
	EXPECT_REALEQ( math_smootherstep( REAL_HALF ), REAL_HALF );

	EXPECT_REALZERO( math_lerp( REAL_ZERO, REAL_ZERO, REAL_ONE ) );
	EXPECT_REALZERO( math_lerp( REAL_ONE, REAL_ONE, REAL_ZERO ) );
	EXPECT_REALONE( math_lerp( REAL_ONE, REAL_ZERO, REAL_ONE ) );
	EXPECT_REALONE( math_lerp( REAL_ZERO, REAL_ONE, REAL_ZERO ) );
	EXPECT_REALEQ( math_lerp( REAL_HALF, REAL_ZERO, REAL_ONE ), REAL_HALF );
	EXPECT_REALEQ( math_lerp( REAL_HALF, REAL_ZERO, REAL_ONE ), REAL_HALF );

	EXPECT_REALZERO( math_unlerp( REAL_ZERO, REAL_ZERO, REAL_ONE ) );
	EXPECT_REALZERO( math_unlerp( REAL_ONE, REAL_ONE, REAL_ZERO ) );
	EXPECT_REALONE( math_unlerp( REAL_ONE, REAL_ZERO, REAL_ONE ) );
	EXPECT_REALONE( math_unlerp( REAL_ZERO, REAL_ONE, REAL_ZERO ) );
	EXPECT_REALEQ( math_unlerp( REAL_HALF, REAL_ZERO, REAL_ONE ), REAL_HALF );
	EXPECT_REALEQ( math_unlerp( REAL_HALF, REAL_ZERO, REAL_ONE ), REAL_HALF );

	EXPECT_REALONE( math_linear_remap( REAL_C( 150.0 ), REAL_C( 100.0 ), REAL_C( 200.0 ), REAL_ZERO, REAL_TWO ) );

	EXPECT_REALZERO( math_clamp( -REAL_ONE, REAL_ZERO, REAL_ONE ) );
	EXPECT_REALZERO( math_clamp( REAL_ZERO, REAL_ZERO, REAL_ONE ) );
	EXPECT_REALEQ( math_clamp( REAL_HALF, REAL_ZERO, REAL_ONE ), REAL_HALF );
	EXPECT_REALONE( math_clamp( REAL_ONE, REAL_ZERO, REAL_ONE ) );
	EXPECT_REALONE( math_clamp( REAL_TWO, REAL_ZERO, REAL_ONE ) );

	return 0;
}
コード例 #10
0
ファイル: time.c プロジェクト: DanielTillett/foundation_lib
int _time_initialize( void )
{
#if FOUNDATION_PLATFORM_WINDOWS
	tick_t unused;
	if( !QueryPerformanceFrequency( (LARGE_INTEGER*)&_time_freq ) ||
	    !QueryPerformanceCounter( (LARGE_INTEGER*)&unused ) )
		return -1;
#elif FOUNDATION_PLATFORM_APPLE
	if( mach_timebase_info( &_time_info ) )
		return -1;
	_time_freq = 1000000000ULL;
#elif FOUNDATION_PLATFORM_POSIX
	struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
	if( clock_gettime( CLOCK_MONOTONIC, &ts ) )
		return -1;
	_time_freq = 1000000000ULL;
#endif

	_time_oofreq  = REAL_C(1.0) / (double)_time_freq;
	_time_startup = time_current();

	return 0;
}


void _time_shutdown( void )
{
}


tick_t time_current( void )
{
#if FOUNDATION_PLATFORM_WINDOWS

	tick_t curclock;
	QueryPerformanceCounter( (LARGE_INTEGER*)&curclock );
	return curclock;

#elif FOUNDATION_PLATFORM_APPLE

	tick_t curclock = 0;
	absolutetime_to_nanoseconds( mach_absolute_time(), &curclock );
	return curclock;

#elif FOUNDATION_PLATFORM_POSIX

	struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
	clock_gettime( CLOCK_MONOTONIC, &ts );
	return ( (uint64_t)ts.tv_sec * 1000000000ULL ) + ts.tv_nsec;

#endif
}


tick_t time_startup( void )
{
	return _time_startup;
}


tick_t time_ticks_per_second( void )
{
	return _time_freq;
}


tick_t time_diff( const tick_t from, const tick_t to )
{
	if( to <= from )
		return 0;
	return ( to - from );
}
	

deltatime_t time_elapsed( const tick_t t )
{
	return (deltatime_t)( (double)time_elapsed_ticks( t ) * _time_oofreq );
}


tick_t time_elapsed_ticks( const tick_t t )
{
	tick_t dt = 0;

#if FOUNDATION_PLATFORM_WINDOWS

	tick_t curclock = t;
	QueryPerformanceCounter( (LARGE_INTEGER*)&curclock );
	dt = curclock - t;

#elif FOUNDATION_PLATFORM_APPLE

	tick_t curclock = t;
	absolutetime_to_nanoseconds( mach_absolute_time(), &curclock );
	dt = curclock - t;

#elif FOUNDATION_PLATFORM_POSIX

	tick_t curclock;
	struct timespec ts = { .tv_sec = 0, .tv_nsec = 0 };
	clock_gettime( CLOCK_MONOTONIC, &ts );

	curclock = ( (tick_t)ts.tv_sec * 1000000000ULL ) + ts.tv_nsec;
	dt = curclock - t;

#endif

	return dt;
}


deltatime_t time_ticks_to_seconds( const tick_t dt )
{
	return (deltatime_t)( (double)dt * _time_oofreq );
}


#if FOUNDATION_PLATFORM_WINDOWS
struct __timeb64 {
	__time64_t time;
	unsigned short millitm;
	short timezone;
	short dstflag;
	};
コード例 #11
0
ファイル: main.c プロジェクト: apprisi/foundation_lib
DECLARE_TEST( event, delay )
{
	event_stream_t* stream;
	event_block_t* block;
	event_t* event;
	tick_t delivery = 0;
	tick_t limit = 0;
	tick_t current = 0;
	uint8_t expect_event = FOUNDATIONEVENT_TERMINATE;

	stream = event_stream_allocate( 0 );

	current = time_current();
	delivery = current + ( time_ticks_per_second() / 2 );
	limit = current + ( time_ticks_per_second() * 20 );

	event_post( stream, expect_event, 0, 0, 0, current + ( time_ticks_per_second() / 2 ) );
	event_post( stream, expect_event + 1, 0, 0, 0, current + (tick_t)((real)time_ticks_per_second() * REAL_C( 0.51 )) );

	do
	{
		block = event_stream_process( stream );
		event = event_next( block, 0 );

		current = time_current();

		if( ( expect_event == FOUNDATIONEVENT_TERMINATE ) && event )
		{
			EXPECT_EQ( event->id, expect_event );
			EXPECT_EQ( event->size, sizeof( event_t ) + 8 ); //8 bytes for additional timestamp payload
			EXPECT_EQ( event->object, 0 );
			EXPECT_EQ( event->flags, EVENTFLAG_DELAY );
			EXPECT_EQ( event_payload_size( event ), 0 );

			EXPECT_GE( current, delivery );
			EXPECT_GE( current, delivery );

			++expect_event;

			event = event_next( block, event );
		}

		if( ( expect_event == FOUNDATIONEVENT_TERMINATE + 1 ) && event )
		{
			EXPECT_EQ( event->id, expect_event );
			EXPECT_EQ( event->size, sizeof( event_t ) + 8 ); //8 bytes for additional timestamp payload
			EXPECT_EQ( event->object, 0 );
			EXPECT_EQ( event->flags, EVENTFLAG_DELAY );
			EXPECT_EQ( event_payload_size( event ), 0 );

			EXPECT_GE( current, delivery );
			EXPECT_GE( current, delivery );

			++expect_event;

			event = event_next( block, event );

			EXPECT_EQ( event, 0 );
		}

		if( ( expect_event > FOUNDATIONEVENT_TERMINATE + 1 ) && !event )
			break;

		thread_yield();

	} while( time_current() < limit );

	EXPECT_EQ( event, 0 );
	EXPECT_EQ( expect_event, FOUNDATIONEVENT_TERMINATE + 2 );
	EXPECT_LE( time_current(), limit );

	//Reverse order of delivery
	current = time_current();
	delivery = current + ( time_ticks_per_second() / 2 );
	limit = current + ( time_ticks_per_second() * 20 );

	event_post( stream, expect_event, 0, 0, 0, current + ( time_ticks_per_second() / 2 ) );
	event_post( stream, expect_event + 1, 0, 0, 0, current + (tick_t)((real)time_ticks_per_second() * REAL_C( 0.41 )) );

	do
	{
		block = event_stream_process( stream );
		event = event_next( block, 0 );

		current = time_current();

		if( ( expect_event == FOUNDATIONEVENT_TERMINATE ) && event )
		{
			EXPECT_EQ( event->id, expect_event );
			EXPECT_EQ( event->size, sizeof( event_t ) + 8 ); //8 bytes for additional timestamp payload
			EXPECT_EQ( event->object, 0 );
			EXPECT_EQ( event->flags, EVENTFLAG_DELAY );
			EXPECT_EQ( event_payload_size( event ), 0 );

			EXPECT_GE( current, delivery );
			EXPECT_GE( current, delivery );

			++expect_event;

			event = event_next( block, event );
		}

		if( ( expect_event == FOUNDATIONEVENT_TERMINATE + 1 ) && event )
		{
			EXPECT_EQ( event->id, expect_event );
			EXPECT_EQ( event->size, sizeof( event_t ) + 8 ); //8 bytes for additional timestamp payload
			EXPECT_EQ( event->object, 0 );
			EXPECT_EQ( event->flags, EVENTFLAG_DELAY );
			EXPECT_EQ( event_payload_size( event ), 0 );

			EXPECT_GE( current, delivery );
			EXPECT_GE( current, delivery );

			++expect_event;

			event = event_next( block, event );

			EXPECT_EQ( event, 0 );
		}

		if( ( expect_event > FOUNDATIONEVENT_TERMINATE + 1 ) && !event )
			break;

		thread_yield();

	} while( time_current() < limit );

	EXPECT_EQ( event, 0 );
	EXPECT_EQ( expect_event, FOUNDATIONEVENT_TERMINATE + 2 );
	EXPECT_LE( time_current(), limit );

	event_stream_deallocate( stream );
	
	return 0;
}