summaryrefslogtreecommitdiff
path: root/engine/toolframework.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engine/toolframework.cpp')
-rw-r--r--engine/toolframework.cpp1253
1 files changed, 1253 insertions, 0 deletions
diff --git a/engine/toolframework.cpp b/engine/toolframework.cpp
new file mode 100644
index 0000000..7817422
--- /dev/null
+++ b/engine/toolframework.cpp
@@ -0,0 +1,1253 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose: Engine system for loading and managing tools
+//
+//=============================================================================
+
+#include "quakedef.h"
+#include "tier0/icommandline.h"
+#include "toolframework/itooldictionary.h"
+#include "toolframework/itoolsystem.h"
+#include "toolframework/itoolframework.h"
+#include "toolframework/iclientenginetools.h"
+#include "toolframework/iserverenginetools.h"
+#include "tier1/KeyValues.h"
+#include "tier1/utlvector.h"
+#include "tier1/tier1.h"
+#include "filesystem_engine.h"
+
+class IToolSystem;
+extern CreateInterfaceFn g_AppSystemFactory;
+typedef bool (*FnQuitHandler)( void *pvUserData );
+void EngineTool_InstallQuitHandler( void *pvUserData, FnQuitHandler func );
+
+//-----------------------------------------------------------------------------
+// Purpose: -tools loads framework
+//-----------------------------------------------------------------------------
+class CToolFrameworkInternal : public IToolFrameworkInternal
+{
+public:
+ // Here's where the app systems get to learn about each other
+ virtual bool Connect( CreateInterfaceFn factory );
+ virtual void Disconnect();
+
+ // Here's where systems can access other interfaces implemented by this object
+ // Returns NULL if it doesn't implement the requested interface
+ virtual void *QueryInterface( const char *pInterfaceName );
+
+ // Init, shutdown
+ virtual InitReturnVal_t Init();
+ virtual void Shutdown();
+
+ virtual bool CanQuit();
+
+public:
+ // Level init, shutdown
+ virtual void ClientLevelInitPreEntityAllTools();
+ // entities are created / spawned / precached here
+ virtual void ClientLevelInitPostEntityAllTools();
+
+ virtual void ClientLevelShutdownPreEntityAllTools();
+ // Entities are deleted / released here...
+ virtual void ClientLevelShutdownPostEntityAllTools();
+
+ virtual void ClientPreRenderAllTools();
+ virtual void ClientPostRenderAllTools();
+
+ virtual bool IsThirdPersonCamera();
+
+ virtual bool IsToolRecording();
+
+ // Level init, shutdown
+ virtual void ServerLevelInitPreEntityAllTools();
+ // entities are created / spawned / precached here
+ virtual void ServerLevelInitPostEntityAllTools();
+
+ virtual void ServerLevelShutdownPreEntityAllTools();
+ // Entities are deleted / released here...
+ virtual void ServerLevelShutdownPostEntityAllTools();
+ // end of level shutdown
+
+ // Called each frame before entities think
+ virtual void ServerFrameUpdatePreEntityThinkAllTools();
+ // called after entities think
+ virtual void ServerFrameUpdatePostEntityThinkAllTools();
+ virtual void ServerPreClientUpdateAllTools();
+ const char* GetEntityData( const char *pActualEntityData );
+ virtual void ServerPreSetupVisibilityAllTools();
+
+ virtual bool PostInit();
+
+ virtual bool ServerInit( CreateInterfaceFn serverFactory );
+ virtual bool ClientInit( CreateInterfaceFn clientFactory );
+
+ virtual void ServerShutdown();
+ virtual void ClientShutdown();
+
+ virtual void Think( bool finalTick );
+
+ virtual void PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg );
+
+ virtual void AdjustEngineViewport( int& x, int& y, int& width, int& height );
+ virtual bool SetupEngineView( Vector &origin, QAngle &angles, float &fov );
+ virtual bool SetupAudioState( AudioState_t &audioState );
+
+ virtual int GetToolCount();
+ virtual const char* GetToolName( int index );
+ virtual void SwitchToTool( int index );
+ virtual IToolSystem* SwitchToTool( const char* pToolName );
+
+ virtual bool IsTopmostTool( const IToolSystem *sys );
+ virtual const IToolSystem *GetToolSystem( int index ) const;
+ virtual IToolSystem *GetTopmostTool();
+
+ virtual void PostMessage( KeyValues *msg );
+
+ virtual bool GetSoundSpatialization( int iUserData, int guid, SpatializationInfo_t& info );
+
+ virtual void HostRunFrameBegin();
+ virtual void HostRunFrameEnd();
+
+ virtual void RenderFrameBegin();
+ virtual void RenderFrameEnd();
+
+ virtual void VGui_PreRenderAllTools( int paintMode );
+ virtual void VGui_PostRenderAllTools( int paintMode );
+
+ virtual void VGui_PreSimulateAllTools();
+ virtual void VGui_PostSimulateAllTools();
+
+ // Are we using tools?
+ virtual bool InToolMode();
+
+ // Should the game be allowed to render the world?
+ virtual bool ShouldGameRenderView();
+
+ virtual IMaterialProxy *LookupProxy( const char *proxyName );
+
+private:
+ void LoadTools();
+ void LoadToolsFromLibrary( const char *dllname );
+
+ void InvokeMethod( ToolSystemFunc_t f );
+ void InvokeMethodInt( ToolSystemFunc_Int_t f, int arg );
+
+ void ShutdownTools();
+
+ // Purpose: Shuts down all modules
+ void ShutdownModules();
+
+ // Purpose: Shuts down all tool dictionaries
+ void ShutdownToolDictionaries();
+
+ CUtlVector< IToolSystem * > m_ToolSystems;
+ CUtlVector< IToolDictionary * > m_Dictionaries;
+ CUtlVector< CSysModule * > m_Modules;
+ int m_nActiveToolIndex;
+ bool m_bInToolMode;
+};
+
+static CToolFrameworkInternal g_ToolFrameworkInternal;
+IToolFrameworkInternal *toolframework = &g_ToolFrameworkInternal;
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Used to invoke a method of all added Game systems in order
+// Input : f - function to execute
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::InvokeMethod( ToolSystemFunc_t f )
+{
+ int toolCount = m_ToolSystems.Count();
+ for ( int i = 0; i < toolCount; ++i )
+ {
+ IToolSystem *sys = m_ToolSystems[i];
+ (sys->*f)();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Used to invoke a method of all added Game systems in order
+// Input : f - function to execute
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::InvokeMethodInt( ToolSystemFunc_Int_t f, int arg )
+{
+ int toolCount = m_ToolSystems.Count();
+ for ( int i = 0; i < toolCount; ++i )
+ {
+ IToolSystem *sys = m_ToolSystems[i];
+ (sys->*f)( arg );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Here's where the app systems get to learn about each other
+// Input : factory -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CToolFrameworkInternal::Connect( CreateInterfaceFn factory )
+{
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::Disconnect()
+{
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Here's where systems can access other interfaces implemented by this object
+// Returns NULL if it doesn't implement the requested interface
+// Input : *pInterfaceName -
+//-----------------------------------------------------------------------------
+void *CToolFrameworkInternal::QueryInterface( const char *pInterfaceName )
+{
+ return NULL;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *pvUserData -
+// Output : static bool
+//-----------------------------------------------------------------------------
+static bool CToolFrameworkInternal_QuitHandler( void *pvUserData )
+{
+ CToolFrameworkInternal *tfm = reinterpret_cast< CToolFrameworkInternal * >( pvUserData );
+ if ( tfm )
+ {
+ return tfm->CanQuit();
+ }
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Init, shutdown
+// Input : -
+// Output : InitReturnVal_t
+//-----------------------------------------------------------------------------
+InitReturnVal_t CToolFrameworkInternal::Init()
+{
+ m_bInToolMode = false;
+ m_nActiveToolIndex = -1;
+
+// Disabled in REL for now
+#if 1
+#ifndef SWDS
+ EngineTool_InstallQuitHandler( this, CToolFrameworkInternal_QuitHandler );
+
+ // FIXME: Eventually this should be -edit
+ if ( CommandLine()->FindParm( "-tools" ) )
+ {
+ LoadTools();
+ }
+#endif
+#endif
+ return INIT_OK;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Called at end of Host_Init
+//-----------------------------------------------------------------------------
+bool CToolFrameworkInternal::PostInit()
+{
+ bool bRetVal = true;
+
+ int toolCount = m_ToolSystems.Count();
+ for ( int i = 0; i < toolCount; ++i )
+ {
+ IToolSystem *system = m_ToolSystems[ i ];
+
+ // FIXME: Should this really get access to a list if factories
+ bool success = system->Init( );
+ if ( !success )
+ {
+ bRetVal = false;
+ }
+ }
+
+ // Activate first tool if we didn't encounter an error
+ if ( bRetVal )
+ {
+ SwitchToTool( 0 );
+ }
+
+ return bRetVal;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::Shutdown()
+{
+ // Shut down all tools
+ ShutdownTools();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : finalTick -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::Think( bool finalTick )
+{
+ int toolCount = m_ToolSystems.Count();
+ for ( int i = 0; i < toolCount; ++i )
+ {
+ IToolSystem *system = m_ToolSystems[ i ];
+ system->Think( finalTick );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : serverFactory -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CToolFrameworkInternal::ServerInit( CreateInterfaceFn serverFactory )
+{
+ bool retval = true;
+
+ int toolCount = m_ToolSystems.Count();
+ for ( int i = 0; i < toolCount; ++i )
+ {
+ IToolSystem *system = m_ToolSystems[ i ];
+ // FIXME: Should this really get access to a list if factories
+ bool success = system->ServerInit( serverFactory );
+ if ( !success )
+ {
+ retval = false;
+ }
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : clientFactory -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CToolFrameworkInternal::ClientInit( CreateInterfaceFn clientFactory )
+{
+ bool retval = true;
+
+ int toolCount = m_ToolSystems.Count();
+ for ( int i = 0; i < toolCount; ++i )
+ {
+ IToolSystem *system = m_ToolSystems[ i ];
+ // FIXME: Should this really get access to a list if factories
+ bool success = system->ClientInit( clientFactory );
+ if ( !success )
+ {
+ retval = false;
+ }
+ }
+ return retval;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ServerShutdown()
+{
+ // Reverse order
+ int toolCount = m_ToolSystems.Count();
+ for ( int i = toolCount - 1; i >= 0; --i )
+ {
+ IToolSystem *system = m_ToolSystems[ i ];
+ system->ServerShutdown();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ClientShutdown()
+{
+ // Reverse order
+ int toolCount = m_ToolSystems.Count();
+ for ( int i = toolCount - 1; i >= 0; --i )
+ {
+ IToolSystem *system = m_ToolSystems[ i ];
+ system->ClientShutdown();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CToolFrameworkInternal::CanQuit()
+{
+ int toolCount = m_ToolSystems.Count();
+ for ( int i = 0; i < toolCount; ++i )
+ {
+ IToolSystem *system = m_ToolSystems[ i ];
+ bool canquit = system->CanQuit();
+ if ( !canquit )
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Shuts down all modules
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ShutdownModules()
+{
+ // Shutdown dictionaries
+ int i;
+ for ( i = m_Modules.Count(); --i >= 0; )
+ {
+ Sys_UnloadModule( m_Modules[i] );
+ }
+
+ m_Modules.RemoveAll();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Shuts down all tool dictionaries
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ShutdownToolDictionaries()
+{
+ // Shutdown dictionaries
+ int i;
+ for ( i = m_Dictionaries.Count(); --i >= 0; )
+ {
+ m_Dictionaries[i]->Shutdown();
+ }
+
+ for ( i = m_Dictionaries.Count(); --i >= 0; )
+ {
+ m_Dictionaries[i]->Disconnect();
+ }
+
+ m_Dictionaries.RemoveAll();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Shuts down all tools
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ShutdownTools()
+{
+ // Deactivate tool
+ SwitchToTool( -1 );
+
+ // Reverse order
+ int i;
+ int toolCount = m_ToolSystems.Count();
+ for ( i = toolCount - 1; i >= 0; --i )
+ {
+ IToolSystem *system = m_ToolSystems[ i ];
+ system->Shutdown();
+ }
+
+ m_ToolSystems.RemoveAll();
+
+ ShutdownToolDictionaries();
+ ShutdownModules();
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Adds tool from specified library
+// Input : *dllname -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::LoadToolsFromLibrary( const char *dllname )
+{
+ CSysModule *module = Sys_LoadModule( dllname );
+ if ( !module )
+ {
+ Warning( "CToolFrameworkInternal::LoadToolsFromLibrary: Unable to load '%s'\n", dllname );
+ return;
+ }
+
+ CreateInterfaceFn factory = Sys_GetFactory( module );
+ if ( !factory )
+ {
+ Sys_UnloadModule( module );
+ Warning( "CToolFrameworkInternal::LoadToolsFromLibrary: Dll '%s' has no factory\n", dllname );
+ return;
+ }
+
+ IToolDictionary *dictionary = ( IToolDictionary * )factory( VTOOLDICTIONARY_INTERFACE_VERSION, NULL );
+ if ( !dictionary )
+ {
+ Sys_UnloadModule( module );
+ Warning( "CToolFrameworkInternal::LoadToolsFromLibrary: Dll '%s' doesn't support '%s'\n", dllname, VTOOLDICTIONARY_INTERFACE_VERSION );
+ return;
+ }
+
+ if ( !dictionary->Connect( g_AppSystemFactory ) )
+ {
+ Sys_UnloadModule( module );
+ Warning( "CToolFrameworkInternal::LoadToolsFromLibrary: Dll '%s' connection phase failed.\n", dllname );
+ return;
+ }
+
+ if ( dictionary->Init( ) != INIT_OK )
+ {
+ Sys_UnloadModule( module );
+ Warning( "CToolFrameworkInternal::LoadToolsFromLibrary: Dll '%s' initialization phase failed.\n", dllname );
+ return;
+ }
+
+ dictionary->CreateTools();
+
+ int toolCount = dictionary->GetToolCount();
+ for ( int i = 0; i < toolCount; ++i )
+ {
+ IToolSystem *tool = dictionary->GetTool( i );
+ if ( tool )
+ {
+ Msg( "Loaded tool '%s'\n", tool->GetToolName() );
+ m_ToolSystems.AddToTail( tool );
+ }
+ }
+
+ m_Dictionaries.AddToTail( dictionary );
+ m_Modules.AddToTail( module );
+}
+
+
+//-----------------------------------------------------------------------------
+// Are we using tools?
+//-----------------------------------------------------------------------------
+bool CToolFrameworkInternal::InToolMode()
+{
+ return m_bInToolMode;
+}
+
+
+//-----------------------------------------------------------------------------
+// Should the game be allowed to render the world?
+//-----------------------------------------------------------------------------
+bool CToolFrameworkInternal::ShouldGameRenderView()
+{
+ if ( m_nActiveToolIndex >= 0 )
+ {
+ IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
+ Assert( tool );
+ return tool->ShouldGameRenderView( );
+ }
+ return true;
+}
+
+IMaterialProxy *CToolFrameworkInternal::LookupProxy( const char *proxyName )
+{
+ int toolCount = GetToolCount();
+ for ( int i = 0; i < toolCount; ++i )
+ {
+ IToolSystem *tool = m_ToolSystems[ i ];
+ Assert( tool );
+
+ IMaterialProxy *matProxy = tool->LookupProxy( proxyName );
+ if ( matProxy )
+ {
+ return matProxy;
+ }
+ }
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: FIXME: Should scan a KeyValues file
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::LoadTools()
+{
+ m_bInToolMode = true;
+
+ // Load rootdir/bin/enginetools.txt
+ KeyValues *kv = new KeyValues( "enginetools" );
+ Assert( kv );
+
+ // We don't ship enginetools.txt to Steam public, so we'll need to load sdkenginetools.txt if enginetools.txt isn't present
+ bool bLoadSDKFile = !g_pFileSystem->FileExists( "enginetools.txt", "EXECUTABLE_PATH" );
+
+ if ( kv && kv->LoadFromFile( g_pFileSystem, bLoadSDKFile ? "sdkenginetools.txt" : "enginetools.txt", "EXECUTABLE_PATH" ) )
+ {
+ for ( KeyValues *tool = kv->GetFirstSubKey();
+ tool != NULL;
+ tool = tool->GetNextKey() )
+ {
+ if ( !Q_stricmp( tool->GetName(), "library" ) )
+ {
+ // CHECK both bin/tools and gamedir/bin/tools
+ LoadToolsFromLibrary( tool->GetString() );
+ }
+ }
+
+ kv->deleteThis();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Level init, shutdown
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ClientLevelInitPreEntityAllTools()
+{
+ InvokeMethod( &IToolSystem::ClientLevelInitPreEntity );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ClientLevelInitPostEntityAllTools()
+{
+ InvokeMethod( &IToolSystem::ClientLevelInitPostEntity );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ClientLevelShutdownPreEntityAllTools()
+{
+ InvokeMethod( &IToolSystem::ClientLevelShutdownPreEntity );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Entities are deleted / released here...
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ClientLevelShutdownPostEntityAllTools()
+{
+ InvokeMethod( &IToolSystem::ClientLevelShutdownPostEntity );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ClientPreRenderAllTools()
+{
+ InvokeMethod( &IToolSystem::ClientPreRender );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CToolFrameworkInternal::IsThirdPersonCamera()
+{
+ if ( m_nActiveToolIndex >= 0 )
+ {
+ IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
+ Assert( tool );
+ return tool->IsThirdPersonCamera( );
+ }
+ return false;
+}
+
+// is the current tool recording?
+bool CToolFrameworkInternal::IsToolRecording()
+{
+ if ( m_nActiveToolIndex >= 0 )
+ {
+ IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
+ Assert( tool );
+ return tool->IsToolRecording( );
+ }
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ClientPostRenderAllTools()
+{
+ InvokeMethod( &IToolSystem::ClientPostRender );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Level init, shutdown
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ServerLevelInitPreEntityAllTools()
+{
+ InvokeMethod( &IToolSystem::ServerLevelInitPreEntity );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: entities are created / spawned / precached here
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ServerLevelInitPostEntityAllTools()
+{
+ InvokeMethod( &IToolSystem::ServerLevelInitPostEntity );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ServerLevelShutdownPreEntityAllTools()
+{
+ InvokeMethod( &IToolSystem::ServerLevelShutdownPreEntity );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Entities are deleted / released here...
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ServerLevelShutdownPostEntityAllTools()
+{
+ InvokeMethod( &IToolSystem::ServerLevelShutdownPostEntity );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Called each frame before entities think
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ServerFrameUpdatePreEntityThinkAllTools()
+{
+ InvokeMethod( &IToolSystem::ServerFrameUpdatePreEntityThink );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Called after entities think
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ServerFrameUpdatePostEntityThinkAllTools()
+{
+ InvokeMethod( &IToolSystem::ServerFrameUpdatePostEntityThink );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Called before client networking occurs on the server
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::ServerPreClientUpdateAllTools()
+{
+ InvokeMethod( &IToolSystem::ServerPreClientUpdate );
+}
+
+
+//-----------------------------------------------------------------------------
+// The server uses this to call into the tools to get the actual
+// entities to spawn on startup
+//-----------------------------------------------------------------------------
+const char* CToolFrameworkInternal::GetEntityData( const char *pActualEntityData )
+{
+ if ( m_nActiveToolIndex >= 0 )
+ {
+ IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
+ Assert( tool );
+ return tool->GetEntityData( pActualEntityData );
+ }
+ return pActualEntityData;
+}
+
+void CToolFrameworkInternal::ServerPreSetupVisibilityAllTools()
+{
+ InvokeMethod( &IToolSystem::ServerPreSetupVisibility );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose: Post a message to tools
+// Input : hEntity -
+// *msg -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg )
+{
+ // FIXME: Only message topmost tool?
+
+ int toolCount = m_ToolSystems.Count();
+ for ( int i = 0; i < toolCount; ++i )
+ {
+ IToolSystem *tool = m_ToolSystems[ i ];
+ Assert( tool );
+ tool->PostMessage( hEntity, msg );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Only active tool gets to adjust viewport
+// Input : x -
+// y -
+// width -
+// height -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::AdjustEngineViewport( int& x, int& y, int& width, int& height )
+{
+ if ( m_nActiveToolIndex >= 0 )
+ {
+ IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
+ Assert( tool );
+ tool->AdjustEngineViewport( x, y, width, height );
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Only active tool gets to set the camera/view
+//-----------------------------------------------------------------------------
+bool CToolFrameworkInternal::SetupEngineView( Vector &origin, QAngle &angles, float &fov )
+{
+ if ( m_nActiveToolIndex < 0 )
+ return false;
+
+ IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
+ Assert( tool );
+ return tool->SetupEngineView( origin, angles, fov );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Only active tool gets to set the microphone
+//-----------------------------------------------------------------------------
+bool CToolFrameworkInternal::SetupAudioState( AudioState_t &audioState )
+{
+ if ( m_nActiveToolIndex < 0 )
+ return false;
+
+ IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
+ Assert( tool );
+ return tool->SetupAudioState( audioState );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::VGui_PreRenderAllTools( int paintMode )
+{
+ InvokeMethodInt( &IToolSystem::VGui_PreRender, paintMode );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::VGui_PostRenderAllTools( int paintMode )
+{
+ InvokeMethodInt( &IToolSystem::VGui_PostRender, paintMode );
+}
+
+void CToolFrameworkInternal::VGui_PreSimulateAllTools()
+{
+ InvokeMethod( &IToolSystem::VGui_PreSimulate );
+}
+
+void CToolFrameworkInternal::VGui_PostSimulateAllTools()
+{
+ InvokeMethod( &IToolSystem::VGui_PostSimulate );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+// Output : int
+//-----------------------------------------------------------------------------
+int CToolFrameworkInternal::GetToolCount()
+{
+ return m_ToolSystems.Count();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : index -
+// Output : const char
+//-----------------------------------------------------------------------------
+const char *CToolFrameworkInternal::GetToolName( int index )
+{
+ if ( index < 0 || index >= m_ToolSystems.Count() )
+ {
+ return "";
+ }
+ IToolSystem *sys = m_ToolSystems[ index ];
+ if ( sys )
+ {
+ return sys->GetToolName();
+ }
+ return "";
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : index -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::SwitchToTool( int index )
+{
+ if ( ( m_ToolSystems.Count() < 1 ) || ( index >= m_ToolSystems.Count() ) )
+ return;
+
+ if ( index != m_nActiveToolIndex )
+ {
+ if ( m_nActiveToolIndex >= 0 )
+ {
+ IToolSystem *pOldTool = m_ToolSystems[ m_nActiveToolIndex ];
+ pOldTool->OnToolDeactivate();
+ }
+
+ m_nActiveToolIndex = index;
+ if ( m_nActiveToolIndex >= 0 )
+ {
+ IToolSystem *pNewTool = m_ToolSystems[ m_nActiveToolIndex ];
+ pNewTool->OnToolActivate();
+ }
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Switches to a named tool
+//-----------------------------------------------------------------------------
+IToolSystem *CToolFrameworkInternal::SwitchToTool( const char* pToolName )
+{
+ int nCount = GetToolCount();
+ for ( int i = 0; i < nCount; ++i )
+ {
+ if ( !Q_stricmp( pToolName, GetToolName(i) ) )
+ {
+ SwitchToTool( i );
+ return m_ToolSystems[i];
+ }
+ }
+
+ return NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *sys -
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CToolFrameworkInternal::IsTopmostTool( const IToolSystem *sys )
+{
+ if ( m_ToolSystems.Count() <= 0 || ( m_nActiveToolIndex < 0 ) )
+ return false;
+
+ return ( m_ToolSystems[ m_nActiveToolIndex ] == sys );
+}
+
+IToolSystem *CToolFrameworkInternal::GetTopmostTool()
+{
+ return m_nActiveToolIndex >= 0 ? m_ToolSystems[ m_nActiveToolIndex ] : NULL;
+}
+
+//-----------------------------------------------------------------------------
+// returns a tool system by index
+//-----------------------------------------------------------------------------
+const IToolSystem *CToolFrameworkInternal::GetToolSystem( int index ) const
+{
+ if ( ( index < 0 ) || ( index >= m_ToolSystems.Count() ) )
+ return NULL;
+
+ return m_ToolSystems[index];
+}
+
+
+void CToolFrameworkInternal::PostMessage( KeyValues *msg )
+{
+ if ( m_nActiveToolIndex >= 0 )
+ {
+ IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
+ Assert( tool );
+ tool->PostMessage( 0, msg );
+ }
+}
+
+bool CToolFrameworkInternal::GetSoundSpatialization( int iUserData, int guid, SpatializationInfo_t& info )
+{
+ if ( m_nActiveToolIndex >= 0 )
+ {
+ IToolSystem *tool = m_ToolSystems[ m_nActiveToolIndex ];
+ Assert( tool );
+ return tool->GetSoundSpatialization( iUserData, guid, info );
+ }
+ return true;
+}
+
+void CToolFrameworkInternal::HostRunFrameBegin()
+{
+ InvokeMethod( &IToolSystem::HostRunFrameBegin );
+}
+
+void CToolFrameworkInternal::HostRunFrameEnd()
+{
+ InvokeMethod( &IToolSystem::HostRunFrameEnd );
+}
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::RenderFrameBegin()
+{
+ InvokeMethod( &IToolSystem::RenderFrameBegin );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CToolFrameworkInternal::RenderFrameEnd()
+{
+ InvokeMethod( &IToolSystem::RenderFrameEnd );
+}
+
+// Exposed because it's an IAppSystem
+EXPOSE_SINGLE_INTERFACE_GLOBALVAR( CToolFrameworkInternal, IToolFrameworkInternal, VTOOLFRAMEWORK_INTERFACE_VERSION, g_ToolFrameworkInternal );
+
+//-----------------------------------------------------------------------------
+// Purpose: exposed from engine to client .dll
+//-----------------------------------------------------------------------------
+class CClientEngineTools : public IClientEngineTools
+{
+public:
+ virtual void LevelInitPreEntityAllTools();
+ virtual void LevelInitPostEntityAllTools();
+ virtual void LevelShutdownPreEntityAllTools();
+ virtual void LevelShutdownPostEntityAllTools();
+ virtual void PreRenderAllTools();
+ virtual void PostRenderAllTools();
+ virtual void PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg );
+ virtual void AdjustEngineViewport( int& x, int& y, int& width, int& height );
+ virtual bool SetupEngineView( Vector &origin, QAngle &angles, float &fov );
+ virtual bool SetupAudioState( AudioState_t &audioState );
+ virtual void VGui_PreRenderAllTools( int paintMode );
+ virtual void VGui_PostRenderAllTools( int paintMode );
+ virtual bool IsThirdPersonCamera( );
+ virtual bool InToolMode();
+};
+
+EXPOSE_SINGLE_INTERFACE( CClientEngineTools, IClientEngineTools, VCLIENTENGINETOOLS_INTERFACE_VERSION );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CClientEngineTools::LevelInitPreEntityAllTools()
+{
+ g_ToolFrameworkInternal.ClientLevelInitPreEntityAllTools();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CClientEngineTools::LevelInitPostEntityAllTools()
+{
+ g_ToolFrameworkInternal.ClientLevelInitPostEntityAllTools();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CClientEngineTools::LevelShutdownPreEntityAllTools()
+{
+ g_ToolFrameworkInternal.ClientLevelShutdownPreEntityAllTools();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CClientEngineTools::LevelShutdownPostEntityAllTools()
+{
+ g_ToolFrameworkInternal.ClientLevelShutdownPostEntityAllTools();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CClientEngineTools::PreRenderAllTools()
+{
+ g_ToolFrameworkInternal.ClientPreRenderAllTools();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CClientEngineTools::PostRenderAllTools()
+{
+ g_ToolFrameworkInternal.ClientPostRenderAllTools();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : hEntity -
+// *msg -
+//-----------------------------------------------------------------------------
+void CClientEngineTools::PostToolMessage( HTOOLHANDLE hEntity, KeyValues *msg )
+{
+ g_ToolFrameworkInternal.PostToolMessage( hEntity, msg );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : x -
+// y -
+// width -
+// height -
+//-----------------------------------------------------------------------------
+void CClientEngineTools::AdjustEngineViewport( int& x, int& y, int& width, int& height )
+{
+ g_ToolFrameworkInternal.AdjustEngineViewport( x, y, width, height );
+}
+
+bool CClientEngineTools::SetupEngineView( Vector &origin, QAngle &angles, float &fov )
+{
+ return g_ToolFrameworkInternal.SetupEngineView( origin, angles, fov );
+}
+
+bool CClientEngineTools::SetupAudioState( AudioState_t &audioState )
+{
+ return g_ToolFrameworkInternal.SetupAudioState( audioState );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CClientEngineTools::VGui_PreRenderAllTools( int paintMode )
+{
+ g_ToolFrameworkInternal.VGui_PreRenderAllTools( paintMode );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CClientEngineTools::VGui_PostRenderAllTools( int paintMode )
+{
+ g_ToolFrameworkInternal.VGui_PostRenderAllTools( paintMode );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+bool CClientEngineTools::IsThirdPersonCamera( )
+{
+ return g_ToolFrameworkInternal.IsThirdPersonCamera( );
+}
+
+bool CClientEngineTools::InToolMode()
+{
+ return g_ToolFrameworkInternal.InToolMode();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose: Exposed to server.dll
+//-----------------------------------------------------------------------------
+class CServerEngineTools : public IServerEngineTools
+{
+public:
+ // Inherited from IServerEngineTools
+ virtual void LevelInitPreEntityAllTools();
+ virtual void LevelInitPostEntityAllTools();
+ virtual void LevelShutdownPreEntityAllTools();
+ virtual void LevelShutdownPostEntityAllTools();
+ virtual void FrameUpdatePreEntityThinkAllTools();
+ virtual void FrameUpdatePostEntityThinkAllTools();
+ virtual void PreClientUpdateAllTools();
+ virtual void PreSetupVisibilityAllTools();
+ virtual const char* GetEntityData( const char *pActualEntityData );
+ virtual bool InToolMode();
+};
+
+EXPOSE_SINGLE_INTERFACE( CServerEngineTools, IServerEngineTools, VSERVERENGINETOOLS_INTERFACE_VERSION );
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CServerEngineTools::LevelInitPreEntityAllTools()
+{
+ g_ToolFrameworkInternal.ServerLevelInitPreEntityAllTools();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CServerEngineTools::LevelInitPostEntityAllTools()
+{
+ g_ToolFrameworkInternal.ServerLevelInitPostEntityAllTools();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CServerEngineTools::LevelShutdownPreEntityAllTools()
+{
+ g_ToolFrameworkInternal.ServerLevelShutdownPreEntityAllTools();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CServerEngineTools::LevelShutdownPostEntityAllTools()
+{
+ g_ToolFrameworkInternal.ServerLevelShutdownPostEntityAllTools();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CServerEngineTools::FrameUpdatePreEntityThinkAllTools()
+{
+ g_ToolFrameworkInternal.ServerFrameUpdatePreEntityThinkAllTools();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CServerEngineTools::FrameUpdatePostEntityThinkAllTools()
+{
+ g_ToolFrameworkInternal.ServerFrameUpdatePostEntityThinkAllTools();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : -
+//-----------------------------------------------------------------------------
+void CServerEngineTools::PreClientUpdateAllTools()
+{
+ g_ToolFrameworkInternal.ServerPreClientUpdateAllTools();
+}
+
+
+//-----------------------------------------------------------------------------
+// The server uses this to call into the tools to get the actual
+// entities to spawn on startup
+//-----------------------------------------------------------------------------
+const char* CServerEngineTools::GetEntityData( const char *pActualEntityData )
+{
+ return g_ToolFrameworkInternal.GetEntityData( pActualEntityData );
+}
+
+void CServerEngineTools::PreSetupVisibilityAllTools()
+{
+ return g_ToolFrameworkInternal.ServerPreSetupVisibilityAllTools();
+}
+
+bool CServerEngineTools::InToolMode()
+{
+ return g_ToolFrameworkInternal.InToolMode();
+}