233 lines
6.1 KiB
C++
233 lines
6.1 KiB
C++
![]() |
/////////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// FILE : PageProvider.cpp
|
||
|
// PURPOSE : Class that wraps a collection of pages and runs book-keeping logic
|
||
|
// for them.
|
||
|
//
|
||
|
// AUTHOR : james.strain
|
||
|
// STARTED : October 2020
|
||
|
//
|
||
|
/////////////////////////////////////////////////////////////////////////////////
|
||
|
#include "PageProvider.h"
|
||
|
#if UI_PAGE_DECK_ENABLED
|
||
|
#include "PageProvider_parser.h"
|
||
|
|
||
|
// framework
|
||
|
#include "fwutil/xmacro.h"
|
||
|
|
||
|
// game
|
||
|
#include "frontend/ui_channel.h"
|
||
|
#include "frontend/page_deck/PageBase.h"
|
||
|
|
||
|
CPageProvider::CPageProvider()
|
||
|
: m_transitioner()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
void CPageProvider::PostLoadInitialize( IPageViewHost& viewHost )
|
||
|
{
|
||
|
auto validationFunc = [this, &viewHost]( uiPageId const id, CPageBase& currentPage )
|
||
|
{
|
||
|
InitializationLambdaHelper( id, currentPage, viewHost );
|
||
|
};
|
||
|
|
||
|
ForEachPage( validationFunc );
|
||
|
}
|
||
|
|
||
|
void CPageProvider::Shutdown()
|
||
|
{
|
||
|
Dismiss();
|
||
|
UnloadInternal();
|
||
|
}
|
||
|
|
||
|
void CPageProvider::LaunchToPage( uiEntrypointId const entrypointId )
|
||
|
{
|
||
|
if( uiVerifyf( !IsRunning(), "Attempting to launch to '" HASHFMT "' but we are already running", HASHOUT(entrypointId) ) )
|
||
|
{
|
||
|
uiPageLink const& startingPageLink = GetLinkFromEntrypoint( entrypointId );
|
||
|
if( uiVerifyf( startingPageLink.IsValid(), "Unable to find requested starting page '" HASHFMT "'", HASHOUT(entrypointId) ) )
|
||
|
{
|
||
|
GoToPage( startingPageLink );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool CPageProvider::IsRunning() const
|
||
|
{
|
||
|
return m_transitioner.HasStackedPages() || m_transitioner.HasTransition();
|
||
|
}
|
||
|
|
||
|
void CPageProvider::Update( float const deltaMs )
|
||
|
{
|
||
|
// We update in order, active but un-focused...
|
||
|
Update_Active( deltaMs );
|
||
|
|
||
|
// ...then focused
|
||
|
Update_Focused( deltaMs );
|
||
|
|
||
|
// Step the transition, if we have one
|
||
|
bool stepTransitions = m_transitioner.HasTransition();
|
||
|
while( stepTransitions )
|
||
|
{
|
||
|
bool const c_wasInstantTransition = m_transitioner.StepTransition( deltaMs );
|
||
|
stepTransitions = c_wasInstantTransition && m_transitioner.HasTransition();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CPageProvider::Dismiss()
|
||
|
{
|
||
|
if( IsRunning() )
|
||
|
{
|
||
|
m_transitioner.Shutdown();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CPageProvider::RequestTransition( uiPageLink const& pageLink )
|
||
|
{
|
||
|
if( IsRunning() )
|
||
|
{
|
||
|
GoToPage( pageLink );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool CPageProvider::CanBackOut() const
|
||
|
{
|
||
|
bool const c_result = m_transitioner.CanBackOut();
|
||
|
return c_result;
|
||
|
}
|
||
|
|
||
|
void CPageProvider::UnloadInternal()
|
||
|
{
|
||
|
m_transitioner.Shutdown();
|
||
|
|
||
|
auto shutdownFunc = []( uiPageId const UNUSED_PARAM(id), CPageBase& currentPage )
|
||
|
{
|
||
|
currentPage.Shutdown();
|
||
|
delete ¤tPage;
|
||
|
};
|
||
|
|
||
|
ForEachPage( shutdownFunc );
|
||
|
m_pageMap.Reset();
|
||
|
m_entrypointMap.Reset();
|
||
|
}
|
||
|
|
||
|
void CPageProvider::Update_Active( float const deltaMs )
|
||
|
{
|
||
|
auto updateFunc = [deltaMs]( uiPageId const UNUSED_PARAM(id), CPageBase& currentPage )
|
||
|
{
|
||
|
currentPage.Update( deltaMs );
|
||
|
};
|
||
|
|
||
|
m_transitioner.ForEachStackedPage_ExceptFocused( updateFunc );
|
||
|
}
|
||
|
|
||
|
void CPageProvider::Update_Focused( float const deltaMs )
|
||
|
{
|
||
|
CPageBase * const focusedPage = GetFocusedPage();
|
||
|
if( focusedPage )
|
||
|
{
|
||
|
focusedPage->Update( deltaMs );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CPageProvider::ForEachPage( uiPageConfig::PageVisitorLambda action )
|
||
|
{
|
||
|
int const c_count = m_pageMap.GetNumSlots();
|
||
|
for( int index = 0; index < c_count; ++index )
|
||
|
{
|
||
|
PageMapEntry * entry = m_pageMap.GetEntry( index );
|
||
|
while( entry )
|
||
|
{
|
||
|
uiAssertf( entry->key.IsNotNull(), "Page entry with null key found" );
|
||
|
|
||
|
if( uiVerifyf( entry->data, "Null page type for entry '" HASHFMT "', your code and data is likely out of sync", HASHOUT(entry->key) ) )
|
||
|
{
|
||
|
action( entry->key, *(entry->data) );
|
||
|
}
|
||
|
|
||
|
entry = entry->next;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void CPageProvider::ForEachPage( uiPageConfig::PageVisitorConstLambda action ) const
|
||
|
{
|
||
|
int const c_count = m_pageMap.GetNumSlots();
|
||
|
for( int index = 0; index < c_count; ++index )
|
||
|
{
|
||
|
PageMapEntry const * entry = m_pageMap.GetEntry( index );
|
||
|
while( entry )
|
||
|
{
|
||
|
uiAssertf( entry->key.IsNotNull(), "Page entry with null key found" );
|
||
|
|
||
|
if( uiVerifyf( entry->data, "Null page type for entry '" HASHFMT "', your code and data is likely out of sync", HASHOUT(entry->key) ) )
|
||
|
{
|
||
|
action( entry->key, *(entry->data) );
|
||
|
}
|
||
|
|
||
|
entry = entry->next;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
CPageBase const * CPageProvider::GetFocusedPage() const
|
||
|
{
|
||
|
CPageBase const * const c_result = m_transitioner.GetFocusedPage();
|
||
|
return c_result;
|
||
|
}
|
||
|
|
||
|
bool CPageProvider::IsActive( CPageBase const& targetPage ) const
|
||
|
{
|
||
|
bool const c_active = m_transitioner.IsStacked( targetPage );
|
||
|
return c_active;
|
||
|
}
|
||
|
|
||
|
bool CPageProvider::IsFocused( CPageBase const& targetPage ) const
|
||
|
{
|
||
|
CPageBase const * const c_focused = GetFocusedPage();
|
||
|
return &targetPage == c_focused;
|
||
|
}
|
||
|
|
||
|
void CPageProvider::InitializationLambdaHelper( uiPageId const pageId, CPageBase& currentPage, IPageViewHost& viewHost ) const
|
||
|
{
|
||
|
// Initialize the page
|
||
|
currentPage.Initialize( pageId, viewHost );
|
||
|
}
|
||
|
|
||
|
uiPageLink const& CPageProvider::GetLinkFromEntrypoint( uiEntrypointId const entrypointId ) const
|
||
|
{
|
||
|
// Default to the default
|
||
|
uiPageLink const * result = &m_defaultEntry;
|
||
|
|
||
|
if( entrypointId.IsNotNull() )
|
||
|
{
|
||
|
// If we have an entry point, utilize that
|
||
|
uiPageLink const * const targetEntryPoint = m_entrypointMap.Access( entrypointId );
|
||
|
if( uiVerifyf( targetEntryPoint != nullptr, "Requested entrypoint '" HASHFMT "' but it doesn't exist", HASHOUT( entrypointId ) ) )
|
||
|
{
|
||
|
result = targetEntryPoint;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return *result;
|
||
|
}
|
||
|
|
||
|
void CPageProvider::GoToPage( uiPageLink const& targetPageLink )
|
||
|
{
|
||
|
if ( targetPageLink.IsValid() )
|
||
|
{
|
||
|
uiPageInfo const& c_targetPage = targetPageLink.GetTarget();
|
||
|
|
||
|
if (c_targetPage.GetId() == uiPageConfig::GetControlCharacter_UpOneLevel())
|
||
|
{
|
||
|
m_transitioner.TransitionToParent();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
m_transitioner.PushTransition(targetPageLink, m_pageMap);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif // UI_PAGE_DECK_ENABLED
|