#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 ); } }