From dd941b1f837ff3e603db9289ade7aa7cbb7d7bc4 Mon Sep 17 00:00:00 2001 From: glucaci Date: Wed, 30 Nov 2016 23:24:46 +0100 Subject: [PATCH] Commands to Server are now Async --- LibMpc/Mpc.cs | 275 ++++++++++++++++++++-------------------- LibMpc/MpcConnection.cs | 96 +++++--------- 2 files changed, 163 insertions(+), 208 deletions(-) diff --git a/LibMpc/Mpc.cs b/LibMpc/Mpc.cs index 0928bcc..82d0701 100644 --- a/LibMpc/Mpc.cs +++ b/LibMpc/Mpc.cs @@ -6,34 +6,22 @@ using System.Threading.Tasks; namespace LibMpc { - public interface IMpc - { - bool IsConnected { get; } - Task ConnectAsync(); - - MpdOutput[] Outputs(); - MpdStatistics Stats(); - } - /// /// The Mpc class implements all commands for the MPD. It takes care of command building /// and parsing the response into .net objects. /// - public class Mpc : IMpc + public class Mpc { private static readonly Regex STATUS_AUDIO_REGEX = new Regex("^(?[0-9]*):(?[0-9]*):(?[0-9]*)$"); + private readonly IPEndPoint _server; private MpcConnection _connection; - private IPEndPoint _server; public Mpc(IPEndPoint server) { _server = server; } - /// - /// Connection status to MPD Server. - /// public bool IsConnected => _connection?.IsConnected ?? false; public async Task ConnectAsync() @@ -57,26 +45,30 @@ namespace LibMpc /// /// The id of the output. /// If the action was successful. - public bool DisableOutput(int id) + public async Task DisableOutputAsync(int id) { - return !_connection.Exec("disableoutput", new string[] { id.ToString() }).IsError; + var mpdResponse = await _connection.Exec("disableoutput", new string[] { id.ToString() }); + return !mpdResponse.IsError; } + /// /// Enables an MPD output. /// /// The id of the output. /// If the action was successful. - public bool EnableOutput(int id) + public async Task EnableOutputAsync(int id) { - return !_connection.Exec("enableoutput", new string[] { id.ToString() }).IsError; + var mpdResponse = await _connection.Exec("enableoutput", new string[] { id.ToString() }); + return !mpdResponse.IsError; } + /// /// Lists all outputs of the MPD. /// /// The list of all MPD outputs. - public MpdOutput[] Outputs() + public async Task OutputsAsync() { - MpdResponse response = _connection.Exec("outputs"); + MpdResponse response = await _connection.Exec("outputs"); if (response.Message.Count % 3 != 0) throw new InvalidMpdResponseException(); @@ -120,9 +112,9 @@ namespace LibMpc /// Returns the list of tag types the MPD supports. /// /// The list of tag types the MPD supports. - public string[] TagTypes() + public async Task TagTypesAsync() { - MpdResponse response = _connection.Exec("tagtypes"); + MpdResponse response = await _connection.Exec("tagtypes"); string[] ret = new string[response.Message.Count]; @@ -140,9 +132,9 @@ namespace LibMpc /// Starts an update of the MPD database. /// /// An sequential number of the update process. - public int Update() + public async Task UpdateAsync() { - MpdResponse response = _connection.Exec("update"); + MpdResponse response = await _connection.Exec("update"); if (response.Message.Count != 1) throw new InvalidMpdResponseException("Respose message has more than one line."); @@ -167,12 +159,12 @@ namespace LibMpc /// Specifies the attribute to search for. /// The value the files attribute must have to be included in the result. /// All files in the database who's attribute matches the given token. - public List Find(ScopeSpecifier scopeSpecifier, string token) + public async Task> FindAsync(ScopeSpecifier scopeSpecifier, string token) { if (token == null) throw new ArgumentNullException("token"); - MpdResponse response = _connection.Exec("find", new string[] { TagConverter.ToTag(scopeSpecifier), token }); + MpdResponse response = await _connection.Exec("find", new string[] { TagConverter.ToTag(scopeSpecifier), token }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -184,9 +176,9 @@ namespace LibMpc /// /// The attribute who's values are requested. /// All values found in files of the MPD for the given attribute. - public List List(ScopeSpecifier scopeSpecifier) + public async Task> ListAsync(ScopeSpecifier scopeSpecifier) { - MpdResponse response = _connection.Exec("list", new string[] { TagConverter.ToTag(scopeSpecifier) }); + MpdResponse response = await _connection.Exec("list", new string[] { TagConverter.ToTag(scopeSpecifier) }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -200,12 +192,12 @@ namespace LibMpc /// The attribute whos value should match a given value for the file to be included in the result. /// The value the searchTag attribute must match for the file to be included in the result. /// All values found in files of the MPD for the given attribute. - public List List(ScopeSpecifier resultTag, ScopeSpecifier searchTag, string searchValue) + public async Task> ListAsync(ScopeSpecifier resultTag, ScopeSpecifier searchTag, string searchValue) { if (searchValue == null) throw new ArgumentNullException("searchValue"); - MpdResponse response = _connection.Exec("list", new string[] { TagConverter.ToTag(resultTag), TagConverter.ToTag(searchTag), searchValue }); + MpdResponse response = await _connection.Exec("list", new string[] { TagConverter.ToTag(resultTag), TagConverter.ToTag(searchTag), searchValue }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -217,12 +209,12 @@ namespace LibMpc /// /// The path whos subdirectories and their files are requested. /// The names of all files and directory found under the given path. - public List ListAll(string path) + public async Task> ListAllAsync(string path) { if (path == null) throw new ArgumentNullException("path"); - MpdResponse response = _connection.Exec("listall", new string[] { path }); + MpdResponse response = await _connection.Exec("listall", new string[] { path }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -234,12 +226,12 @@ namespace LibMpc /// /// The path of which the file information is requested. /// The information of all files found in the given path and its subdirectories. - public List ListAllInfo(string path) + public async Task> ListAllInfoAsync(string path) { if (path == null) throw new ArgumentNullException("path"); - MpdResponse response = _connection.Exec("listallinfo", new string[] { path }); + MpdResponse response = await _connection.Exec("listallinfo", new string[] { path }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -250,22 +242,22 @@ namespace LibMpc /// Returns the directory listing of the root directory. /// /// The listing of the root directory. - public MpdDirectoryListing LsInfo() + public async Task LsInfoAsync() { - return LsInfo(null); + return await LsInfoAsync(null); } /// /// Returns the directory listing of the given path. /// /// The path whos listing is requested. /// The directory listing of the given path. - public MpdDirectoryListing LsInfo(string path) + public async Task LsInfoAsync(string path) { MpdResponse response; if (path == null) - response = _connection.Exec("lsinfo"); + response = await _connection.Exec("lsinfo"); else - response = _connection.Exec("lsinfo", new string[] { path }); + response = await _connection.Exec("lsinfo", new string[] { path }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -281,12 +273,12 @@ namespace LibMpc /// Specifies the attribute to search for. /// The value the files attribute must have to be included in the result. /// All files in the database who's attribute matches the given token. - public List Search(ScopeSpecifier scopeSpecifier, string token) + public async Task> SearchAsync(ScopeSpecifier scopeSpecifier, string token) { if (token == null) throw new ArgumentNullException("token"); - MpdResponse response = _connection.Exec("search", new string[] { TagConverter.ToTag(scopeSpecifier), token }); + MpdResponse response = await _connection.Exec("search", new string[] { TagConverter.ToTag(scopeSpecifier), token }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -301,12 +293,12 @@ namespace LibMpc /// Adds a file to the playlist. /// /// The name and path of the file to add. - public void Add(string filename) + public async Task AddAsync(string filename) { if (filename == null) throw new ArgumentNullException("filename"); - MpdResponse response = _connection.Exec("add", new string[] { filename }); + MpdResponse response = await _connection.Exec("add", new string[] { filename }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -316,12 +308,12 @@ namespace LibMpc /// /// The name and path of the file to add. /// The id of the file in the playlist. - public int AddId(string filename) + public async Task AddIdAsync(string filename) { if (filename == null) throw new ArgumentNullException("filename"); - MpdResponse response = _connection.Exec("add", new string[] { filename }); + MpdResponse response = await _connection.Exec("add", new string[] { filename }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -341,9 +333,9 @@ namespace LibMpc /// /// Clears the playlist. /// - public void Clear() + public async Task ClearAsync() { - MpdResponse response = _connection.Exec("clear"); + MpdResponse response = await _connection.Exec("clear"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -352,9 +344,9 @@ namespace LibMpc /// Returns the information of the current song. /// /// The information of the current song. - public MpdFile CurrentSong() + public async Task CurrentSongAsync() { - MpdResponse response = _connection.Exec("currentsong"); + MpdResponse response = await _connection.Exec("currentsong"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -365,9 +357,9 @@ namespace LibMpc /// Deletes the track with the given index from the current playlist. /// /// The index of the track to remove from the playlist. - public void Delete(int nr) + public async Task DeleteAsync(int nr) { - MpdResponse response = _connection.Exec("delete", new string[] { nr.ToString() }); + MpdResponse response = await _connection.Exec("delete", new string[] { nr.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -376,9 +368,9 @@ namespace LibMpc /// Deletes the track with the given id from the current playlist. /// /// The id of the track to remove from the playlist. - public void DeleteId(int id) + public async Task DeleteIdAsync(int id) { - MpdResponse response = _connection.Exec("deleteid", new string[] { id.ToString() }); + MpdResponse response = await _connection.Exec("deleteid", new string[] { id.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -387,12 +379,12 @@ namespace LibMpc /// Loads the playlist with the given name. /// /// The name of the playlist to load. - public void Load(string name) + public async Task LoadAsync(string name) { if (name == null) throw new ArgumentNullException("name"); - MpdResponse response = _connection.Exec("load", new string[] { name }); + MpdResponse response = await _connection.Exec("load", new string[] { name }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -402,14 +394,14 @@ namespace LibMpc /// /// The old name of the playlist. /// The new name of the playlist. - public void Rename(string oldName, string newName) + public async Task RenameAsync(string oldName, string newName) { if (oldName == null) throw new ArgumentNullException("oldName"); if (newName == null) throw new ArgumentNullException("newName"); - MpdResponse response = _connection.Exec("rename", new string[] { oldName, newName }); + MpdResponse response = await _connection.Exec("rename", new string[] { oldName, newName }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -419,9 +411,9 @@ namespace LibMpc /// /// The old index of the track in the playlist. /// The new index of the track in the playlist. - public void Move(int oldNr, int newNr) + public async Task MoveAsync(int oldNr, int newNr) { - MpdResponse response = _connection.Exec("move", new string[] { oldNr.ToString(), newNr.ToString() }); + MpdResponse response = await _connection.Exec("move", new string[] { oldNr.ToString(), newNr.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -431,9 +423,9 @@ namespace LibMpc /// /// The id of the track to move. /// The new index of the track in the playlist. - public void MoveId(int id, int nr) + public async Task MoveIdAsync(int id, int nr) { - MpdResponse response = _connection.Exec("moveid", new string[] { id.ToString(), nr.ToString() }); + MpdResponse response = await _connection.Exec("moveid", new string[] { id.ToString(), nr.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -442,9 +434,9 @@ namespace LibMpc /// Returns the meta data of the items in the current playlist. /// /// The meta data of the items in the current playlist. - public List PlaylistInfo() + public async Task> PlaylistInfoAsync() { - MpdResponse response = _connection.Exec("playlistinfo"); + MpdResponse response = await _connection.Exec("playlistinfo"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -456,9 +448,9 @@ namespace LibMpc /// /// The index of the track in the playlist. /// The meta data of the track in the current playlist. - public MpdFile PlaylistInfo(int nr) + public async Task PlaylistInfoAsync(int nr) { - MpdResponse response = _connection.Exec("playlistinfo", new string[] { nr.ToString() }); + MpdResponse response = await _connection.Exec("playlistinfo", new string[] { nr.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -469,9 +461,9 @@ namespace LibMpc /// Returns the meta data of the items in the current playlist. /// /// The meta data of the items in the current playlist. - public List PlaylistId() + public async Task> PlaylistIdAsync() { - MpdResponse response = _connection.Exec("playlistid"); + MpdResponse response = await _connection.Exec("playlistid"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -483,9 +475,9 @@ namespace LibMpc /// /// The id of the track in the playlist. /// The meta data of the track in the current playlist. - public MpdFile PlaylistId(int id) + public async Task PlaylistIdAsync(int id) { - MpdResponse response = _connection.Exec("playlistid", new string[] { id.ToString() }); + MpdResponse response = await _connection.Exec("playlistid", new string[] { id.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -497,9 +489,9 @@ namespace LibMpc /// /// The version number. /// All changed songs in the playlist since the given version. - public List Plchanges(int version) + public async Task> PlchangesAsync(int version) { - MpdResponse response = _connection.Exec("plchanges", new string[] { version.ToString() }); + MpdResponse response = await _connection.Exec("plchanges", new string[] { version.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -514,9 +506,9 @@ namespace LibMpc /// The ids and positions of the changed tracks in the playlist since the given version as KeyValuePairs. /// The key is the index and the id is the value. /// - public List> PlChangesPosId(int version) + public async Task>> PlChangesPosIdAsync(int version) { - MpdResponse response = _connection.Exec("plchangesposid", new string[] { version.ToString() }); + MpdResponse response = await _connection.Exec("plchangesposid", new string[] { version.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -558,12 +550,12 @@ namespace LibMpc /// Removes the playlist with the given name. /// /// The name of the playlist to remove. - public void Rm(string name) + public async Task RmAsync(string name) { if (name == null) throw new ArgumentNullException("name"); - MpdResponse response = _connection.Exec("rm", new string[] { name }); + MpdResponse response = await _connection.Exec("rm", new string[] { name }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -572,12 +564,12 @@ namespace LibMpc /// Saves the current playlist with the given name. /// /// The name to the save the currenty playlist. - public void Save(string name) + public async Task SaveAsync(string name) { if (name == null) throw new ArgumentNullException("name"); - MpdResponse response = _connection.Exec("save", new string[] { name }); + MpdResponse response = await _connection.Exec("save", new string[] { name }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -585,9 +577,9 @@ namespace LibMpc /// /// Shuffles the current playlist. /// - public void Shuffle() + public async Task ShuffleAsync() { - MpdResponse response = _connection.Exec("shuffle"); + MpdResponse response = await _connection.Exec("shuffle"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -597,9 +589,9 @@ namespace LibMpc /// /// The index of the first track. /// The index of the second track. - public void Swap(int nr1, int nr2) + public async Task SwapAsync(int nr1, int nr2) { - MpdResponse response = _connection.Exec("swap", new string[] { nr1.ToString(), nr2.ToString() }); + MpdResponse response = await _connection.Exec("swap", new string[] { nr1.ToString(), nr2.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -609,9 +601,9 @@ namespace LibMpc /// /// The id of the first track. /// The id of the second track. - public void SwapId(int id1, int id2) + public async Task SwapIdAsync(int id1, int id2) { - MpdResponse response = _connection.Exec("swapid", new string[] { id1.ToString(), id2.ToString() }); + MpdResponse response = await _connection.Exec("swapid", new string[] { id1.ToString(), id2.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -621,12 +613,12 @@ namespace LibMpc /// /// The playlist whos filename are requested. /// The filenames of the tracks in the given playlist. - public List ListPlaylist(string name) + public async Task> ListPlaylistAsync(string name) { if (name == null) throw new ArgumentNullException("name"); - MpdResponse response = _connection.Exec("listplaylist", new string[] { name }); + MpdResponse response = await _connection.Exec("listplaylist", new string[] { name }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -638,12 +630,12 @@ namespace LibMpc /// /// The playlist whos files meta data are requested. /// The meta data of the tracks in the given playlist. - public List ListPlaylistInfo(string name) + public async Task> ListPlaylistInfoAsync(string name) { if (name == null) throw new ArgumentNullException("name"); - MpdResponse response = _connection.Exec("listplaylistinfo", new string[] { name }); + MpdResponse response = await _connection.Exec("listplaylistinfo", new string[] { name }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -655,14 +647,14 @@ namespace LibMpc /// /// The name of the playlist. /// The path and name of the file to add. - public void PlaylistAdd(string name, string file) + public async Task PlaylistAddAsync(string name, string file) { if (name == null) throw new ArgumentNullException("name"); if (file == null) throw new ArgumentNullException("file"); - MpdResponse response = _connection.Exec("playlistadd", new string[] { name, file }); + MpdResponse response = await _connection.Exec("playlistadd", new string[] { name, file }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -671,12 +663,12 @@ namespace LibMpc /// Clears all tracks from a playlist. /// /// The name of the playlist to clear. - public void PlaylistClear(string name) + public async Task PlaylistClearAsync(string name) { if (name == null) throw new ArgumentNullException("name"); - MpdResponse response = _connection.Exec("playlistclear", new string[] { name }); + MpdResponse response = await _connection.Exec("playlistclear", new string[] { name }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -686,12 +678,12 @@ namespace LibMpc /// /// The name of the playlist /// The id of the track to delete. - public void PlaylistDelete(string name, int id) + public async Task PlaylistDeleteAsync(string name, int id) { if (name == null) throw new ArgumentNullException("name"); - MpdResponse response = _connection.Exec("playlistdelete", new string[] { name, id.ToString() }); + MpdResponse response = await _connection.Exec("playlistdelete", new string[] { name, id.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -702,12 +694,12 @@ namespace LibMpc /// The name of the playlist. /// The id of the track to move. /// The position to move the track to. - public void PlaylistMove(string name, int id, int nr) + public async Task PlaylistMoveAsync(string name, int id, int nr) { if (name == null) throw new ArgumentNullException("name"); - MpdResponse response = _connection.Exec("playlistmove", new string[] { id.ToString(), nr.ToString() }); + MpdResponse response = await _connection.Exec("playlistmove", new string[] { id.ToString(), nr.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -718,12 +710,12 @@ namespace LibMpc /// The attribute to search for the given value. /// The value to search for in the given attribute. /// The meta data for all tracks in the current playlist whos attribute equals the given value. - public List PlaylistFind(ScopeSpecifier scopeSpecifier, string token) + public async Task> PlaylistFindAsync(ScopeSpecifier scopeSpecifier, string token) { if (token == null) throw new ArgumentNullException("token"); - MpdResponse response = _connection.Exec("playlistfind", new string[] { TagConverter.ToTag(scopeSpecifier), token }); + MpdResponse response = await _connection.Exec("playlistfind", new string[] { TagConverter.ToTag(scopeSpecifier), token }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -736,12 +728,12 @@ namespace LibMpc /// The attribute to search for the given value. /// The value to search for in the given attribute. /// The meta data for all tracks in the current playlist whos attribute contains the given value. - public List PlaylistSearch(ScopeSpecifier scopeSpecifier, string token) + public async Task> PlaylistSearchAsync(ScopeSpecifier scopeSpecifier, string token) { if (token == null) throw new ArgumentNullException("token"); - MpdResponse response = _connection.Exec("playlistsearch", new string[] { TagConverter.ToTag(scopeSpecifier), token }); + MpdResponse response = await _connection.Exec("playlistsearch", new string[] { TagConverter.ToTag(scopeSpecifier), token }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -755,9 +747,9 @@ namespace LibMpc /// Sets the seconds to crossfade between songs. /// /// The seconds to crossfade between songs. - public void Crossfade(int seconds) + public async Task CrossfadeAsync(int seconds) { - MpdResponse response = _connection.Exec("crossfade", new string[] { seconds.ToString() }); + MpdResponse response = await _connection.Exec("crossfade", new string[] { seconds.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -765,9 +757,9 @@ namespace LibMpc /// /// Starts the playback of the next song in the playlist- /// - public void Next() + public async Task NextAsync() { - MpdResponse response = _connection.Exec("next"); + MpdResponse response = await _connection.Exec("next"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -776,9 +768,9 @@ namespace LibMpc /// Sets the MPD to pause or resume the playback. /// /// If the playback should be paused or resumed. - public void Pause(bool pause) + public async Task PauseAsync(bool pause) { - MpdResponse response = _connection.Exec("pause", new string[] { pause ? "1" : "0" }); + MpdResponse response = await _connection.Exec("pause", new string[] { pause ? "1" : "0" }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -786,9 +778,9 @@ namespace LibMpc /// /// Starts the playback of the current item in the playlist. /// - public void Play() + public async Task PlayAsync() { - MpdResponse response = _connection.Exec("play"); + MpdResponse response = await _connection.Exec("play"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -797,9 +789,9 @@ namespace LibMpc /// Starts the playback of the item with the given index in the playlist. /// /// The index of the track in the playlist to start playing. - public void Play(int nr) + public async Task PlayAsync(int nr) { - MpdResponse response = _connection.Exec("play", new string[] { nr.ToString() }); + MpdResponse response = await _connection.Exec("play", new string[] { nr.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -807,9 +799,9 @@ namespace LibMpc /// /// Starts the playback of the track in the playlist with the id 0. /// - public void PlayId() + public async Task PlayIdAsync() { - MpdResponse response = _connection.Exec("playid"); + MpdResponse response = await _connection.Exec("playid"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -818,9 +810,9 @@ namespace LibMpc /// Starts the playback of the track in the playlist with the given id. /// /// The id of the track to start playing. - public void PlayId(int id) + public async Task PlayIdAsync(int id) { - MpdResponse response = _connection.Exec("playid", new string[] { id.ToString() }); + MpdResponse response = await _connection.Exec("playid", new string[] { id.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -828,9 +820,9 @@ namespace LibMpc /// /// Starts the playback of the previous track in the playlist. /// - public void Previous() + public async Task PreviousAsync() { - MpdResponse response = _connection.Exec("previous"); + MpdResponse response = await _connection.Exec("previous"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -839,9 +831,9 @@ namespace LibMpc /// Sets the MPD to random or sequential playback. /// /// If the MPD playlist should be played randomly. - public void Random(bool random) + public async Task RandomAsync(bool random) { - MpdResponse response = _connection.Exec("random", new string[] { random ? "1" : "0" }); + MpdResponse response = await _connection.Exec("random", new string[] { random ? "1" : "0" }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -850,9 +842,9 @@ namespace LibMpc /// Sets if the MPD should repeat the playlist. /// /// If the MPD should repeat the playlist. - public void Repeat(bool repeat) + public async Task RepeatAsync(bool repeat) { - MpdResponse response = _connection.Exec("repeat", new string[] { repeat ? "1" : "0" }); + MpdResponse response = await _connection.Exec("repeat", new string[] { repeat ? "1" : "0" }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -862,9 +854,9 @@ namespace LibMpc /// /// The index of the song in the playlist. /// The number of seconds to start playback on. - public void Seek(int nr, int time) + public async Task SeekAsync(int nr, int time) { - MpdResponse response = _connection.Exec("seek", new string[] { nr.ToString(), time.ToString() }); + MpdResponse response = await _connection.Exec("seek", new string[] { nr.ToString(), time.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -874,9 +866,9 @@ namespace LibMpc /// /// The id of the song in the playlist. /// The number of seconds to start playback on. - public void SeekId(int id, int time) + public async Task SeekIdAsync(int id, int time) { - MpdResponse response = _connection.Exec("seekid", new string[] { id.ToString(), time.ToString() }); + MpdResponse response = await _connection.Exec("seekid", new string[] { id.ToString(), time.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -885,14 +877,14 @@ namespace LibMpc /// Sets the output volume of the MPD. /// /// The output volume of the MPD between 0 and 100. - public void SetVol(int vol) + public async Task SetVolAsync(int vol) { if (vol < 0) throw new ArgumentException("vol < 0"); if (vol > 100) throw new ArgumentException("vol > 100"); - MpdResponse response = _connection.Exec("setvol", new string[] { vol.ToString() }); + MpdResponse response = await _connection.Exec("setvol", new string[] { vol.ToString() }); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -900,9 +892,9 @@ namespace LibMpc /// /// Stops the playback of the MPD. /// - public void Stop() + public async Task StopAsync() { - MpdResponse response = _connection.Exec("stop"); + MpdResponse response = await _connection.Exec("stop"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -914,17 +906,17 @@ namespace LibMpc /// /// Clears the error message set in the MPD. /// - public void ClearError() + public async Task ClearErrorAsync() { - _connection.Exec("clearerror"); + await _connection.Exec("clearerror"); } /// /// Returns which commands the current user has access to. /// /// The commands the current user has access to. - public List Commands() + public async Task> CommandsAsync() { - MpdResponse response = _connection.Exec("commands"); + MpdResponse response = await _connection.Exec("commands"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -935,9 +927,9 @@ namespace LibMpc /// Returns which commands the current user does has access to. /// /// The commands the current user does has access to. - public List NotCommands() + public async Task> NotCommandsAsync() { - MpdResponse response = _connection.Exec("notcommands"); + MpdResponse response = await _connection.Exec("notcommands"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -949,27 +941,28 @@ namespace LibMpc /// /// The password to authorize to the server. /// If the password is valid. - public bool Password(string password) + public async Task PasswordAsync(string password) { if (password == null) throw new ArgumentNullException("password"); - return _connection.Exec("password", new string[] { password }).IsError; + var mpdResponse = await _connection.Exec("password", new string[] { password }); + return mpdResponse.IsError; } /// /// Sends a ping command to the server and waits for the response. /// - public void Ping() + public async Task PingAsync() { - _connection.Exec("ping"); + await _connection.Exec("ping"); } /// /// Requests the current statistics from the MPD, /// /// The current statistics fromt the MPD. - public MpdStatistics Stats() + public async Task StatsAsync() { - MpdResponse response = _connection.Exec("stats"); + MpdResponse response = await _connection.Exec("stats"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); @@ -1045,9 +1038,9 @@ namespace LibMpc /// Returns the current status of the MPD. /// /// The current status of the MPD. - public MpdStatus Status() + public async Task StatusAsync() { - MpdResponse response = _connection.Exec("status"); + MpdResponse response = await _connection.Exec("status"); if (response.IsError) throw new MpdResponseException(response.ErrorCode, response.ErrorMessage); diff --git a/LibMpc/MpcConnection.cs b/LibMpc/MpcConnection.cs index 2584ae0..9fb1f7a 100644 --- a/LibMpc/MpcConnection.cs +++ b/LibMpc/MpcConnection.cs @@ -24,68 +24,29 @@ namespace LibMpc private static readonly Regex ACK_REGEX = new Regex("^ACK \\[(?[0-9]*)@(?[0-9]*)] \\{(?[a-z]*)} (?.*)$"); - private IPEndPoint _ipEndPoint; + private readonly IPEndPoint _server; private TcpClient _tcpClient; private NetworkStream _networkStream; - private StreamReader _reader; private StreamWriter _writer; private string _version; - /// - /// If the connection to the MPD is connected. - /// - public bool IsConnected { get { return (_tcpClient != null) && _tcpClient.Connected; } } - /// - /// The version of the MPD. - /// - public string Version { get { return _version; } } - private bool _autoConnect = false; - /// - /// If a connection should be established when a command is to be - /// executed in disconnected state. - /// - public bool AutoConnect - { - get{ return _autoConnect; } - set { _autoConnect = value; } - } - - /// - /// Creates a new MpdConnection. - /// - /// The IPEndPoint of the MPD server. public MpcConnection(IPEndPoint server) { - Server = server; - } - /// - /// The IPEndPoint of the MPD server. - /// - /// When a conenction to a MPD server is already established. - public IPEndPoint Server - { - get { return _ipEndPoint; } - set - { - if (IsConnected) - throw new AlreadyConnectedException(); + if (IsConnected) return; - _ipEndPoint = value; - - ClearConnectionFields(); - } + ClearConnectionFields(); + _server = server; } - - /// - /// Connects to the MPD server who's IPEndPoint was set in the Server property. - /// - /// If no IPEndPoint was set to the Server property. + + public bool IsConnected => (_tcpClient != null) && _tcpClient.Connected; + public string Version => _version; + public async Task ConnectAsync() { - if (_ipEndPoint == null) + if (_server == null) throw new InvalidOperationException("Server IPEndPoint not set."); if (IsConnected) @@ -93,7 +54,7 @@ namespace LibMpc _tcpClient = new TcpClient(); - await _tcpClient.ConnectAsync(_ipEndPoint.Address, _ipEndPoint.Port); + await _tcpClient.ConnectAsync(_server.Address, _server.Port); _networkStream = _tcpClient.GetStream(); @@ -116,10 +77,12 @@ namespace LibMpc /// /// Disconnects from the current MPD server. /// - public Task Disconnect() + private Task Disconnect() { if (_tcpClient == null) + { return Task.CompletedTask; + } _networkStream.Dispose(); ClearConnectionFields(); @@ -132,7 +95,7 @@ namespace LibMpc /// The command to execute. /// The MPD server response parsed into a basic object. /// If the command contains a space of a newline charakter. - public MpdResponse Exec(string command) + public async Task Exec(string command) { if (command == null) throw new ArgumentNullException("command"); @@ -141,7 +104,8 @@ namespace LibMpc if (command.Contains("\n")) throw new ArgumentException("command contains newline"); - CheckConnected(); + // TODO: Integrate connection status in MpdResponse + var connectionResult = await CheckConnectionAsync(); try { @@ -152,8 +116,7 @@ namespace LibMpc } catch (Exception) { - try { Disconnect(); } - catch (Exception) { } + try { await Disconnect(); } catch (Exception) { } return null; // TODO: Create Null Object for MpdResponse } } @@ -164,7 +127,7 @@ namespace LibMpc /// The arguments of the command. /// The MPD server response parsed into a basic object. /// If the command contains a space of a newline charakter. - public MpdResponse Exec(string command, string[] argument) + public async Task Exec(string command, string[] argument) { if (command == null) throw new ArgumentNullException("command"); @@ -183,7 +146,8 @@ namespace LibMpc throw new ArgumentException("argument[" + i + "] contains newline"); } - CheckConnected(); + // TODO: Integrate connection status in MpdResponse + var connectionResult = await CheckConnectionAsync(); try { @@ -200,21 +164,19 @@ namespace LibMpc } catch (Exception) { - try { Disconnect(); } catch (Exception) { } + try { await Disconnect(); } catch (Exception) { } throw; } } - private void CheckConnected() + private async Task CheckConnectionAsync() { if (!IsConnected) { - if (_autoConnect) - ConnectAsync(); - else - throw new NotConnectedException(); - } - + await ConnectAsync(); + } + + return IsConnected; } private void WriteToken(string token) @@ -262,10 +224,10 @@ namespace LibMpc private void ClearConnectionFields() { - _tcpClient?.Dispose(); - _networkStream?.Dispose(); - _reader?.Dispose(); _writer?.Dispose(); + _reader?.Dispose(); + _networkStream?.Dispose(); + _tcpClient?.Dispose(); _version = string.Empty; } }