etqw-sdk/source/game/guis/UITimeline.cpp

455 lines
11 KiB
C++

// Copyright (C) 2007 Id Software, Inc.
//
#include "../precompiled.h"
#pragma hdrstop
#if defined( _DEBUG ) && !defined( ID_REDIRECT_NEWDELETE )
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#include "UserInterfaceLocal.h"
#include "UserInterfaceTypes.h"
#include "UITimeline.h"
#include "UIWindow.h"
const char sdUITimelineEvent_Identifier[] = "sdUITimelineEvent";
const char sdUITemplateFunctionInstance_Identifier[] = "sdUITemplateFunctionInstance";
/*
============
sdUITimelineManager::sdUITimelineManager
============
*/
sdUITimelineManager::sdUITimelineManager( sdUserInterfaceLocal& ui_, sdUserInterfaceScope& enclosingScope_, sdUIScript& script_ ) :
enclosingScope( enclosingScope_ ),
ui( ui_ ),
script( script_ ) {
}
/*
============
sdUITimelineManager::CreateTimelines
============
*/
bool sdUITimelineManager::CreateTimelines( const sdDeclGUITimelineHolder& timelineInfo, const sdDeclGUI* guiDecl ) {
for( int timelineIndex = 0; timelineIndex < timelineInfo.GetNumTimelines(); timelineIndex++ ) {
const char* timelineName = timelineInfo.GetTimelineName( timelineIndex );
sdUITimeline* newTimeline = new sdUITimeline( timelineName, this );
timelines[ timelineName ] = newTimeline;
}
return true;
}
/*
============
sdUITimelineManager::CreateEvents
============
*/
bool sdUITimelineManager::CreateEvents( const sdDeclGUITimelineHolder& timelineInfo, const sdDeclGUI* guiDecl, idTokenCache& tokenCache ) {
if( timelines.Num() != timelineInfo.GetNumTimelines() ) {
assert( 0 );
return false;
}
for( int timelineIndex = 0; timelineIndex < timelines.Num(); timelineIndex++ ) {
sdUITimeline* newTimeline = timelines.FindIndex( timelineIndex )->second;
newTimeline->CreateEvents( *timelineInfo.GetTimeline( timelineIndex ), guiDecl, tokenCache );
}
return true;
}
/*
============
sdUITimelineManager::CreateProperties
============
*/
bool sdUITimelineManager::CreateProperties( const sdDeclGUITimelineHolder& timelineInfo, const sdDeclGUI* guiDecl, const idTokenCache& tokenCache ) {
if( timelines.Num() != timelineInfo.GetNumTimelines() ) {
assert( 0 );
return false;
}
for( int timelineIndex = 0; timelineIndex < timelines.Num(); timelineIndex++ ) {
sdUITimeline* newTimeline = timelines.FindIndex( timelineIndex )->second;
newTimeline->CreateProperties( *timelineInfo.GetTimeline( timelineIndex ), guiDecl, tokenCache );
}
return true;
}
/*
============
sdUITimelineManager::GetSubScope
============
*/
sdUserInterfaceScope* sdUITimelineManager::GetSubScope( const char* name ) {
timelineHash_t::Iterator iter = timelines.Find( name );
if( iter != timelines.End() ) {
return iter->second;
}
return NULL;
}
/*
============
sdUITimelineManager::Clear
============
*/
void sdUITimelineManager::Clear() {
timelines.DeleteValues();
timelines.Clear();
resetScopes.SetNum( 0, false );
timelineEvents.DeleteContents( true );
}
/*
================
sdUITimelineManager::PostTimelineEvent
================
*/
void sdUITimelineManager::PostTimelineEvent( int offset, int index, sdUITimeline* scope ) {
sdUITimelineEvent* event = new sdUITimelineEvent;
event->index = index;
event->timeline = scope;
event->time = ui.GetCurrentTime() + offset;
timelineEvents.Append( event );
}
/*
================
sdUITimelineManager::ClearTimelineEvents
================
*/
void sdUITimelineManager::ClearTimelineEvents( sdUITimeline* scope ) {
int i;
for ( i = timelineEvents.Num() - 1; i >= 0; i-- ) {
if ( timelineEvents[ i ]->timeline == scope ) {
delete timelineEvents[ i ];
timelineEvents.RemoveIndex( i );
}
}
}
/*
============
sdUITimelineManager::ResetAllTimelines
============
*/
void sdUITimelineManager::ResetAllTimelines() {
for( int i = 0; i < timelines.Num(); i++ ) {
sdUITimeline* timeline = timelines.FindIndex( i )->second;
timeline->Reset();
}
}
/*
============
sdUITimelineManager::ClearAllTimelines
============
*/
void sdUITimelineManager::ClearAllTimelines() {
for( int i = 0; i < timelines.Num(); i++ ) {
sdUITimeline* timeline = timelines.FindIndex( i )->second;
timeline->Clear();
}
}
/*
============
sdUITimelineManager::PushAllTimelines
============
*/
void sdUITimelineManager::PushAllTimelines() {
for( int i = 0; i < timelines.Num(); i++ ) {
sdUITimeline* timeline = timelines.FindIndex( i )->second;
timeline->PushEvents();
}
}
/*
============
sdUITimelineManager::OnSnapshotHitch
============
*/
void sdUITimelineManager::OnSnapshotHitch( int delta ) {
for ( int i = 0; i < timelineEvents.Num(); i++ ) {
sdUITimelineEvent* event = timelineEvents[ i ];
event->time -= delta;
}
}
/*
============
sdUITimelineManager::Run
============
*/
void sdUITimelineManager::Run( int time ) {
for ( int i = 0; i < timelineEvents.Num(); ) {
sdUITimelineEvent* event = timelineEvents[ i ];
if ( time >= event->time ) {
event->timeline->RunTimeEvent( event->index );
if ( timelineEvents.Remove( event ) ) {
delete event;
}
i = 0;
} else {
i++;
}
}
for ( int i = 0; i < resetScopes.Num(); i++ ) {
resetScopes[ i ]->Reset();
}
resetScopes.SetNum( 0, false );
}
const char sdUITemplateFunctionInstance_IdentifierTimeline[] = "sdUITimelineFunction";
idHashMap< sdUITemplateFunction< sdUITimeline >* > sdUITimeline::timelineFunctions;
/*
============
sdUITimeline::sdUITimeline
============
*/
sdUITimeline::sdUITimeline( const char* name_, sdUITimelineManager* manager_ ) :
name( name_ ),
needsReset( false ),
resetTime( 0 ),
active( 1.0f ),
manager( manager_ ) {
events.SetNumEvents( TE_NUM_EVENTS );
properties.RegisterProperty( "active", active );
properties.RegisterProperty( "name", name );
name.SetReadOnly( true );
UI_ADD_FLOAT_CALLBACK( active, sdUITimeline, OnActiveChanged );
}
/*
============
sdUITimeline::RunTimeEvent
============
*/
bool sdUITimeline::RunTimeEvent( int index ) {
return script.RunEventHandle( events.GetEvent( sdUIEventInfo( TE_ONTIME, index ) ), this );
}
/*
============
sdUITimeline::GetProperty
============
*/
sdProperties::sdProperty* sdUITimeline::GetProperty( const char* name ) {
using namespace sdProperties;
sdProperty* prop = properties.GetProperty( name, sdProperties::PT_INVALID, false );
if( !prop ) {
return manager->GetScope().GetProperty( name );
}
return prop;
}
/*
============
sdUITimeline::GetProperty
============
*/
sdProperties::sdProperty* sdUITimeline::GetProperty( const char* name, sdProperties::ePropertyType type ) {
using namespace sdProperties;
sdProperty* prop = properties.GetProperty( name, type, false );
if( !prop ) {
return manager->GetScope().GetProperty( name, type );
}
return prop;
}
/*
============
sdUITimeline::FindPropertyName
============
*/
const char* sdUITimeline::FindPropertyName( sdProperties::sdProperty* property, sdUserInterfaceScope*& scope ) {
scope = this;
return properties.NameForProperty( property );
}
/*
============
sdUITimeline::PushEvents
============
*/
void sdUITimeline::PushEvents() {
Clear();
if( active == 0.0f ) {
return;
}
for( int i = 0; i < timeline.Num(); i++ ) {
if( timeline[ i ] >= resetTime ) {
manager->PostTimelineEvent( timeline[ i ] - resetTime, i, this );
}
}
}
/*
============
sdUITimeline::Clear
============
*/
void sdUITimeline::Clear() {
manager->ClearTimelineEvents( this );
}
/*
============
sdUITimeline::GetFunction
============
*/
sdUIFunctionInstance* sdUITimeline::GetFunction( const char* name ) {
const sdUITemplateFunction< sdUITimeline >* function = sdUITimeline::FindFunction( name );
if( !function ) {
return manager->GetScope().GetFunction( name );
}
return new sdUITemplateFunctionInstance< sdUITimeline, sdUITemplateFunctionInstance_IdentifierTimeline >( this, function );
}
/*
============
sdUITimeline::FindFunction
============
*/
const sdUITemplateFunction< sdUITimeline >* sdUITimeline::FindFunction( const char* name ) {
sdUITemplateFunction< sdUITimeline >** ptr;
return timelineFunctions.Get( name, &ptr ) ? *ptr : NULL;
}
/*
============
sdUITimeline::InitFunctions
============
*/
void sdUITimeline::InitFunctions() {
timelineFunctions.Set( "resetTime", new sdUITemplateFunction< sdUITimeline >( 'v', "f", &sdUITimeline::Script_ResetTime ) );
}
/*
============
sdUITimeline::OnActiveChanged
============
*/
void sdUITimeline::OnActiveChanged( const float oldValue, const float newValue ) {
if( newValue == 0.0f ) {
Clear();
} else {
DeferredReset();
}
}
/*
============
sdUITimeline::Reset
============
*/
void sdUITimeline::Reset() {
PushEvents();
}
/*
============
sdUITimeline::DeferredReset
============
*/
void sdUITimeline::DeferredReset() {
manager->DeferredResetTimeline( this );
}
/*
============
sdUITimeline::CreateEvents
============
*/
bool sdUITimeline::CreateEvents( const sdDeclGUITimeline& timelineInfo, const sdDeclGUI* guiDecl, idTokenCache& tokenCache ) {
const idList< sdDeclGUITimeEvent* > events = timelineInfo.GetEvents();
const idList< sdDeclGUIProperty* > properties = timelineInfo.GetProperties();
timeline.AssureSize( events.Num() );
idList<unsigned short> constructorTokens;
bool hasValues = sdDeclGUI::CreateConstructor( properties, constructorTokens, tokenCache );
if ( hasValues ) {
idLexer parser( sdDeclGUI::LEXER_FLAGS );
parser.LoadTokenStream( constructorTokens, tokenCache, "sdUITimeline::CreateEvents" );
sdUIEventInfo constructionEvent( TE_CONSTRUCTOR, 0 );
script.ParseEvent( &parser, constructionEvent, this );
script.RunEventHandle( GetEvent( constructionEvent ), this );
}
for( int eventIndex = 0; eventIndex < events.Num(); eventIndex++ ) {
const sdDeclGUITimeEvent* eventInfo = events[ eventIndex ];
sdUserInterfaceLocal::PushTrace( eventInfo->GetTextInfo() );
idLexer parser( sdDeclGUI::LEXER_FLAGS );
parser.LoadTokenStream( eventInfo->GetTokenIndices(), tokenCache, va( "onTime '%i'", eventInfo->GetStartTime() ) );
//parser.LoadMemory( eventInfo->GetText(), eventInfo->GetTextLength(), va( "onTime '%i'", eventInfo->GetStartTime()) );
script.ParseEvent( &parser, sdUIEventInfo( TE_ONTIME, eventIndex ), this );
timeline[ eventIndex ] = eventInfo->GetStartTime();
sdUserInterfaceLocal::PopTrace();
}
return true;
}
/*
============
sdUITimeline::CreateProperties
============
*/
bool sdUITimeline::CreateProperties( const sdDeclGUITimeline& declProperties, const sdDeclGUI* guiDecl, const idTokenCache& tokenCache ) {
sdUIWindow::SetupProperties( properties, declProperties.GetProperties(), manager->GetUI(), tokenCache );
return true;
}
/*
============
sdUITimeline::Script_ResetTime
============
*/
void sdUITimeline::Script_ResetTime( sdUIFunctionStack& stack ) {
stack.Pop( resetTime );
DeferredReset();
}
/*
============
sdUITimeline::OnSnapshotHitch
============
*/
void sdUITimeline::OnSnapshotHitch( int delta ) {
for( int i = 0; i < timeline.Num(); i++ ) {
timeline[ i ] -= delta;
}
}