JD2022-TU1/main/extern/Soundwich/Solution/Engine/Src/Synth.cpp

552 lines
12 KiB
C++

#include "Synth.h"
#include "Component.h"
#include "Util/InputFileStream.h"
#include "Util/OutputFileStream.h"
#include "Util/InputMemoryStream.h"
#include "EngineImpl.h"
#ifdef ITF_WINDOWS
#include "Tracking/Tracker_win32.h"
#else
#include "Tracking/Tracker_Stub.h"
#endif
#if defined( USE_WWISE )
#include "Wwise/WwiseEngine.h"
#endif
Soundwich::Synth::Synth( Engine::Impl* engine, const Util::String& name )
: _engine( engine )
, _name( name )
{
#ifdef ITF_WINDOWS
_tracker = new Tracker_win32();
#else
_tracker = new Tracker_Stub();
#endif
#if defined( USE_WWISE )
WwiseEngine::GetInstance( )->RegisterGameObject( (uint32)this, _name.Chars( ) );
#endif
}
Soundwich::Synth::~Synth( )
{
#if defined( USE_WWISE )
WwiseEngine::GetInstance( )->UnregisterGameObject( (uint32)this );
#endif
for( ComponentDictionary::Iterator it = _components.Begin( ); it != _components.End( ); ++it )
{
Component* component = it->second;
delete component;
}
_components.Clear( );
for( ConnectionArray::Iterator it = _connections.Begin( ); it != _connections.End( ); ++it )
{
Connection* connection = *it;
delete connection;
}
_connections.Clear( );
delete(_tracker);
}
SoundResult Soundwich::Synth::Serialize( Util::BinaryWriter& writer )
{
//writer.Write( (uint16)_components.Size( ) );
//for( auto component : _components )
//{
// // write type id
// writer.Write< Util::UniqueId::IdType >( component->GetId( ) );
// // write name
// writer.Write< Util::String >( component->GetName( ) );
// // serialize
// component->Serialize( writer );
//}
//
//writer.Write( (uint16)_connections.Size( ) );
//for( auto connection : _connections )
//{
// // write type id
// writer.Write< Util::UniqueId::IdType >( connection->GetId( ) );
// // serialize
// connection->Serialize( writer );
//}
return Ok;
}
SoundResult Soundwich::Synth::Deserialize( Util::BinaryReader& reader )
{
//uint16 size;
//bool result = reader.Read( size );
//if( result )
//{
// for( uint16 count = 0; count < size; ++count )
// {
// Component* component = nullptr;
// // read type id
// Util::UniqueId::IdType id;
// result = reader.Read< Util::UniqueId::IdType >( id );
// if( result )
// {
// // read name
// Util::String name;
// result = reader.Read< Util::String >( name );
// if( result )
// {
// // create component
// Component::CreateMethods[ id ]( this, name, &component );
// // deserialize
// result = component->Deserialize( reader );
// }
// }
// }
//}
//if( !result )
//{
// LOG_ERROR( GetEngine( )->GetLog( ), "Error deserializing component" );
// // clean up
// for( auto component : _components )
// {
// delete component;
// }
// return result ? Ok : DeserializeComponentError;
//}
//result = reader.Read( size );
//if( result )
//{
// for( uint16 count = 0; count < size; ++count )
// {
// Connection* connection = nullptr;
// // read type id
// Util::UniqueId::IdType id;
// result = reader.Read< Util::UniqueId::IdType >( id );
// if( result )
// {
// // create connection
// Connection::CreateMethods[ id ]( this, &connection );
// // deserialize
// result = connection->Deserialize( reader );
// }
// }
//}
//if( !result )
//{
// LOG_ERROR( GetEngine( )->GetLog( ), "Error deserializing connection" );
// // clean up
// for( auto connection : _connections )
// {
// delete connection;
// }
//}
//return result ? Ok : DeserializeConnectionError;
return Ok;
}
SoundResult Soundwich::Synth::Serialize( Util::XmlWriter& writer )
{
writer.OpenElement( "Synth" );
writer.OpenElement( "Components" );
ComponentDictionary::Iterator component = _components.begin();
for( ; component != _components.end() ; ++component )
{
// create component tag
writer.OpenElement( component->second->GetDerivedType( ) );
// write name
writer.WriteAttribute< Util::String >( "Name", component->second->GetName( ) );
// serialize
component->second->Serialize( writer );
writer.CloseElement( );
}
writer.CloseElement( );
writer.OpenElement( "Connections" );
ConnectionArray::Iterator connection = _connections.begin();
for( ; connection != _connections.end() ; ++connection )
{
// create connection tag
writer.OpenElement( (*connection)->GetDerivedType( ) );
// serialize
(*connection)->Serialize( writer );
writer.CloseElement( );
}
writer.CloseElement( );
writer.CloseElement( );
return Ok;
}
SoundResult Soundwich::Synth::Deserialize( Util::XmlReader& reader )
{
bool result = reader.GetChildElement( "Synth" );
if( result )
{
result = reader.GetChildElement( "Components" );
if( result )
{
if( reader.HasChildElements( ) )
{
reader.GetChildElement( );
do
{
Component* component = nullptr;
// read type
Util::String type = reader.GetName( );
// read name
Util::String name;
result = reader.ReadAttribute( "Name", name );
if( result )
{
// create component
GetEngine( )->GetFactory( ).CreateComponent( this, type, name, &component );
//Component::CreateMethods[ Component::IdFromType( type ) ]( this, name, &component );
// deserialize
result = component && component->Deserialize( reader );
}
}
while ( reader.GetNextSibling( ) );
reader.GetParentElement( );
}
reader.GetParentElement( );
}
if( !result )
{
return DeserializeError;
}
result = reader.GetChildElement( "Connections" );
if( result )
{
if( reader.HasChildElements( ) )
{
reader.GetChildElement( );
do
{
Connection* connection = nullptr;
// read type
Util::String type = reader.GetName( );
// create connection
GetEngine( )->GetFactory( ).CreateConnection( this, type, &connection );
//Connection::CreateMethods[ Connection::IdFromType( type ) ]( this, &connection );
// deserialize
result = connection && connection->Deserialize( reader );
}
while ( reader.GetNextSibling( ) );
}
}
if( !result )
{
return DeserializeError;
}
}
return result ? Ok : DeserializeError;
}
SoundResult Soundwich::Synth::LoadFromFile( const Util::String& fileName )
{
Util::InputFileStream stream( fileName );
if( stream.Exists( ) )
{
Util::BinaryReader reader( stream );
return Deserialize( reader );
}
else
{
return LoadError;
}
}
SoundResult Soundwich::Synth::LoadFromMemory( void* data, uint32 size )
{
Util::InputMemoryStream stream( (uint8*)data, size );
Util::BinaryReader reader( stream );
return Deserialize( reader );
}
SoundResult Soundwich::Synth::LoadFromXmlFile( const Util::String& fileName )
{
Util::InputFileStream stream( fileName );
if( stream.Exists( ) )
{
Util::XmlReader reader( stream );
return Deserialize( reader );
}
else
{
return LoadError;
}
}
SoundResult Soundwich::Synth::LoadFromXmlMemory( const Util::String& xml )
{
Util::InputMemoryStream stream( (uint8*)xml.Chars( ), xml.Length( ) );
Util::XmlReader reader( stream );
return Deserialize( reader );
}
SoundResult Soundwich::Synth::SaveToFile( const Util::String& fileName )
{
Util::OutputFileStream stream( fileName );
if( stream.Exists( ) )
{
Util::BinaryWriter writer( stream );
return Serialize( writer );
}
else
{
return SaveError;
}
}
SoundResult Soundwich::Synth::SaveToXmlFile( const Util::String& fileName )
{
Util::OutputFileStream stream( fileName );
if( stream.Exists( ) )
{
Util::XmlWriter writer( stream );
return Serialize( writer );
}
else
{
return SaveError;
}
}
void Soundwich::Synth::AddTick( Component* component )
{
Assert( !_ticking.Contains( component ) );
_ticking.PushBack( component );
}
void Soundwich::Synth::RemoveTick( Component* component )
{
Assert( _ticking.Contains( component ) );
_ticking.Remove( component );
}
void Soundwich::Synth::Tick( flt32 interval )
{
// copy array as component ticks can remove themselves
ComponentArray ticking = _ticking;
for( ComponentArray::Iterator it = ticking.Begin( ); it != ticking.End( ); ++it )
{
(*it)->Tick( interval );
}
}
void Soundwich::Synth::AddRender( Component* component, int32 depth )
{
Assert( !_rendering[depth]->Contains( component ) );
if( depth >= (int32)_rendering.Size( ) )
{
_rendering.Resize( depth + 1 );
}
if( _rendering[depth] == nullptr )
{
_rendering[depth] = new Util::DynamicArray< Component* >;
}
_rendering[depth]->PushBack( component );
}
void Soundwich::Synth::RemoveRender( Component* component, int32 depth )
{
Assert( depth < (int32)_rendering.Size( ) );
Assert( _rendering[depth] );
Assert( _rendering[depth]->Contains( component ) );
_rendering[depth]->Remove( component );
}
void Soundwich::Synth::Render( )
{
for( RenderingArray::Iterator depth = _rendering.Begin( ); depth != _rendering.End( ); ++depth )
{
Util::DynamicArray< Component* > prepare = **depth;
for( ComponentArray::Iterator it = prepare.Begin( ); it != prepare.End( ); ++it )
{
(*it)->Prepare( );
}
}
for( RenderingArray::Iterator depth = _rendering.Begin( ); depth != _rendering.End( ); ++depth )
{
Util::DynamicArray< Component* > process = **depth;
for( ComponentArray::Iterator it = process.Begin( ); it != process.End( ); ++it )
{
(*it)->Process( );
}
}
}
void Soundwich::Synth::GetStats( Engine::Stats& stats )
{
for( ComponentDictionary::Iterator it = _components.Begin( ); it != _components.End( ); ++it )
{
Component* component = it->second;
component->GetStats( stats );
}
}
void Soundwich::Synth::SwitchTracking( bool enable, const char* exportFilePath)
{
_tracker->Switch( enable, exportFilePath);
}
void Soundwich::Synth::StartTrackingActivation()
{
_tracker->StartActivation();
}
void Soundwich::Synth::EndTrackingActivation()
{
_tracker->CloseActivation();
}
void Soundwich::Synth::RecordTrackingConnection ( const char* dataType, const char* value, const Soundwich::Component* from, const Soundwich::Component* to, int32 portOut, int32 portIn )
{
_tracker->AddTrackConnection(dataType, from->GetName(), to->GetName(), portOut, portIn, value);
_tracker->AddTrackComponent(from->GetName(), from->GetDerivedType());
_tracker->AddTrackComponent(to->GetName(), to->GetDerivedType());
}
void Soundwich::Synth::RegisterTracker(ISoundwichTracking* cb)
{
_tracker->RegisterCallback(cb);
}
void Soundwich::Synth::UnregisterTracker(ISoundwichTracking* cb)
{
_tracker->UnregisterCallback(cb);
}
void Soundwich::Synth::SetDebugLogging( bool enable )
{
for( ComponentDictionary::Iterator it = _components.Begin( ); it != _components.End( ); ++it )
{
Component* component = it->second;
component->SetDebugLogging( enable );
}
for( ConnectionArray::Iterator it = _connections.Begin( ); it != _connections.End( ); ++it )
{
Connection* connection = *it;
connection->SetDebugLogging( enable );
}
}