552 lines
12 KiB
C++
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 );
|
|
}
|
|
}
|