<commit_before>#include <stingray/toolkit/Factory.h>

#include <stingray/toolkit/any.h>

#include <stingray/app/RecordErrors.h>
#include <stingray/app/activation_manager/ActivationIntent.h>
#include <stingray/app/application_context/AppChannel.h>
#include <stingray/app/application_context/ChannelList.h>
#include <stingray/app/scheduler/ScheduledEvents.h>
#include <stingray/ca/BasicSubscriptionLease.h>
#include <stingray/ca/BissConditionalAccess.h>
#include <stingray/ca/DreSubscription.h>
#include <stingray/ca/SubscriptionBundle.h>
#include <stingray/crypto/PlainCipherKey.h>
#include <stingray/details/IReceiverTrait.h>
#include <stingray/hdmi/IHDMI.h>
#include <stingray/media/ImageFileMediaData.h>
#include <stingray/media/MediaInfoBase.h>
#include <stingray/media/formats/flv/MediaInfo.h>
#include <stingray/media/formats/mp3/Mp3MediaInfo.h>
#include <stingray/media/formats/mp4/MediaInfo.h>
#include <stingray/media/formats/mp4/Stream.h>
#include <stingray/media/formats/mp4/SubstreamDescriptors.h>
#include <stingray/mpeg/ContentDescription.h>
#include <stingray/mpeg/PvrDescription.h>
#include <stingray/mpeg/Stream.h>
#include <stingray/net/DHCPInterfaceConfiguration.h>
#include <stingray/net/IgnoredInterfaceConfiguration.h>
#include <stingray/net/LinkLocalInterfaceConfiguration.h>
#include <stingray/net/ManualInterfaceConfiguration.h>
#include <stingray/parentalcontrol/AgeRating.h>
#ifdef PLATFORM_EMU
#	include <stingray/platform/emu/scanner/Channel.h>
#endif
#ifdef PLATFORM_EMU
#	include <stingray/platform/emu/scanner/EmuScanPerformerFactory.h>
#endif
#ifdef PLATFORM_MSTAR
#	include <stingray/platform/mstar/crypto/HardwareCipherKey.h>
#endif
#ifdef PLATFORM_OPENSSL
#	include <stingray/platform/openssl/crypto/Certificate.h>
#endif
#ifdef PLATFORM_OPENSSL
#	include <stingray/platform/openssl/crypto/CertificateRevocationList.h>
#endif
#ifdef PLATFORM_OPENSSL
#	include <stingray/platform/openssl/crypto/EvpKey.h>
#endif
#ifdef PLATFORM_STAPI
#	include <stingray/platform/stapi/crypto/HardwareCipherKey.h>
#endif
#include <stingray/pushvod/pushvod_emu/PushVODEmulationMovie.h>
#include <stingray/records/FileSystemRecord.h>
#include <stingray/rpc/UrlObjectId.h>
#include <stingray/scanner/DVBServiceId.h>
#include <stingray/scanner/DefaultDVBTBandInfo.h>
#include <stingray/scanner/DefaultMpegService.h>
#include <stingray/scanner/DefaultMpegSubstreamDescriptor.h>
#include <stingray/scanner/DefaultScanParams.h>
#include <stingray/scanner/DefaultScanPerformerFactory.h>
#include <stingray/scanner/DreCasGeographicRegion.h>
#include <stingray/scanner/LybidScanParams.h>
#include <stingray/scanner/LybidScanPerformerFactory.h>
#include <stingray/scanner/TerrestrialScanParams.h>
#include <stingray/scanner/TricolorGeographicRegion.h>
#include <stingray/scanner/TricolorScanParams.h>
#include <stingray/scanner/TricolorScanPerformerFactory.h>
#include <stingray/scanner/lybid/LybidServiceMetaInfo.h>
#include <stingray/scanner/terrestrial/TerrestrialServiceMetaInfo.h>
#include <stingray/scanner/tricolor/TricolorServiceMetaInfo.h>
#include <stingray/stats/StatisticChannelInfo.h>
#include <stingray/streams/PlaybackStreamContent.h>
#include <stingray/streams/RecordStreamContent.h>
#include <stingray/streams/RecordStreamMetaInfo.h>
#include <stingray/time/BuiltinTimeSourceId.h>
#include <stingray/time/TDTTimeSourceId.h>
#include <stingray/time/TransportsTimeSourceObtainer.h>
#include <stingray/tuners/TunerState.h>
#include <stingray/tuners/dvbs/Antenna.h>
#include <stingray/tuners/dvbs/DefaultDVBSTransport.h>
#include <stingray/tuners/dvbs/Satellite.h>
#include <stingray/tuners/dvbt/DVBTTransport.h>
#include <stingray/tuners/ip/TsOverIpTransport.h>
#include <stingray/update/VersionRequirement.h>
#include <stingray/update/system/CopyFile.h>
#include <stingray/update/system/EraseFlashPartition.h>
#include <stingray/update/system/MountFilesystem.h>
#include <stingray/update/system/MoveFile.h>
#include <stingray/update/system/RemoveFile.h>
#include <stingray/update/system/UnmountFilesystem.h>
#include <stingray/update/system/WriteFlashPartition.h>

/* WARNING! This is autogenerated file, DO NOT EDIT! */

namespace stingray { namespace Detail
{
	void Factory::RegisterTypes()
	{
#ifdef BUILD_SHARED_LIB
		/*nothing*/
#else
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::NoSubscriptionRecordError);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::SimpleRecordError);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ActivationKeyIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::PersonalCodeIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::PlatformNameIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ReceiverTraitIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::AppChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ChannelList);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::CinemaHallScheduledViewing);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ContinuousScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::DeferredStandby);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::InfiniteScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledRecord);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledViewing);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BasicSubscriptionLease);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BasicSubscriptionProvider);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BissSubscription);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Dre4Provider);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Dre4Subscription);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(SubscriptionBundle);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(PlainCipherKey);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBCReceiverTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBSReceiverTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBTReceiverTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HouseholdClientTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HouseholdServerTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidOperatorTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(SatIpClientTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorOperatorTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HDMIConfig);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ImageFileMediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ImageFileMediaPreview);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(InMemoryImageMediaPreview);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MediaInfoBase);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(flv::MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Mp3MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::Stream);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::Mp4MediaAudioSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::Mp4MediaVideoSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mpeg::ContentDescription);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mpeg::PvrDescription);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mpeg::Stream);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DHCPInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(IgnoredInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LinkLocalInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ManualInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(AgeRating);
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::EmuServiceId);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::RadioChannel);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::SubstreamDescriptor);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::TVChannel);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::EmuScanPerformerFactory);
#endif
#ifdef PLATFORM_MSTAR
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mstar::HardwareCipherKey);
#endif
#ifdef PLATFORM_OPENSSL
		TOOLKIT_REGISTER_CLASS_EXPLICIT(openssl::Certificate);
#endif
#ifdef PLATFORM_OPENSSL
		TOOLKIT_REGISTER_CLASS_EXPLICIT(openssl::CertificateRevocationList);
#endif
#ifdef PLATFORM_OPENSSL
		TOOLKIT_REGISTER_CLASS_EXPLICIT(openssl::EvpKey);
#endif
#ifdef PLATFORM_STAPI
		TOOLKIT_REGISTER_CLASS_EXPLICIT(stapi::HardwareCipherKey);
#endif
		TOOLKIT_REGISTER_CLASS_EXPLICIT(PushVODEmulationMovie);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(FileSystemRecord);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(rpc::UrlObjectId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBServiceId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBTBandInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegRadioChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegService);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegTVChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegAudioSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegDataCarouselSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegPcrSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegSubtitlesSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegTeletextBasedSubtitlesSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegTeletextSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegVideoSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultScanPerformerFactory);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DreCasGeographicRegion);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidScanPerformerFactory);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TerrestrialScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorGeographicRegion);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorScanPerformerFactory);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidServiceMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TerrestrialServiceMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorServiceMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Detail::any::ObjectHolder<stingray::StatisticChannelInfo>);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(PlaybackStreamContent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RecordStreamContent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RecordStreamMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BuiltinTimeSourceId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TDTTimeSourceId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TransportTimeOffset);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(CircuitedTunerState);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LockedTunerState);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(UnlockedTunerState);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Antenna);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBSTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Satellite);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBTTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TsOverIpTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(VersionRequirement);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(CopyFile);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(EraseFlashPartition);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MountFilesystem);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MoveFile);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RemoveFile);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(UnmountFilesystem);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(WriteFlashPartition);
#endif
	}
}}
<commit_msg>Update 'stingray_resources' and factory classes.<commit_after>#include <stingray/toolkit/Factory.h>

#include <stingray/toolkit/any.h>

#include <stingray/app/RecordErrors.h>
#include <stingray/app/activation_manager/ActivationIntent.h>
#include <stingray/app/application_context/AppChannel.h>
#include <stingray/app/application_context/ChannelList.h>
#include <stingray/app/scheduler/ScheduledEvents.h>
#include <stingray/ca/BasicSubscriptionLease.h>
#include <stingray/ca/BissConditionalAccess.h>
#include <stingray/ca/DreSubscription.h>
#include <stingray/ca/SubscriptionBundle.h>
#include <stingray/crypto/PlainCipherKey.h>
#include <stingray/details/IReceiverTrait.h>
#include <stingray/hdmi/IHDMI.h>
#include <stingray/media/ImageFileMediaData.h>
#include <stingray/media/MediaInfoBase.h>
#include <stingray/media/formats/flv/MediaInfo.h>
#include <stingray/media/formats/mp3/Mp3MediaInfo.h>
#include <stingray/media/formats/mp4/MediaInfo.h>
#include <stingray/media/formats/mp4/Stream.h>
#include <stingray/media/formats/mp4/SubstreamDescriptors.h>
#include <stingray/mpeg/ContentDescription.h>
#include <stingray/mpeg/PvrDescription.h>
#include <stingray/mpeg/Stream.h>
#include <stingray/net/DHCPInterfaceConfiguration.h>
#include <stingray/net/IgnoredInterfaceConfiguration.h>
#include <stingray/net/LinkLocalInterfaceConfiguration.h>
#include <stingray/net/ManualInterfaceConfiguration.h>
#include <stingray/net/NetworkConfiguration.h>
#include <stingray/parentalcontrol/AgeRating.h>
#ifdef PLATFORM_EMU
#	include <stingray/platform/emu/scanner/Channel.h>
#endif
#ifdef PLATFORM_EMU
#	include <stingray/platform/emu/scanner/EmuScanPerformerFactory.h>
#endif
#ifdef PLATFORM_MSTAR
#	include <stingray/platform/mstar/crypto/HardwareCipherKey.h>
#endif
#ifdef PLATFORM_OPENSSL
#	include <stingray/platform/openssl/crypto/Certificate.h>
#endif
#ifdef PLATFORM_OPENSSL
#	include <stingray/platform/openssl/crypto/CertificateRevocationList.h>
#endif
#ifdef PLATFORM_OPENSSL
#	include <stingray/platform/openssl/crypto/EvpKey.h>
#endif
#ifdef PLATFORM_STAPI
#	include <stingray/platform/stapi/crypto/HardwareCipherKey.h>
#endif
#include <stingray/pushvod/pushvod_emu/PushVODEmulationMovie.h>
#include <stingray/records/FileSystemRecord.h>
#include <stingray/rpc/UrlObjectId.h>
#include <stingray/scanner/DVBServiceId.h>
#include <stingray/scanner/DefaultDVBTBandInfo.h>
#include <stingray/scanner/DefaultMpegService.h>
#include <stingray/scanner/DefaultMpegSubstreamDescriptor.h>
#include <stingray/scanner/DefaultScanParams.h>
#include <stingray/scanner/DefaultScanPerformerFactory.h>
#include <stingray/scanner/DreCasGeographicRegion.h>
#include <stingray/scanner/LybidScanParams.h>
#include <stingray/scanner/LybidScanPerformerFactory.h>
#include <stingray/scanner/TerrestrialScanParams.h>
#include <stingray/scanner/TricolorGeographicRegion.h>
#include <stingray/scanner/TricolorScanParams.h>
#include <stingray/scanner/TricolorScanPerformerFactory.h>
#include <stingray/scanner/lybid/LybidServiceMetaInfo.h>
#include <stingray/scanner/terrestrial/TerrestrialServiceMetaInfo.h>
#include <stingray/scanner/tricolor/AutoCreatedListMetaInfo.h>
#include <stingray/scanner/tricolor/TricolorServiceMetaInfo.h>
#include <stingray/stats/StatisticChannelInfo.h>
#include <stingray/streams/PlaybackStreamContent.h>
#include <stingray/streams/RecordStreamContent.h>
#include <stingray/streams/RecordStreamMetaInfo.h>
#include <stingray/time/BuiltinTimeSourceId.h>
#include <stingray/time/TDTTimeSourceId.h>
#include <stingray/time/TransportsTimeSourceObtainer.h>
#include <stingray/tuners/TunerState.h>
#include <stingray/tuners/dvbs/Antenna.h>
#include <stingray/tuners/dvbs/DefaultDVBSTransport.h>
#include <stingray/tuners/dvbs/Satellite.h>
#include <stingray/tuners/dvbt/DVBTTransport.h>
#include <stingray/tuners/ip/TsOverIpTransport.h>
#include <stingray/update/VersionRequirement.h>
#include <stingray/update/system/CopyFile.h>
#include <stingray/update/system/EraseFlashPartition.h>
#include <stingray/update/system/MountFilesystem.h>
#include <stingray/update/system/MoveFile.h>
#include <stingray/update/system/RemoveFile.h>
#include <stingray/update/system/UnmountFilesystem.h>
#include <stingray/update/system/WriteFlashPartition.h>

/* WARNING! This is autogenerated file, DO NOT EDIT! */

namespace stingray { namespace Detail
{
	void Factory::RegisterTypes()
	{
#ifdef BUILD_SHARED_LIB
		/*nothing*/
#else
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::NoSubscriptionRecordError);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::SimpleRecordError);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ActivationKeyIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::PersonalCodeIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::PlatformNameIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ReceiverTraitIntent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::AppChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ChannelList);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::CinemaHallScheduledViewing);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ContinuousScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::DeferredStandby);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::InfiniteScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledEvent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledRecord);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(app::ScheduledViewing);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BasicSubscriptionLease);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BasicSubscriptionProvider);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BissSubscription);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Dre4Provider);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Dre4Subscription);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(SubscriptionBundle);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(PlainCipherKey);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBCReceiverTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBSReceiverTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBTReceiverTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HouseholdClientTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HouseholdServerTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidOperatorTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(SatIpClientTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorOperatorTrait);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(HDMIConfig);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ImageFileMediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ImageFileMediaPreview);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(InMemoryImageMediaPreview);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MediaInfoBase);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(flv::MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Mp3MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::MediaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::Stream);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::Mp4MediaAudioSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mp4::Mp4MediaVideoSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mpeg::ContentDescription);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mpeg::PvrDescription);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mpeg::Stream);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DHCPInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(IgnoredInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LinkLocalInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(ManualInterfaceConfiguration);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Detail::any::ObjectHolder<NetworkConfigurationStatus>);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(AgeRating);
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::EmuServiceId);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::RadioChannel);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::SubstreamDescriptor);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::TVChannel);
#endif
#ifdef PLATFORM_EMU
		TOOLKIT_REGISTER_CLASS_EXPLICIT(emu::EmuScanPerformerFactory);
#endif
#ifdef PLATFORM_MSTAR
		TOOLKIT_REGISTER_CLASS_EXPLICIT(mstar::HardwareCipherKey);
#endif
#ifdef PLATFORM_OPENSSL
		TOOLKIT_REGISTER_CLASS_EXPLICIT(openssl::Certificate);
#endif
#ifdef PLATFORM_OPENSSL
		TOOLKIT_REGISTER_CLASS_EXPLICIT(openssl::CertificateRevocationList);
#endif
#ifdef PLATFORM_OPENSSL
		TOOLKIT_REGISTER_CLASS_EXPLICIT(openssl::EvpKey);
#endif
#ifdef PLATFORM_STAPI
		TOOLKIT_REGISTER_CLASS_EXPLICIT(stapi::HardwareCipherKey);
#endif
		TOOLKIT_REGISTER_CLASS_EXPLICIT(PushVODEmulationMovie);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(FileSystemRecord);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(rpc::UrlObjectId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBServiceId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBTBandInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegRadioChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegService);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultMpegTVChannel);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegAudioSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegDataCarouselSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegPcrSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegSubtitlesSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegTeletextBasedSubtitlesSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegTeletextSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MpegVideoSubstreamDescriptor);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultScanPerformerFactory);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DreCasGeographicRegion);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidScanPerformerFactory);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TerrestrialScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorGeographicRegion);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorScanParams);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorScanPerformerFactory);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LybidServiceMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TerrestrialServiceMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(AutoCreatedListMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TricolorServiceMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Detail::any::ObjectHolder<stingray::StatisticChannelInfo>);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(PlaybackStreamContent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RecordStreamContent);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RecordStreamMetaInfo);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(BuiltinTimeSourceId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TDTTimeSourceId);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TransportTimeOffset);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(CircuitedTunerState);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(LockedTunerState);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(UnlockedTunerState);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Antenna);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DefaultDVBSTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(Satellite);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(DVBTTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(TsOverIpTransport);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(VersionRequirement);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(CopyFile);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(EraseFlashPartition);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MountFilesystem);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(MoveFile);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(RemoveFile);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(UnmountFilesystem);
		TOOLKIT_REGISTER_CLASS_EXPLICIT(WriteFlashPartition);
#endif
	}
}}
<|endoftext|>


<commit_before>/*
 * Agent.cpp
 *
 * The reinforcement learning agent: the core of the project
 */

#include <vector>
#include <chrono>
#include <math.h>
#include <stdio.h>
#include <fstream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iostream>

#include <Box2D/Box2D.h>

#include "Agent.h"
#include "State.h"
#include "../action/Action.h"

const int	Agent::STATES_TO_BACKPORT		= 50;

const float Agent::VALUE_ADJUST_FRACTION	= 0.35f;
const float Agent::EPSILON					= 0.15f;

Agent::Agent(std::vector<Action*> availableActions):
	availableActions(availableActions), generator(seed()){

	//states.reserve(std::pow(9, 9));//reserves ≈ 400 MB RAM and prevents reallocations

	loadPolicyFromFile();
}

void Agent::think(State state, std::vector<float> collectedRewards){

	int		currentStateIndex	= 0;
	float	lastValue, factor;

	//first check whether this state already occured or not and retrieve the iterator
	std::vector<State>::iterator it = std::lower_bound(states.begin(), states.end(), state);
	currentStateIndex = (it - states.begin());

	if(currentStateIndex >= states.size() || states[currentStateIndex] != state){
		//If its a new state, add it at the *right* position to prevent another sort
		it = states.insert(it, state);

		//As we inserted an element we need to increase the index of all after the new one
		for(int i=0;i<lastActions.size();i++){
			if(lastActions[i].first >= currentStateIndex){
				lastActions[i].first++;
			}
		}
	}

	/*
	 * Maybe (actually most of the time in a pinball game) the good/bad reward isn't simply caused by the last action taken
	 * A series of actions and event have lead to this specific situation, so we need to apply the reward received for the last action
	 * to the last state in general, in other words to every possible action
	 *
	 * Example:
	 * State 0:		Action: EnableFlipperLeft		Reward:	0.0f	Cause: Ball leaves the CF in the direction of a pin
	 * State 10:	Action: DisableFlipperRight		Reward: 0.0f	Cause: Nothing, ball is still travelling in the direction of the pin
	 * State 15:	Action: DisableFlipperRight		Reward: 1.0f	Cause: Nothing BUT the ball kicked in state 0 hits the pin and causes a reward of 1.0f
	 *
	 * Now we want to series of actions taken from the last few states to occur more often because we know it was "good"
	 * We now want to apply the reward received in state 15 to the actions taken in the last few steps
	 */

	for(int i=0;i<lastActions.size();i++){

		if(lastActions.size() == 1){
			factor = 1; //prevents division by 0
		}else{
			factor = ((float)i) / (lastActions.size() - 1); //the last one is the most "important" one
		}

		lastValue = states[lastActions[i].first].getValue(lastActions[i].second);

		//Apply all collected rewards, they can't be simply added up because then values greater than 1.0f would be possible
		for(int j=0;j<collectedRewards.size();j++){

			/* As currently we don't know more than that what we did in the last state and what the result is, we create a "connection" between the action and the reward
			 * If we receive a good reward (1.0f) the epsilonGreedy() function is more likely to select this action in exactly this state again
			 */
			lastValue = lastValue + (factor * VALUE_ADJUST_FRACTION) * (collectedRewards[j] - lastValue);
		}

		//TODO: can be optimized
		if(collectedRewards.size() == 0){
			/*
			 * If there was no reward we want to port the average value of the current state back
			 * in order to ensure it will occur more or less often. To do that, we simply converge all
			 * values of the previous [∆ - 2 - n] to the average of the last one [∆ - 1]
			 */
			lastValue = lastValue + ((factor * VALUE_ADJUST_FRACTION) * (states[lastActions[lastActions.size()-1].first].getAverageValue() - lastValue));
		}
		states[lastActions[i].first].setValue(lastActions[i].second, lastValue);

	}

	//then decide what action to take next
	Action* actionToTake = this->epsilonGreedy(states[currentStateIndex], EPSILON);

	//and the JUST DO IT
	actionToTake->run();

	lastActions.push_back(std::make_pair(currentStateIndex, actionToTake));

	if(lastActions.size() > STATES_TO_BACKPORT){
		for(int i=0;i<(lastActions.size() - STATES_TO_BACKPORT);i++){
			lastActions.pop_front();
		}
	}
}

unsigned Agent::seed(){
	return (unsigned) std::chrono::system_clock::now().time_since_epoch().count();
}

float Agent::randomFloatInRange(const float &min, const float &max){
	std::uniform_real_distribution<float>		distribution
	= std::uniform_real_distribution<float>(min, max);

	return distribution(generator);
}

int Agent::randomIntInRange(const int &min, const int &max){
	std::uniform_int_distribution<int>		distribution
		= std::uniform_int_distribution<int>(min, max);

	return distribution(generator);
}

/*Action Agent::softmax(State state, unsigned long temperature){

	std::vector<double> probabilities(states.size());
	float numerator, denominator;

	for(int i = 0;i<availableActions.size();i++){

	}

	for(int i=0;i<states.size();i++){

		probabilities[i] = 0;
	}
}*/

Action* Agent::epsilonGreedy(State state, const float &epsilon){
	if(epsilon < randomFloatInRange(0.0f, 1.0f)){
		//pick a greedy state
		return greedy(state);
	}else{
		//pick a random state
		return random(availableActions);
	}
}

Action* Agent::greedy(State state){
	float					maxValue = 0;
	float					tmpValue;
	std::vector<Action*>	maxActions;

	for(int i=0;i<availableActions.size();i++){
		tmpValue		= state.getValue(availableActions[i]);

		if(tmpValue > maxValue){
			maxValue = tmpValue;

			maxActions.clear();
			maxActions.push_back(availableActions[i]);
		}else if(tmpValue == maxValue){
			maxActions.push_back(availableActions[i]);
		}
	}

	if(maxActions.size() == 1){
		return maxActions[0];
	}else{
		return random(maxActions);
	}
}

Action* Agent::random(std::vector<Action*> availableActions){
	return availableActions[randomIntInRange(0, availableActions.size()-1)];
}

void Agent::savePoliciesToFile(){

	if(states.size() != 0){

		std::ofstream policies;
		policies.open("policies.csv");

		//Generate header
		policies << "POSITION_X;POSITION_Y;VELOCITY_X;VELOCITY_Y";
		for(int i=0;i<availableActions.size();i++){
			policies << ";ACTION_" << availableActions[i]->getUID();
		}
		policies << std::endl;

		//and the content in the same order

		for(int i=0;i<states.size();i++){
			policies << states[i].ballPosition.x << ";" << states[i].ballPosition.y << ";"
								<< states[i].ballVelocity.x << ";" << states[i].ballVelocity.y;

			for(int j=0;j<availableActions.size();j++){

				if(states[i].values.find(availableActions[j]) == states[i].values.end()){
					policies << ";" << Action::DEFAULT_REWARD;
					//printf("DEFAULT Value: %f\n", Action::DEFAULT_REWARD);
				}else{
					policies << ";" << (states[i].getValue(availableActions[j]));
					//printf("Value: %f\n", (states[i].getValue(availableActions[j])));
				}
			}

			policies << std::endl;
		}
	}
}

void Agent::loadPolicyFromFile(){
	std::string					line, header;
	std::ifstream				policies;
	std::vector<std::string>	partials;

	states.clear();

	printf("Reading and parsing policies.csv....\n");

	policies.open("policies.csv");

	if(std::getline(policies, header)){
		while (std::getline(policies, line)){

			b2Vec2	ballPosition;
			b2Vec2	ballVelocity;

			split(line, ';', partials);

			ballPosition.x		= stof(partials[0]);
			ballPosition.y		= stof(partials[1]);

			ballVelocity.x		= stof(partials[2]);
			ballVelocity.y		= stof(partials[3]);

			State state(ballPosition, ballVelocity);

			for(int i=0; i<availableActions.size(); i++){ //TODO check if the order in the header is the same as in available actions
				state.values[availableActions[i]] = stof(partials[4 + i]);
			}

			// push new state to states
			states.push_back(state);

			partials.clear();
		}
	}

	printf("Read and parsed policies.csv, %lu states were imported.\n", states.size());

	return;
}

std::vector<std::string> Agent::split(const std::string &s, char delim, std::vector<std::string> &elems) {
	std::stringstream ss(s);
	std::string item;
	while (std::getline(ss, item, delim)) {
		elems.push_back(item);
	}
	return elems;
}
<commit_msg>Commented line in<commit_after>/*
 * Agent.cpp
 *
 * The reinforcement learning agent: the core of the project
 */

#include <vector>
#include <chrono>
#include <math.h>
#include <stdio.h>
#include <fstream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iostream>

#include <Box2D/Box2D.h>

#include "Agent.h"
#include "State.h"
#include "../action/Action.h"

const int	Agent::STATES_TO_BACKPORT		= 50;

const float Agent::VALUE_ADJUST_FRACTION	= 0.35f;
const float Agent::EPSILON					= 0.15f;

Agent::Agent(std::vector<Action*> availableActions):
	availableActions(availableActions), generator(seed()){

	states.reserve(std::pow(9, 9));//reserves ≈ 400 MB RAM and prevents reallocations

	loadPolicyFromFile();
}

void Agent::think(State state, std::vector<float> collectedRewards){

	int		currentStateIndex	= 0;
	float	lastValue, factor;

	//first check whether this state already occured or not and retrieve the iterator
	std::vector<State>::iterator it = std::lower_bound(states.begin(), states.end(), state);
	currentStateIndex = (it - states.begin());

	if(currentStateIndex >= states.size() || states[currentStateIndex] != state){
		//If its a new state, add it at the *right* position to prevent another sort
		it = states.insert(it, state);

		//As we inserted an element we need to increase the index of all after the new one
		for(int i=0;i<lastActions.size();i++){
			if(lastActions[i].first >= currentStateIndex){
				lastActions[i].first++;
			}
		}
	}

	/*
	 * Maybe (actually most of the time in a pinball game) the good/bad reward isn't simply caused by the last action taken
	 * A series of actions and event have lead to this specific situation, so we need to apply the reward received for the last action
	 * to the last state in general, in other words to every possible action
	 *
	 * Example:
	 * State 0:		Action: EnableFlipperLeft		Reward:	0.0f	Cause: Ball leaves the CF in the direction of a pin
	 * State 10:	Action: DisableFlipperRight		Reward: 0.0f	Cause: Nothing, ball is still travelling in the direction of the pin
	 * State 15:	Action: DisableFlipperRight		Reward: 1.0f	Cause: Nothing BUT the ball kicked in state 0 hits the pin and causes a reward of 1.0f
	 *
	 * Now we want to series of actions taken from the last few states to occur more often because we know it was "good"
	 * We now want to apply the reward received in state 15 to the actions taken in the last few steps
	 */

	for(int i=0;i<lastActions.size();i++){

		if(lastActions.size() == 1){
			factor = 1; //prevents division by 0
		}else{
			factor = ((float)i) / (lastActions.size() - 1); //the last one is the most "important" one
		}

		lastValue = states[lastActions[i].first].getValue(lastActions[i].second);

		//Apply all collected rewards, they can't be simply added up because then values greater than 1.0f would be possible
		for(int j=0;j<collectedRewards.size();j++){

			/* As currently we don't know more than that what we did in the last state and what the result is, we create a "connection" between the action and the reward
			 * If we receive a good reward (1.0f) the epsilonGreedy() function is more likely to select this action in exactly this state again
			 */
			lastValue = lastValue + (factor * VALUE_ADJUST_FRACTION) * (collectedRewards[j] - lastValue);
		}

		//TODO: can be optimized
		if(collectedRewards.size() == 0){
			/*
			 * If there was no reward we want to port the average value of the current state back
			 * in order to ensure it will occur more or less often. To do that, we simply converge all
			 * values of the previous [∆ - 2 - n] to the average of the last one [∆ - 1]
			 */
			lastValue = lastValue + ((factor * VALUE_ADJUST_FRACTION) * (states[lastActions[lastActions.size()-1].first].getAverageValue() - lastValue));
		}
		states[lastActions[i].first].setValue(lastActions[i].second, lastValue);

	}

	//then decide what action to take next
	Action* actionToTake = this->epsilonGreedy(states[currentStateIndex], EPSILON);

	//and the JUST DO IT
	actionToTake->run();

	lastActions.push_back(std::make_pair(currentStateIndex, actionToTake));

	if(lastActions.size() > STATES_TO_BACKPORT){
		for(int i=0;i<(lastActions.size() - STATES_TO_BACKPORT);i++){
			lastActions.pop_front();
		}
	}
}

unsigned Agent::seed(){
	return (unsigned) std::chrono::system_clock::now().time_since_epoch().count();
}

float Agent::randomFloatInRange(const float &min, const float &max){
	std::uniform_real_distribution<float>		distribution
	= std::uniform_real_distribution<float>(min, max);

	return distribution(generator);
}

int Agent::randomIntInRange(const int &min, const int &max){
	std::uniform_int_distribution<int>		distribution
		= std::uniform_int_distribution<int>(min, max);

	return distribution(generator);
}

/*Action Agent::softmax(State state, unsigned long temperature){

	std::vector<double> probabilities(states.size());
	float numerator, denominator;

	for(int i = 0;i<availableActions.size();i++){

	}

	for(int i=0;i<states.size();i++){

		probabilities[i] = 0;
	}
}*/

Action* Agent::epsilonGreedy(State state, const float &epsilon){
	if(epsilon < randomFloatInRange(0.0f, 1.0f)){
		//pick a greedy state
		return greedy(state);
	}else{
		//pick a random state
		return random(availableActions);
	}
}

Action* Agent::greedy(State state){
	float					maxValue = 0;
	float					tmpValue;
	std::vector<Action*>	maxActions;

	for(int i=0;i<availableActions.size();i++){
		tmpValue		= state.getValue(availableActions[i]);

		if(tmpValue > maxValue){
			maxValue = tmpValue;

			maxActions.clear();
			maxActions.push_back(availableActions[i]);
		}else if(tmpValue == maxValue){
			maxActions.push_back(availableActions[i]);
		}
	}

	if(maxActions.size() == 1){
		return maxActions[0];
	}else{
		return random(maxActions);
	}
}

Action* Agent::random(std::vector<Action*> availableActions){
	return availableActions[randomIntInRange(0, availableActions.size()-1)];
}

void Agent::savePoliciesToFile(){

	if(states.size() != 0){

		std::ofstream policies;
		policies.open("policies.csv");

		//Generate header
		policies << "POSITION_X;POSITION_Y;VELOCITY_X;VELOCITY_Y";
		for(int i=0;i<availableActions.size();i++){
			policies << ";ACTION_" << availableActions[i]->getUID();
		}
		policies << std::endl;

		//and the content in the same order

		for(int i=0;i<states.size();i++){
			policies << states[i].ballPosition.x << ";" << states[i].ballPosition.y << ";"
								<< states[i].ballVelocity.x << ";" << states[i].ballVelocity.y;

			for(int j=0;j<availableActions.size();j++){

				if(states[i].values.find(availableActions[j]) == states[i].values.end()){
					policies << ";" << Action::DEFAULT_REWARD;
					//printf("DEFAULT Value: %f\n", Action::DEFAULT_REWARD);
				}else{
					policies << ";" << (states[i].getValue(availableActions[j]));
					//printf("Value: %f\n", (states[i].getValue(availableActions[j])));
				}
			}

			policies << std::endl;
		}
	}
}

void Agent::loadPolicyFromFile(){
	std::string					line, header;
	std::ifstream				policies;
	std::vector<std::string>	partials;

	states.clear();

	printf("Reading and parsing policies.csv....\n");

	policies.open("policies.csv");

	if(std::getline(policies, header)){
		while (std::getline(policies, line)){

			b2Vec2	ballPosition;
			b2Vec2	ballVelocity;

			split(line, ';', partials);

			ballPosition.x		= stof(partials[0]);
			ballPosition.y		= stof(partials[1]);

			ballVelocity.x		= stof(partials[2]);
			ballVelocity.y		= stof(partials[3]);

			State state(ballPosition, ballVelocity);

			for(int i=0; i<availableActions.size(); i++){ //TODO check if the order in the header is the same as in available actions
				state.values[availableActions[i]] = stof(partials[4 + i]);
			}

			// push new state to states
			states.push_back(state);

			partials.clear();
		}
	}

	printf("Read and parsed policies.csv, %lu states were imported.\n", states.size());

	return;
}

std::vector<std::string> Agent::split(const std::string &s, char delim, std::vector<std::string> &elems) {
	std::stringstream ss(s);
	std::string item;
	while (std::getline(ss, item, delim)) {
		elems.push_back(item);
	}
	return elems;
}
<|endoftext|>


<commit_before>#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <sys/farptr.h>
#include <dpmi.h>
#include <go32.h>
#include <pc.h>
#include <bios.h>
#include <time.h>
#include <unistd.h>
#include <iterator>
#include <string>
#include <vector>
#include <array>
#include <memory>

#include "OPL2.h"
#include "controller.h"

#define STR(x) #x
#define XSTR(x) STR(x)

bool enableOPL2 = false;
extern OPL2 opl2;
std::vector<int> noSound;
std::vector<int> melody;
std::vector<int>::const_iterator currentSoundPosition;
int currentNote = 0;
std::string buffer[3];

short get_lpt_port(int i) {
    return _farpeekw(_dos_ds, 0x0408 + (2 * (i - 1)));
}

short setup(void) {
    cputs("OPT2LPT setup\r\n\r\n");

    char num_ports, port, i;

    num_ports = 0;
    for (i = 1; i < 4; i++) {
        if (get_lpt_port(i)) {
            num_ports++;
            port = i;
        }
    }

    if (num_ports == 0) {
        cputs("Sorry, no printer port found...\r\n");
        exit(1);
    } else if (num_ports == 1) {
        cprintf("Found one printer port: LPT%d\r\n", port);
        return get_lpt_port(port);
    } else {
        cputs("Found multiple printer ports:");
        for (i = 1; i < 4; i++) {
            if (get_lpt_port(i)) {
                cprintf(" LPT%d", i);
            }
        }
        cputs("\r\nWhich one is the OPT2LPT connected to? [");
        for (i = 1; i < 4; i++) {
            if (get_lpt_port(i)) {
                cprintf("%d", i);
            }
        }
        cputs("]? ");
        do {
            port = getch() - '0';
        } while (port < 1 || port > 3 || !get_lpt_port(port));
        cprintf("LPT%d\r\n", port);
        return get_lpt_port(port);
    }
    return 0;
}

void playSound(const std::vector<int> &sound) {

    if ( sound.empty() ) {
        melody.clear();
        return;
    }

    melody = sound;
    currentSoundPosition = std::begin(melody);
}

void playMusic(const std::string &music) {
    if (enableOPL2) {
        if (music.empty()) {
            music_set("", "", "");
            return;
        }
        auto melody1 = music.substr(0, music.find(';'));
        auto melody2 = music.substr( music.find(';') + 1 );
        auto melody3 = melody2.substr( melody2.find(';') + 1 );
        melody2 = melody2.substr(0, melody2.find(';'));
        buffer[0] = melody1;
        buffer[1] = melody2;
        buffer[2] = melody3;
        music_set(buffer[0].c_str(), buffer[1].c_str(), buffer[2].c_str());
        return;
    }

    int frequency = 0;
    melody.clear();
    for (const auto &note : music) {
        switch (note) {
            case 'a':
            case 'A':
                frequency = 932;
                break;
            case 'B':
            case 'b':
                frequency = 988;
                break;
            case 'C':
            case 'c':
                frequency = 1109;
                break;
            case 'D':
            case 'd':
                frequency = 1175;
                break;
            case 'E':
            case 'e':
                frequency = 1318;
                break;
            case 'F':
            case 'f':
                frequency = 1397;
                break;
            case 'G':
            case 'g':
                frequency = 1568;
                break;
            case ';':
                melody.clear();
                continue;
        }
        melody.push_back(frequency);
    }
    playSound(melody);
}

void muteSound() {
    if ( !enableOPL2 ) {
        nosound();
        melody.clear();
        currentNote = 0;
    } else {
        playMusic("");
    }
}

void playTune(const std::string &music) {
    buffer[0] = music + ";" + music + ";" + music;
    hackTune( music.c_str() );
}

void setupOPL2() {
    short lpt_base = setup();
    opl2.init(lpt_base);
    music_setup();
    enableOPL2 = true;
}

void soundFrequency(int frequency) {
    if (!enableOPL2) {
        if (frequency != 0 && currentNote != frequency ) {
            sound( frequency );
            currentNote = frequency;
        }
    }
}

void soundTick() {
    if (enableOPL2) {
        music_loop();
    } else {
        if (melody.empty()) {
            return;
        }

        if (currentSoundPosition != std::end(melody)) {
            soundFrequency(*currentSoundPosition);
            currentSoundPosition = std::next(currentSoundPosition);
        } else {
            muteSound();
            melody.clear();
        }
    }
}

void stopSounds() {
    if (enableOPL2) {
        music_shutdown();
    } else {
        muteSound();
    }
}
<commit_msg>Replace STL vector and array with EASTL versions in music module<commit_after>#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <sys/farptr.h>
#include <dpmi.h>
#include <go32.h>
#include <pc.h>
#include <bios.h>
#include <time.h>
#include <unistd.h>
#include <iterator>
#include <string>
#include <memory>
#include <EASTL/vector.h>
#include <EASTL/array.h>

using eastl::vector;
using eastl::array;

#include "OPL2.h"
#include "controller.h"

#define STR(x) #x
#define XSTR(x) STR(x)

bool enableOPL2 = false;
extern OPL2 opl2;
std::vector<int> noSound;
std::vector<int> melody;
std::vector<int>::const_iterator currentSoundPosition;
int currentNote = 0;
std::string buffer[3];

short get_lpt_port(int i) {
    return _farpeekw(_dos_ds, 0x0408 + (2 * (i - 1)));
}

short setup(void) {
    cputs("OPT2LPT setup\r\n\r\n");

    char num_ports, port, i;

    num_ports = 0;
    for (i = 1; i < 4; i++) {
        if (get_lpt_port(i)) {
            num_ports++;
            port = i;
        }
    }

    if (num_ports == 0) {
        cputs("Sorry, no printer port found...\r\n");
        exit(1);
    } else if (num_ports == 1) {
        cprintf("Found one printer port: LPT%d\r\n", port);
        return get_lpt_port(port);
    } else {
        cputs("Found multiple printer ports:");
        for (i = 1; i < 4; i++) {
            if (get_lpt_port(i)) {
                cprintf(" LPT%d", i);
            }
        }
        cputs("\r\nWhich one is the OPT2LPT connected to? [");
        for (i = 1; i < 4; i++) {
            if (get_lpt_port(i)) {
                cprintf("%d", i);
            }
        }
        cputs("]? ");
        do {
            port = getch() - '0';
        } while (port < 1 || port > 3 || !get_lpt_port(port));
        cprintf("LPT%d\r\n", port);
        return get_lpt_port(port);
    }
    return 0;
}

void playSound(const std::vector<int> &sound) {

    if ( sound.empty() ) {
        melody.clear();
        return;
    }

    melody = sound;
    currentSoundPosition = std::begin(melody);
}

void playMusic(const std::string &music) {
    if (enableOPL2) {
        if (music.empty()) {
            music_set("", "", "");
            return;
        }
        auto melody1 = music.substr(0, music.find(';'));
        auto melody2 = music.substr( music.find(';') + 1 );
        auto melody3 = melody2.substr( melody2.find(';') + 1 );
        melody2 = melody2.substr(0, melody2.find(';'));
        buffer[0] = melody1;
        buffer[1] = melody2;
        buffer[2] = melody3;
        music_set(buffer[0].c_str(), buffer[1].c_str(), buffer[2].c_str());
        return;
    }

    int frequency = 0;
    melody.clear();
    for (const auto &note : music) {
        switch (note) {
            case 'a':
            case 'A':
                frequency = 932;
                break;
            case 'B':
            case 'b':
                frequency = 988;
                break;
            case 'C':
            case 'c':
                frequency = 1109;
                break;
            case 'D':
            case 'd':
                frequency = 1175;
                break;
            case 'E':
            case 'e':
                frequency = 1318;
                break;
            case 'F':
            case 'f':
                frequency = 1397;
                break;
            case 'G':
            case 'g':
                frequency = 1568;
                break;
            case ';':
                melody.clear();
                continue;
        }
        melody.push_back(frequency);
    }
    playSound(melody);
}

void muteSound() {
    if ( !enableOPL2 ) {
        nosound();
        melody.clear();
        currentNote = 0;
    } else {
        playMusic("");
    }
}

void playTune(const std::string &music) {
    buffer[0] = music + ";" + music + ";" + music;
    hackTune( music.c_str() );
}

void setupOPL2() {
    short lpt_base = setup();
    opl2.init(lpt_base);
    music_setup();
    enableOPL2 = true;
}

void soundFrequency(int frequency) {
    if (!enableOPL2) {
        if (frequency != 0 && currentNote != frequency ) {
            sound( frequency );
            currentNote = frequency;
        }
    }
}

void soundTick() {
    if (enableOPL2) {
        music_loop();
    } else {
        if (melody.empty()) {
            return;
        }

        if (currentSoundPosition != std::end(melody)) {
            soundFrequency(*currentSoundPosition);
            currentSoundPosition = std::next(currentSoundPosition);
        } else {
            muteSound();
            melody.clear();
        }
    }
}

void stopSounds() {
    if (enableOPL2) {
        music_shutdown();
    } else {
        muteSound();
    }
}
<|endoftext|>


<commit_before>#ifndef _sbl_flow
#define _sbl_flow
#include<map>
#include<ostream>
#include"adjacency_list.hpp"
#include"shortest_path_tree.hpp"
#include"../utility/type_traits.hpp"
#include"../utility/foreach.hpp"
#include"../base.hpp"

namespace sbl {

template<class GetCapacity, class GetFlow, class SetFlow>
class MaxFlow {
    private:
        GetCapacity old_get_capacity;
        GetFlow     old_get_flow;
        SetFlow     old_set_flow;

        // a new graph represent the residual network
        // we will split every directed edge to
        // two new edge with opposite direction.
        AdjacencyList graph;

        // mapping residual network's edge to origin edge
        std::map<size_t, size_t> newToOldIndex;

    public:
        template<class Graph>
        MaxFlow(
            Graph input_graph,
            GetCapacity input_get_capacity,
            GetFlow input_get_flow,
            SetFlow input_set_flow
        ):
            old_get_capacity(input_get_capacity),
            old_get_flow(input_get_flow),
            old_set_flow(input_set_flow) {

            // build residual network
            size_t nodeCount = input_graph.number_of_nodes();
            for (size_t head = 0; head < nodeCount; head++) {
                foredge(input_graph, head, tail, oldEdge) {

                    // split oldEdge to two edges with opposite direction
                    // (edge) and (edge^1), should be paired.

                    // we call this "positive direction edge", PDE
                    newToOldIndex[graph.add_edge(head, tail)] = oldEdge;

                    // we call this "negaitive direction edge", NDE
                    newToOldIndex[graph.add_edge(tail, head)] = oldEdge;
                }
            }

            //PDE and NDE should have same capacity. flow in PDE plus NDE
            //should always equal to the capacity.
            //
            //for example, in the origin graph (old graph), we have 0 --> 1
            //with 9 capacity, then if flow in 0 --> 1 is 0, for convenience we
            //let flow in 1 --> 0 be 9. if flow in 0 --> 1 is 2 then flow in
            //0 --> 1 is 9-2=7. Now any path without zero residual capacity in
            //residual network, we could find a augmenting path in origin flow
            //network to match it. Then it is possible to reuse shortest_path.

        }
    private:

        static bool is_positive_direction_edge(size_t edge) {
            return edge % 2 == 0;
        }

        static bool is_negative_direction_edge(size_t edge) {
            return not is_positive_direction_edge(edge);
        }

        typedef typename result_of<GetCapacity(size_t)>::type ResultOfGetCapacity;
        typedef typename result_of<GetFlow(size_t)>::type ResultOfGetFlow;

        ResultOfGetCapacity get_capacity(size_t edge) const {
            assert(newToOldIndex.count(edge));
            size_t oldEdge = newToOldIndex.find(edge)->second;
            return old_get_capacity(oldEdge);
        }

        ResultOfGetFlow get_flow(size_t edge) const {
            assert(newToOldIndex.count(edge));
            size_t oldEdge = newToOldIndex.find(edge)->second;
            if (is_positive_direction_edge(edge))
                return old_get_flow(oldEdge);
            else
                return old_get_capacity(oldEdge) - old_get_flow(oldEdge);
        }

        ResultOfGetFlow residual_capacity(size_t edge) const {
            return get_capacity(edge) - get_flow(edge);
        }
        void set_flow(size_t edge, ResultOfGetFlow newFlow) {
            assert(newToOldIndex.count(edge));
            size_t oldEdge = newToOldIndex[edge];

            if (is_positive_direction_edge(edge))
                old_set_flow(oldEdge, newFlow);
            else
                old_set_flow(oldEdge, old_get_capacity(oldEdge) - newFlow);
            assert(get_flow(edge) == newFlow);
        }

        template<class Weight>
        struct Cost {
            Weight weight;
            bool isPositive;
            bool isFinite;

            Cost(): weight(), isPositive(true), isFinite(true) {}

            friend Cost operator+(Cost lhs, Cost rhs) {
                if (not lhs.isFinite) return lhs;
                if (not rhs.isFinite) return rhs;

                if (lhs.weight < rhs.weight)
                    std::swap(lhs, rhs);

                if (lhs.isPositive == rhs.isPositive)
                    lhs.weight += rhs.weight;
                else {
                    if (lhs.weight == rhs.weight)
                        lhs.isPositive = true;
                    lhs.weight -= rhs.weight;
                }

                return lhs;
            }

            friend bool operator<(Cost lhs, Cost rhs) {

                if (lhs.isPositive and not rhs.isPositive)
                    return false;

                if (not lhs.isPositive and rhs.isPositive)
                    return true;

                if (not lhs.isFinite)
                    return not lhs.isPositive;

                if (not rhs.isFinite)
                    return rhs.isPositive;

                if (lhs.isPositive)
                    return lhs.weight < rhs.weight;
                else
                    return rhs.weight < lhs.weight;

            }

            friend std::ostream& operator<<(std::ostream& os, Cost cost) {
                if(not cost.isPositive)
                    os << "-";
                if(cost.isFinite)
                    os << cost.weight;
                else
                    os << "infinity";
                return os;
            }

        };

        template<class Self, class GetWeight>
        class GetCost {
            private:
                const Self &self;
                const GetWeight &getWeight;
                typedef typename result_of<GetWeight(size_t)>::type Weight;
                typedef Cost<Weight> CostType;

            public:
                CostType operator()(size_t edge) const {
                    assert(self.get_capacity(edge) >= self.get_flow(edge));
                    CostType result;
                    result.isFinite = self.residual_capacity(edge) > 0;
                    if (result.isFinite) {
                        size_t oldEdge = self.newToOldIndex.find(edge)->second;
                        result.weight = getWeight(oldEdge);
                        result.isPositive = is_positive_direction_edge(edge);
                    }
                    return result;
                }
                GetCost(const Self &iSelf, const GetWeight &iGetWeight)
                    : self(iSelf), getWeight(iGetWeight) {}
        }; // struct GetCost

        struct AlwaysOne {
            size_t operator()(size_t)const {
                return 1;
            }
        };

        /// @brief change the flow by a augmenting path
        template<class ShortestPathTree>
        void change_flows(
            size_t source,
            size_t target,
            const ShortestPathTree &tree,
            ResultOfGetFlow *expandFlow
        ) {
            // backtrack to the source
            if (source == target)
                return;
            size_t last = tree.get_father(target);
            AUTO(edges, graph.find_edges(last, target));
            ResultOfGetFlow all = 0;
            foreach(edge, edges) {
                all += residual_capacity(edge);
            }
            *expandFlow = std::min(*expandFlow, all);

            change_flows(source, last, tree, expandFlow);

            // change the flow
            AUTO(k, *expandFlow);
            foreach(edge, edges) {
                AUTO(p, std::min(k, residual_capacity(edge)));
                set_flow(edge, p + get_flow(edge));
                assert(k >= p);
                k -= p;
            }
            assert(k == 0);
        }

    public:

        template<class GetWeight>
        ResultOfGetFlow run(
            size_t source,
            size_t target,
            const GetWeight &getWeight
        ) {
            // Edmonds-Karp algorithm
            ResultOfGetFlow result, expandFlow;
            do {
                expandFlow = std::numeric_limits<ResultOfGetFlow>::max();
                AUTO(get_cost, MAKE2(GetCost, *this, getWeight));
                AUTO(weightedGraph, MAKE2(
                         WeightedGraphWrapper,
                         graph,
                         get_cost
                     ));
                AUTO(tree, MAKE1(ShortestPathTree, weightedGraph));
                tree.run(source, target, true);
                change_flows(source, target, tree, &expandFlow);
                result += expandFlow;
            } while (expandFlow > 0);
            return result;
        }

        ResultOfGetFlow run(
            size_t source,
            size_t target
        ) {
            return run(source, target, AlwaysOne());
        }

}; // struct MaxFlow

/// @brief calculate the max flow of current flow network
///
/// Actually, this is just a wrapper for MaxFlow.
template<class Graph, class GetCapacity, class GetFlow, class SetFlow>
void max_flow(
    Graph input_graph,              ///< any sbl's graph
    GetCapacity input_get_capacity, ///< a functor to get the capacity
    GetFlow input_get_flow,         ///< a functor to get the current flow
    SetFlow input_set_flow,         ///< a functor to change the flow
    typename Graph::Node source,    ///< node represent source
    typename Graph::Node target     ///< node represent sink/target
) {
    MaxFlow<GetCapacity, GetFlow, SetFlow>
    main(input_graph, input_get_capacity, input_get_flow, input_set_flow);
    main.run(source, target);
}

template<class Graph, class GetCapacity, class GetFlow, class SetFlow, class GetCost>
void minimum_cost_flow(
    Graph input_graph,              ///< any sbl's graph
    GetCapacity input_get_capacity, ///< a functor to get the capacity
    GetFlow input_get_flow,         ///< a functor to get the current flow
    SetFlow input_set_flow,         ///< a functor to change the flow
    GetCost input_get_cost,         ///< a functor to get the cost
    typename Graph::Node source,    ///< node represent source
    typename Graph::Node target     ///< node represent sink/target
) {
    MaxFlow<GetCapacity, GetFlow, SetFlow>
    main(input_graph, input_get_capacity, input_get_flow, input_set_flow);
    main.run(source, target, input_get_cost);
}

} // namespace sbl

#endif
<commit_msg>add MaxFlow::get_old_edge, maybe we could drop std::map in the future<commit_after>#ifndef _sbl_flow
#define _sbl_flow
#include<map>
#include<ostream>
#include"adjacency_list.hpp"
#include"shortest_path_tree.hpp"
#include"../utility/type_traits.hpp"
#include"../utility/foreach.hpp"
#include"../base.hpp"

namespace sbl {

template<class GetCapacity, class GetFlow, class SetFlow>
class MaxFlow {
    private:
        GetCapacity old_get_capacity;
        GetFlow     old_get_flow;
        SetFlow     old_set_flow;

        // a new graph represent the residual network
        // we will split every directed edge to
        // two new edge with opposite direction.
        AdjacencyList graph;

        // mapping residual network's edge to origin edge
        // XXX: std::map is not necessary, it could be calcuated directly
        std::map<size_t, size_t> newToOldIndex;

    public:
        template<class Graph>
        MaxFlow(
            Graph input_graph,
            GetCapacity input_get_capacity,
            GetFlow input_get_flow,
            SetFlow input_set_flow
        ):
            old_get_capacity(input_get_capacity),
            old_get_flow(input_get_flow),
            old_set_flow(input_set_flow) {

            // build residual network
            size_t nodeCount = input_graph.number_of_nodes();
            for (size_t head = 0; head < nodeCount; head++) {
                foredge(input_graph, head, tail, oldEdge) {

                    // split oldEdge to two edges with opposite direction
                    // (edge) and (edge^1), should be paired.

                    // we call this "positive direction edge", PDE
                    newToOldIndex[graph.add_edge(head, tail)] = oldEdge;

                    // we call this "negaitive direction edge", NDE
                    newToOldIndex[graph.add_edge(tail, head)] = oldEdge;
                }
            }

            //PDE and NDE should have same capacity. flow in PDE plus NDE
            //should always equal to the capacity.
            //
            //for example, in the origin graph (old graph), we have 0 --> 1
            //with 9 capacity, then if flow in 0 --> 1 is 0, for convenience we
            //let flow in 1 --> 0 be 9. if flow in 0 --> 1 is 2 then flow in
            //0 --> 1 is 9-2=7. Now any path without zero residual capacity in
            //residual network, we could find a augmenting path in origin flow
            //network to match it. Then it is possible to reuse shortest_path.

        }
    private:

        size_t get_old_edge(size_t edge) const {
            assert(newToOldIndex.count(edge));
            return newToOldIndex.find(edge)->second;
        }

        static inline bool is_positive_direction_edge(size_t edge) {
            return edge % 2 == 0;
        }

        static inline bool is_negative_direction_edge(size_t edge) {
            return not is_positive_direction_edge(edge);
        }

        typedef typename result_of<GetCapacity(size_t)>::type ResultOfGetCapacity;
        typedef typename result_of<GetFlow(size_t)>::type ResultOfGetFlow;

        ResultOfGetCapacity get_capacity(size_t edge) const {
            return old_get_capacity(get_old_edge(edge));
        }

        ResultOfGetFlow get_flow(size_t edge) const {
            size_t oldEdge = get_old_edge(edge);
            if (is_positive_direction_edge(edge))
                return old_get_flow(oldEdge);
            else
                return old_get_capacity(oldEdge) - old_get_flow(oldEdge);
        }

        ResultOfGetFlow residual_capacity(size_t edge) const {
            return get_capacity(edge) - get_flow(edge);
        }
        void set_flow(size_t edge, ResultOfGetFlow newFlow) {
            size_t oldEdge = get_old_edge(edge);

            if (is_positive_direction_edge(edge))
                old_set_flow(oldEdge, newFlow);
            else
                old_set_flow(oldEdge, old_get_capacity(oldEdge) - newFlow);
            assert(get_flow(edge) == newFlow);
        }

        template<class Weight>
        struct Cost {
            Weight weight;
            bool isPositive;
            bool isFinite;

            Cost(): weight(), isPositive(true), isFinite(true) {}

            friend Cost operator+(Cost lhs, Cost rhs) {
                if (not lhs.isFinite) return lhs;
                if (not rhs.isFinite) return rhs;

                if (lhs.weight < rhs.weight)
                    std::swap(lhs, rhs);

                if (lhs.isPositive == rhs.isPositive)
                    lhs.weight += rhs.weight;
                else {
                    if (lhs.weight == rhs.weight)
                        lhs.isPositive = true;
                    lhs.weight -= rhs.weight;
                }

                return lhs;
            }

            friend bool operator<(Cost lhs, Cost rhs) {

                if (lhs.isPositive and not rhs.isPositive)
                    return false;

                if (not lhs.isPositive and rhs.isPositive)
                    return true;

                if (not lhs.isFinite)
                    return not lhs.isPositive;

                if (not rhs.isFinite)
                    return rhs.isPositive;

                if (lhs.isPositive)
                    return lhs.weight < rhs.weight;
                else
                    return rhs.weight < lhs.weight;

            }

            friend std::ostream& operator<<(std::ostream& os, Cost cost) {
                if(not cost.isPositive)
                    os << "-";
                if(cost.isFinite)
                    os << cost.weight;
                else
                    os << "infinity";
                return os;
            }

        };

        template<class Self, class GetWeight>
        class GetCost {
            private:
                const Self &self;
                const GetWeight &getWeight;
                typedef typename result_of<GetWeight(size_t)>::type Weight;
                typedef Cost<Weight> CostType;

            public:
                CostType operator()(size_t edge) const {
                    assert(self.get_capacity(edge) >= self.get_flow(edge));
                    CostType result;
                    result.isFinite = self.residual_capacity(edge) > 0;
                    if (result.isFinite) {
                        size_t oldEdge = self.get_old_edge(edge);
                        result.weight = getWeight(oldEdge);
                        result.isPositive = is_positive_direction_edge(edge);
                    }
                    return result;
                }
                GetCost(const Self &iSelf, const GetWeight &iGetWeight)
                    : self(iSelf), getWeight(iGetWeight) {}
        }; // struct GetCost

        struct AlwaysOne {
            size_t operator()(size_t)const {
                return 1;
            }
        };

        /// @brief change the flow by a augmenting path
        template<class ShortestPathTree>
        void change_flows(
            size_t source,
            size_t target,
            const ShortestPathTree &tree,
            ResultOfGetFlow *expandFlow
        ) {
            // backtrack to the source
            if (source == target)
                return;
            size_t last = tree.get_father(target);
            AUTO(edges, graph.find_edges(last, target));
            ResultOfGetFlow all = 0;
            foreach(edge, edges) {
                all += residual_capacity(edge);
            }
            *expandFlow = std::min(*expandFlow, all);

            change_flows(source, last, tree, expandFlow);

            // change the flow
            AUTO(k, *expandFlow);
            foreach(edge, edges) {
                AUTO(p, std::min(k, residual_capacity(edge)));
                set_flow(edge, p + get_flow(edge));
                assert(k >= p);
                k -= p;
            }
            assert(k == 0);
        }

    public:

        template<class GetWeight>
        ResultOfGetFlow run(
            size_t source,
            size_t target,
            const GetWeight &getWeight
        ) {
            // Edmonds-Karp algorithm
            ResultOfGetFlow result, expandFlow;
            do {
                expandFlow = std::numeric_limits<ResultOfGetFlow>::max();
                AUTO(get_cost, MAKE2(GetCost, *this, getWeight));
                AUTO(weightedGraph, MAKE2(
                         WeightedGraphWrapper,
                         graph,
                         get_cost
                     ));
                AUTO(tree, MAKE1(ShortestPathTree, weightedGraph));
                tree.run(source, target, true);
                change_flows(source, target, tree, &expandFlow);
                result += expandFlow;
            } while (expandFlow > 0);
            return result;
        }

        ResultOfGetFlow run(
            size_t source,
            size_t target
        ) {
            return run(source, target, AlwaysOne());
        }

}; // struct MaxFlow

/// @brief calculate the max flow of current flow network
///
/// Actually, this is just a wrapper for MaxFlow.
template<class Graph, class GetCapacity, class GetFlow, class SetFlow>
void max_flow(
    Graph input_graph,              ///< any sbl's graph
    GetCapacity input_get_capacity, ///< a functor to get the capacity
    GetFlow input_get_flow,         ///< a functor to get the current flow
    SetFlow input_set_flow,         ///< a functor to change the flow
    typename Graph::Node source,    ///< node represent source
    typename Graph::Node target     ///< node represent sink/target
) {
    MaxFlow<GetCapacity, GetFlow, SetFlow>
    main(input_graph, input_get_capacity, input_get_flow, input_set_flow);
    main.run(source, target);
}

template<class Graph, class GetCapacity, class GetFlow, class SetFlow, class GetCost>
void minimum_cost_flow(
    Graph input_graph,              ///< any sbl's graph
    GetCapacity input_get_capacity, ///< a functor to get the capacity
    GetFlow input_get_flow,         ///< a functor to get the current flow
    SetFlow input_set_flow,         ///< a functor to change the flow
    GetCost input_get_cost,         ///< a functor to get the cost
    typename Graph::Node source,    ///< node represent source
    typename Graph::Node target     ///< node represent sink/target
) {
    MaxFlow<GetCapacity, GetFlow, SetFlow>
    main(input_graph, input_get_capacity, input_get_flow, input_set_flow);
    main.run(source, target, input_get_cost);
}

} // namespace sbl

#endif
<|endoftext|>


<commit_before>/*
* Copyright (C) 2008-2013 The Communi Project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

#include "application.h"
#include "settingswizard.h"
#include "connectioninfo.h"
#include "settingsmodel.h"
#include "sharedtimer.h"
#include <QDesktopServices>
#include <QMessageBox>
#include <QSettings>
#include <QDebug>
#include <QIcon>
#include <QFile>
#include <Irc>

QByteArray Application::Private::encoding("ISO-8859-15");

Application::Application(int& argc, char* argv[]) : QApplication(argc, argv)
{
    setApplicationName("Communi");
    setOrganizationName("Communi");
    setApplicationVersion(Irc::version());

    QIcon icon;
    icon.addFile(":/resources/icons/16x16/communi.png");
    icon.addFile(":/resources/icons/24x24/communi.png");
    icon.addFile(":/resources/icons/32x32/communi.png");
    icon.addFile(":/resources/icons/48x48/communi.png");
    icon.addFile(":/resources/icons/64x64/communi.png");
    icon.addFile(":/resources/icons/128x128/communi.png");
    setWindowIcon(icon);

    qRegisterMetaTypeStreamOperators<ConnectionInfo>("ConnectionInfo");
    qRegisterMetaTypeStreamOperators<ConnectionInfos>("ConnectionInfos");

    QSettings settings;
    if (arguments().contains("-reset"))
        settings.clear();

    if (settings.contains("settings")) {
        QVariant value = settings.value("settings");
        if (value.canConvert<QVariantMap>())
            Application::settings()->setValues(value.toMap());
    }

    QFile file(":resources/stylesheet.css");
    if (file.open(QFile::ReadOnly | QIODevice::Text))
        setStyleSheet(QString::fromUtf8(file.readAll()));

    QDir dir = dataDir();
    if (dir.exists() || dir.mkpath(".")) {
        QString filePath = dir.filePath("notify.mp3");
        if (!QFile::exists(filePath))
            QFile::copy(":/resources/notify.mp3", filePath);
    }
}

Application::~Application()
{
    QSettings settings;
    settings.setValue("settings", Application::settings()->values());
}

QString Application::applicationSlogan()
{
    return tr("%1 is a simple and light-weight cross-platform IRC client.").arg(applicationName());
}

QByteArray Application::encoding()
{
    return Private::encoding;
}

void Application::setEncoding(const QByteArray& encoding)
{
    Private::encoding = encoding;
}

SettingsModel* Application::settings()
{
    static SettingsModel model;
    if (model.rowCount() == 0)
        model.setValues(defaultSettings());
    return &model;
}

QVariantMap Application::defaultSettings()
{
    QVariantMap settings;

    settings["ui.font"] = QFont();
    settings["ui.theme"] = "light";
    settings["ui.scrollback"] = 0;

    settings["formatting.timeStamp"] = "[hh:mm:ss]";
    settings["formatting.hideUserHosts"] = false;

#ifdef Q_OS_MAC
    QString navigate("Ctrl+Alt+%1");
    QString nextActive("Shift+Ctrl+Alt+%1");
#else
    QString navigate("Alt+%1");
    QString nextActive("Shift+Alt+%1");
#endif

    settings["shortcuts.previousView"] = navigate.arg("Up");
    settings["shortcuts.nextView"] = navigate.arg("Down");
    settings["shortcuts.collapseView"] = navigate.arg("Left");
    settings["shortcuts.expandView"] = navigate.arg("Right");
    settings["shortcuts.previousActiveView"] = nextActive.arg("Up");
    settings["shortcuts.nextActiveView"] = nextActive.arg("Down");
    settings["shortcuts.mostActiveView"] = "Ctrl+L";
    settings["shortcuts.searchView"] = "Ctrl+S";

    // TODO:
//    settings["messages.joins"] = true;
//    settings["messages.parts"] = true;
//    settings["messages.nicks"] = true;
//    settings["messages.modes"] = true;
//    settings["messages.kicks"] = true;
//    settings["messages.quits"] = true;
//    settings["messages.topics"] = true;

    settings["themes.light.background"] = QColor("#ffffff");
    settings["themes.light.message"] = QColor("#000000");
    settings["themes.light.event"] = QColor("#808080");
    settings["themes.light.notice"] = QColor("#a54242");
    settings["themes.light.action"] = QColor("#8b388b");
    settings["themes.light.highlight"] = QColor("#ff4040");
    settings["themes.light.timestamp"] = QColor("#808080");
    settings["themes.light.link"] = QColor("#4040ff");

    settings["aliases.chanserv"] = "MSG ChanServ $*";
    settings["aliases.nickserv"] = "MSG NickServ $*";

    return settings;
}

QDir Application::dataDir()
{
    return QDir(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
}

void Application::aboutApplication()
{
    QMessageBox::about(
#ifdef Q_WS_MAC
        0,
#else
        activeWindow(),
#endif // Q_WS_MAC
        applicationName(), QString(
            "
%1
"
            "
%2
"
            "
%3
"
            "
Copyright (C) 2008-2013 The Communi Project
")
        .arg(tr("About %1").arg(applicationName()))
        .arg(applicationSlogan())
        .arg(organizationDomain())
    );
}

void Application::showSettings()
{
    SettingsModel model;
    model.setValues(settings()->values());
    SettingsWizard wizard(&model, activeWindow());
    if (wizard.exec())
        settings()->setValues(model.values());
}
<commit_msg>Add -reset-settings/connections for convenience<commit_after>/*
* Copyright (C) 2008-2013 The Communi Project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

#include "application.h"
#include "settingswizard.h"
#include "connectioninfo.h"
#include "settingsmodel.h"
#include "sharedtimer.h"
#include <QDesktopServices>
#include <QMessageBox>
#include <QSettings>
#include <QDebug>
#include <QIcon>
#include <QFile>
#include <Irc>

QByteArray Application::Private::encoding("ISO-8859-15");

Application::Application(int& argc, char* argv[]) : QApplication(argc, argv)
{
    setApplicationName("Communi");
    setOrganizationName("Communi");
    setApplicationVersion(Irc::version());

    QIcon icon;
    icon.addFile(":/resources/icons/16x16/communi.png");
    icon.addFile(":/resources/icons/24x24/communi.png");
    icon.addFile(":/resources/icons/32x32/communi.png");
    icon.addFile(":/resources/icons/48x48/communi.png");
    icon.addFile(":/resources/icons/64x64/communi.png");
    icon.addFile(":/resources/icons/128x128/communi.png");
    setWindowIcon(icon);

    qRegisterMetaTypeStreamOperators<ConnectionInfo>("ConnectionInfo");
    qRegisterMetaTypeStreamOperators<ConnectionInfos>("ConnectionInfos");

    QSettings settings;
    if (arguments().contains("-reset"))
        settings.clear();
    if (arguments().contains("-reset-settings"))
        settings.remove("settings");
    if (arguments().contains("-reset-connections"))
        settings.remove("connections");

    if (settings.contains("settings")) {
        QVariant value = settings.value("settings");
        if (value.canConvert<QVariantMap>())
            Application::settings()->setValues(value.toMap());
    }

    QFile file(":resources/stylesheet.css");
    if (file.open(QFile::ReadOnly | QIODevice::Text))
        setStyleSheet(QString::fromUtf8(file.readAll()));

    QDir dir = dataDir();
    if (dir.exists() || dir.mkpath(".")) {
        QString filePath = dir.filePath("notify.mp3");
        if (!QFile::exists(filePath))
            QFile::copy(":/resources/notify.mp3", filePath);
    }
}

Application::~Application()
{
    QSettings settings;
    settings.setValue("settings", Application::settings()->values());
}

QString Application::applicationSlogan()
{
    return tr("%1 is a simple and light-weight cross-platform IRC client.").arg(applicationName());
}

QByteArray Application::encoding()
{
    return Private::encoding;
}

void Application::setEncoding(const QByteArray& encoding)
{
    Private::encoding = encoding;
}

SettingsModel* Application::settings()
{
    static SettingsModel model;
    if (model.rowCount() == 0)
        model.setValues(defaultSettings());
    return &model;
}

QVariantMap Application::defaultSettings()
{
    QVariantMap settings;

    settings["ui.font"] = QFont();
    settings["ui.theme"] = "light";
    settings["ui.scrollback"] = 0;

    settings["formatting.timeStamp"] = "[hh:mm:ss]";
    settings["formatting.hideUserHosts"] = false;

#ifdef Q_OS_MAC
    QString navigate("Ctrl+Alt+%1");
    QString nextActive("Shift+Ctrl+Alt+%1");
#else
    QString navigate("Alt+%1");
    QString nextActive("Shift+Alt+%1");
#endif

    settings["shortcuts.previousView"] = navigate.arg("Up");
    settings["shortcuts.nextView"] = navigate.arg("Down");
    settings["shortcuts.collapseView"] = navigate.arg("Left");
    settings["shortcuts.expandView"] = navigate.arg("Right");
    settings["shortcuts.previousActiveView"] = nextActive.arg("Up");
    settings["shortcuts.nextActiveView"] = nextActive.arg("Down");
    settings["shortcuts.mostActiveView"] = "Ctrl+L";
    settings["shortcuts.searchView"] = "Ctrl+S";

    // TODO:
//    settings["messages.joins"] = true;
//    settings["messages.parts"] = true;
//    settings["messages.nicks"] = true;
//    settings["messages.modes"] = true;
//    settings["messages.kicks"] = true;
//    settings["messages.quits"] = true;
//    settings["messages.topics"] = true;

    settings["themes.light.background"] = QColor("#ffffff");
    settings["themes.light.message"] = QColor("#000000");
    settings["themes.light.event"] = QColor("#808080");
    settings["themes.light.notice"] = QColor("#a54242");
    settings["themes.light.action"] = QColor("#8b388b");
    settings["themes.light.highlight"] = QColor("#ff4040");
    settings["themes.light.timestamp"] = QColor("#808080");
    settings["themes.light.link"] = QColor("#4040ff");

    settings["aliases.chanserv"] = "MSG ChanServ $*";
    settings["aliases.nickserv"] = "MSG NickServ $*";

    return settings;
}

QDir Application::dataDir()
{
    return QDir(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
}

void Application::aboutApplication()
{
    QMessageBox::about(
#ifdef Q_WS_MAC
        0,
#else
        activeWindow(),
#endif // Q_WS_MAC
        applicationName(), QString(
            "
%1
"
            "
%2
"
            "
%3
"
            "
Copyright (C) 2008-2013 The Communi Project
")
        .arg(tr("About %1").arg(applicationName()))
        .arg(applicationSlogan())
        .arg(organizationDomain())
    );
}

void Application::showSettings()
{
    SettingsModel model;
    model.setValues(settings()->values());
    SettingsWizard wizard(&model, activeWindow());
    if (wizard.exec())
        settings()->setValues(model.values());
}
<|endoftext|>


<commit_before>#include "Ohmbrewer_Pump.h"

/**
 * The speed at which the Pump runs..
 */
int Ohmbrewer::Pump::getSpeed() const {
    return _speed;
}

/**
 * Sets the speed at which the Pump runs.
 */
const int Ohmbrewer::Pump::setSpeed(const int speed) {
    _speed = speed;
}

/**
 * Constructor
 */
Ohmbrewer::Pump::Pump(int id, int* pins) : Ohmbrewer::Equipment(id, pins) {
    _speed = 0;
}

/**
 * Constructor
 */
Ohmbrewer::Pump::Pump(int id, int* pins, int stopTime, bool state, char* currentTask) : Ohmbrewer::Equipment(id, pins, stopTime, state, currentTask) {
    _speed = 0;
}

/**
 * Constructor
 */
Ohmbrewer::Pump::Pump(int id, int* pins, int stopTime, bool state, char* currentTask, int speed) : Ohmbrewer::Equipment(id, pins, stopTime, state, currentTask)  {
    _speed = speed;
}

/**
 * Copy Constructor
 */
Ohmbrewer::Pump::Pump(const Pump& clonee) : Ohmbrewer::Equipment((Equipment)clonee) {
    _speed = clonee.getSpeed();
}

/**
 * Destructor
 */
Ohmbrewer::Pump::~Pump() {
    // Nothing to do here...
}

/**
 * Overloaded << operator.
 */
// friend std::ostream& operator<<( std::ostream& os, Pump const& pump);

/**
 * Specifies the interface for arguments sent to this Equipment's associated function.
 * Parses the supplied string into an array of strings for setting the Equipment's values.
 * Most likely will be called during update().
 */
char** Ohmbrewer::Pump::parseArgs(const char* argsStr) {
    // TODO: Implement Pump::parseArgs
}

/**
 * Sets the Equipment state. True => On, False => Off
 */
const int Ohmbrewer::Pump::setState(const bool state) {
    _state = state;
}

/**
 * The Equipment state. True => On, False => Off
 */
bool Ohmbrewer::Pump::getState() const {
    return _state;
}

/**
 * True if the Equipment state is On.
 */
bool Ohmbrewer::Pump::isOn() const {
    return _state;
}

/**
 * True if the Equipment state is Off.
 */
bool Ohmbrewer::Pump::isOff() const {
    return !_state;
}

/**
 * Performs the Equipment's current task. Expect to use this during loop().
 * This function is called by work().
 */
int Ohmbrewer::Pump::doWork() {
    // TODO: Implement Pump::doWork
}

/**
 * Draws information to the Rhizome's display.
 * This function is called by display().
 */
int Ohmbrewer::Pump::doDisplay() {
    // TODO: Implement Pump::doDisplay
}

/**
 * Publishes updates to Ohmbrewer, etc.
 * This function is called by update().
 */
int Ohmbrewer::Pump::doUpdate() {
    // TODO: Implement Pump::doUpdate
}

/**
 * Reports which of the Rhizome's pins are occupied by the
 * Equipment, forming a logical Sprout.
 */
int* Ohmbrewer::Pump::whichPins() const {
    return _pins;
}

<commit_msg>Forgot to set the _type value for Pump.<commit_after>#include "Ohmbrewer_Pump.h"

/**
 * The speed at which the Pump runs..
 */
int Ohmbrewer::Pump::getSpeed() const {
    return _speed;
}

/**
 * Sets the speed at which the Pump runs.
 */
const int Ohmbrewer::Pump::setSpeed(const int speed) {
    _speed = speed;
}

/**
 * Constructor
 */
Ohmbrewer::Pump::Pump(int id, int* pins) : Ohmbrewer::Equipment(id, pins) {
    _speed = 0;
    _type = "pump";
}

/**
 * Constructor
 */
Ohmbrewer::Pump::Pump(int id, int* pins, int stopTime, bool state, char* currentTask) : Ohmbrewer::Equipment(id, pins, stopTime, state, currentTask) {
    _speed = 0;
    _type = "pump";
}

/**
 * Constructor
 */
Ohmbrewer::Pump::Pump(int id, int* pins, int stopTime, bool state, char* currentTask, int speed) : Ohmbrewer::Equipment(id, pins, stopTime, state, currentTask)  {
    _speed = speed;
    _type = "pump";
}

/**
 * Copy Constructor
 */
Ohmbrewer::Pump::Pump(const Pump& clonee) : Ohmbrewer::Equipment((Equipment)clonee) {
    _speed = clonee.getSpeed();
}

/**
 * Destructor
 */
Ohmbrewer::Pump::~Pump() {
    // Nothing to do here...
}

/**
 * Overloaded << operator.
 */
// friend std::ostream& operator<<( std::ostream& os, Pump const& pump);

/**
 * Specifies the interface for arguments sent to this Equipment's associated function.
 * Parses the supplied string into an array of strings for setting the Equipment's values.
 * Most likely will be called during update().
 */
char** Ohmbrewer::Pump::parseArgs(const char* argsStr) {
    // TODO: Implement Pump::parseArgs
}

/**
 * Sets the Equipment state. True => On, False => Off
 */
const int Ohmbrewer::Pump::setState(const bool state) {
    _state = state;
}

/**
 * The Equipment state. True => On, False => Off
 */
bool Ohmbrewer::Pump::getState() const {
    return _state;
}

/**
 * True if the Equipment state is On.
 */
bool Ohmbrewer::Pump::isOn() const {
    return _state;
}

/**
 * True if the Equipment state is Off.
 */
bool Ohmbrewer::Pump::isOff() const {
    return !_state;
}

/**
 * Performs the Equipment's current task. Expect to use this during loop().
 * This function is called by work().
 */
int Ohmbrewer::Pump::doWork() {
    // TODO: Implement Pump::doWork
}

/**
 * Draws information to the Rhizome's display.
 * This function is called by display().
 */
int Ohmbrewer::Pump::doDisplay() {
    // TODO: Implement Pump::doDisplay
}

/**
 * Publishes updates to Ohmbrewer, etc.
 * This function is called by update().
 */
int Ohmbrewer::Pump::doUpdate() {
    // TODO: Implement Pump::doUpdate
}

/**
 * Reports which of the Rhizome's pins are occupied by the
 * Equipment, forming a logical Sprout.
 */
int* Ohmbrewer::Pump::whichPins() const {
    return _pins;
}

<|endoftext|>