rott/kf_sources/Engine/Classes/StreamPlaylist.uc
2026-07-14 20:27:09 +07:00

493 lines
10 KiB
Ucode

//==============================================================================
// Created on: 10/12/2003
// A user-configured list of streaming music files.
//
// Written by Ron Prestenback
// © 2003, Epic Games, Inc. All Rights Reserved
//==============================================================================
class StreamPlaylist extends StreamBase
PerObjectConfig
Config(UPlaylists);
var() protected config int Current;
var() protected config array<string> Playlist;
var() protected string Title;
var() protected config bool bNeedSave;
var() editinline editconst noexport private editconstarray transient array<int> RandomPool;
var() editinline editconst noexport protected StreamInterface FileManager;
var() editinline editconst noexport protected editconstarray array<Stream> Songs;
delegate OnPlaylistChanged();
function bool InitializePlaylist( StreamInterface InManager )
{
if ( InManager == None || IsInitialized() )
return false;
FileManager = InManager;
LoadPlaylist();
return true;
}
function bool LoadPlaylist()
{
local int i;
ClearPlaylist();
for ( i = 0; i < Playlist.Length; i++ )
{
if ( !FileManager.ValidFile(Playlist[i]) )
{
log("Removing file from playlist '"$GetTitle()$"' - file not found",'MusicPlayer');
Playlist.Remove(i--,1);
continue;
}
AddSong(Playlist[i]);
}
ResetRandomPool();
bNeedSave = False;
return true;
}
function Stream CreateStream( string FileName )
{
if ( FileName == "" )
return None;
return FileManager.CreateStream( FileName );
}
function int AddSong( string SongFileName, optional bool bSkipNotification )
{
local Stream NewStream;
local EFileType Type;
local int i;
if ( SongFileName == "" )
return -1;
Type = ConvertToFileType(SongFileName);
if ( Type == FILE_Stream )
{
NewStream = CreateStream(SongFileName);
if ( NewStream == None )
return -1;
i = AddStream(GetPlaylistLength(), NewStream, bSkipNotification);
bNeedSave = bNeedSave || ValidStreamIndex(i);
return i;
}
return -1;
}
function int AddStream( int Index, Stream NewStream, optional bool bSkipNotification )
{
local int i;
local string Str;
if ( NewStream == None )
return -1;
Str = NewStream.GetFileName();
if ( Str == "" )
return -1;
i = FindIndexByName( Str );
if ( !ValidStreamIndex(i) )
{
if ( !ValidStreamIndex(Index) )
Index = GetPlaylistLength();
Songs.Insert( Index, 1 );
Songs[Index] = NewStream;
RandomPool[RandomPool.Length] = Index;
if ( !bSkipNotification )
OnPlaylistChanged();
return Index;
}
return i;
}
function int InsertSong( int idx, string Path, optional bool bSkipNotification )
{
local Stream NewStream;
local EFileType Type;
local int i;
if ( !ValidStreamIndex(idx) )
return AddSong(Path,bSkipNotification);
if ( Path == "" )
return -1;
Type = ConvertToFileType(Path);
if ( Type == FILE_Stream )
{
NewStream = CreateStream(Path);
if ( NewStream == None )
return -1;
i = AddStream(idx, NewStream, bSkipNotification);
bNeedSave = bNeedSave || ValidStreamIndex(i);
return i;
}
return -1;
}
function bool RemoveSong( string SongFileName, optional bool bSkipNotification )
{
return RemoveSongAt(FindIndexByName(SongFileName), bSkipNotification);
}
function bool RemoveSongAt( int idx, optional bool bSkipNotification )
{
local int i;
if ( !ValidStreamIndex(idx) )
return false;
Songs.Remove(idx,1);
// Remove the last index from the random pool
for ( i = 0; i < RandomPool.Length; i++ )
if ( RandomPool[i] == Songs.Length )
{
RandomPool.Remove(i,1);
break;
}
// If this was the current song, attempt to set the current to the previous song, so that the playlist will
// select the next song correctly
if ( idx == Current && !SetCurrent(idx-1) )
SetCurrent(0);
bNeedSave = True;
if ( !bSkipNotification )
OnPlaylistChanged();
return true;
}
function string NextSong( bool bMayRepeat )
{
local int i;
i = GetCurrent() + 1;
if ( !ValidStreamIndex(i) && bMayRepeat )
i = 0;
if ( SetCurrent(i) )
return Songs[Current].GetPath();
return "";
}
function string PrevSong( bool bMayRepeat )
{
local int i;
i = GetCurrent() - 1;
if ( !ValidStreamIndex(i) && bMayRepeat )
i = GetPlaylistLength() - 1;
if ( SetCurrent(i) )
return Songs[Current].GetPath();
return "";
}
function ReplaceWith( StreamPlaylist Other )
{
if ( Other == None )
return;
FileManager = Other.FileManager;
Other.GetSongs(Songs);
ResetRandomPool();
SetCurrent( Other.GetCurrent() );
bNeedSave = True;
}
function bool ClearPlaylist()
{
bNeedSave = bNeedSave || Songs.Length > 0;
Songs.Remove( 0, Songs.Length );
RandomPool.Remove(0, RandomPool.Length);
return true;
}
function string GetRandomSong()
{
local int idx;
local Stream RandomStream;
if ( RandomPool.Length == 0 )
ResetRandomPool();
if ( RandomPool.Length > 0 )
{
idx = Rand(RandomPool.Length - 1);
if ( ValidStreamIndex(RandomPool[idx]) )
{
RandomStream = Songs[RandomPool[idx]];
RandomPool.Remove(idx,1);
return RandomStream.GetPath();
}
}
return "";
}
function ResetRandomPool()
{
local int i;
RandomPool.Length = Songs.Length;
for ( i = 0; i < Songs.Length; i++ )
RandomPool[i] = i;
}
function bool SetTitle( string NewTitle )
{
if ( NewTitle == "" )
return false;
Title = NewTitle;
OnPlaylistChanged();
Save();
return true;
}
function bool SetCurrent( int Index )
{
if ( !ValidStreamIndex(Index) )
return false;
Current = Index;
bNeedSave = True;
return true;
}
// DOES NOT perform notification!!
function bool SetSongs( array<Stream> NewSongs )
{
Songs = NewSongs;
ResetRandomPool();
bNeedSave = True;
return true;
}
// =====================================================================================================================
// =====================================================================================================================
// Query
// =====================================================================================================================
// =====================================================================================================================
function bool IsInitialized()
{
return FileManager != None;
}
function string GetTitle()
{
return Title;
}
function int GetCurrent()
{
return Current;
}
function GetSongs( out array<Stream> SongArray )
{
SongArray = Songs;
}
function Stream GetCurrentStream()
{
return GetStreamAt(GetCurrent());
}
function Stream GetStream( string StreamName )
{
local int i;
i = FindIndexByName(StreamName);
return GetStreamAt(i);
}
function Stream GetStreamAt( int Index )
{
if (ValidStreamIndex(Index) )
return Songs[Index];
return None;
}
function int GetPlaylistLength()
{
return Songs.Length;
}
function int FindIndexByName( string Test )
{
local FilePath APath;
if ( ParsePath(Test, APath) )
{
if ( APath.Extension != "" )
{
if ( APath.Directory != "" )
return FindIndexByPath(APath.FullPath);
else if ( APath.FileName != "" )
return FindIndexByFullName( APath.FileName $ "." $ APath.Extension );
}
else return FindIndexByFileName(APath.FileName);
}
return -1;
}
function int FindIndexByPath( string Test )
{
local int i;
if ( Test == "" )
return -1;
for ( i = 0; i < Songs.Length; i++ )
if ( Songs[i].GetPath() ~= Test )
return i;
return -1;
}
function int FindIndexByFullName( string Test )
{
local int i, num;
if ( Test == "" )
return -1;
num = GetPlaylistLength();
for ( i = 0; i < num; i++ )
{
if ( Songs[i].GetFullName() ~= Test )
return i;
}
return -1;
}
function int FindIndexByFileName( string Test )
{
local int i, num;
if ( Test == "" )
return -1;
num = GetPlaylistLength();
for ( i = 0; i < num; i++ )
{
if ( Songs[i].GetFileName() ~= Test )
return i;
}
return -1;
}
function bool ValidStreamName( string FileName )
{
if ( FileName == "" )
return false;
return ValidStreamIndex( FindIndexByName(FileName) );
}
function bool ValidStreamIndex( int Index )
{
return Index >= 0 && Index < Songs.Length;
}
// =====================================================================================================================
// =====================================================================================================================
// Debug
// =====================================================================================================================
// =====================================================================================================================
function DebugInfo()
{
local int i;
log(" Playlist '"$GetTitle()$"', Length:"$GetPlaylistLength(),'MusicPlayer');
for ( i = 0; i < GetPlaylistLength(); i++ )
log(" "$i$")"@Songs[i].GetSongTitle(),'MusicPlayer');
}
function bool HandleDebugExec(string Command, string Param)
{
local int i;
if ( Super.HandleDebugExec(Command,Param) )
return true;
switch ( Locs(Command))
{
case "addsong":
AddSong(Param);
return true;
case "dumptags":
for ( i = 0; i < Songs.Length; i++ )
Songs[i].DumpTags();
return true;
case "scripttags":
for ( i = 0; i < Songs.Length; i++ )
Songs[i].DumpScriptTag();
case "showsongs":
log("Playlist"@GetTitle()@"has"@Songs.Length@"songs",'MusicPlayer');
for ( i = 0; i < Songs.Length; i++ )
log(" "$i$")"@Songs[i].GetPath(),'MusicPlayer');
return true;
}
return false;
}
function Save()
{
local int i;
if ( !bNeedSave )
return;
Playlist.Remove(0, Playlist.Length);
for ( i = 0; i < Songs.Length; i++ )
if ( Songs[i] != None )
Playlist[i] = Songs[i].GetPath();
bNeedSave = False;
SaveConfig();
}
DefaultProperties
{
bNeedSave=True
}