private void ExecuteCommands() { bool terminating = Terminating; while (!terminating) { MPDSendable sendable = null; lock (m_Lock) { // Avoid using the property as it might break // threading. TODO: this could be neatly wrapped into // a method that returns a command or null if // terminating, but it's just cosmetics. terminating = m_Terminating; if (m_CommandQueue.Count > 0) { sendable = m_CommandQueue.Dequeue(); m_ThreadEvent.Reset(); } } if (!terminating) { if (sendable == null) { m_ThreadEvent.WaitOne(); } else { if (sendable is MPDCommand) { MPDCommand command = sendable as MPDCommand; UpdateThreadMessage(command); bool optimizeOut = false; optimizeOut = optimizeOut || (command.Op == "status" && m_StatusUpdateEnqueued); optimizeOut = optimizeOut || (command.Op == "stats" && m_StatsUpdateEnqueued); if (!optimizeOut) { SendCommand(command.FullSyntax); ReceiveResponse(command); } } else if (sendable is MPDCommandList) { MPDCommandList commands = sendable as MPDCommandList; if (commands.Nonempty) { SendCommand(sendable.FullSyntax); ReceiveResponse(sendable); } } } } } }
public void Send(MPDSendable sendable) { lock (m_Lock) { m_CommandQueue.Enqueue(sendable); m_ThreadEvent.Set(); } }
private void ReceiveResponse(MPDSendable sendable) { // TODO: if the server is really slow (Mopidy on an RPI for // example), we can get stuck here during shutdown. MPDResponseLine statusLine = GetResponseLine(); while (statusLine != null && !statusLine.IsStatus) { m_DataModel.NetworkLog?.LogResponseVerbose(statusLine); if (statusLine.Key != MPDResponseLine.Keyword.Unknown) { m_CurrentResponse.Add(statusLine); } statusLine = GetResponseLine(); } if (statusLine != null) { m_DataModel.NetworkLog?.LogResponseCompact(statusLine); if (statusLine.Key == MPDResponseLine.Keyword.ACK) { m_Parent.OnErrorMessageChanged(statusLine.Value); } else if (sendable is MPDCommand) { MPDCommand command = sendable as MPDCommand; if (command.Op == "currentsong") { ParseSongList(); Callback(m_DataModel.CurrentSong.OnCurrentSongResponseReceived); m_CurrentSongList.Clear(); } else if (command.Op == "listallinfo") { ParseSongList(); Callback(m_DataModel.Database.OnListAllInfoResponseReceived); m_CurrentSongList.Clear(); } else if (command.Op == "listplaylistinfo") { ParseSongList(); Callback(m_DataModel.SavedPlaylists.OnListPlaylistInfoResponseReceived, command.Argument1); m_CurrentSongList.Clear(); } else if (command.Op == "lsinfo") { Callback(m_DataModel.SavedPlaylists.OnLsInfoResponseReceived); } else if (command.Op == "outputs") { Callback(m_DataModel.OutputCollection.OnOutputsResponseReceived); } else if (command.Op == "playlistinfo") { ParseSongList(); Callback(m_DataModel.Playlist.OnPlaylistInfoResponseReceived); m_CurrentSongList.Clear(); } else if (command.Op == "search") { ParseSongList(); Callback(m_DataModel.AdvancedSearch.OnSearchResponseReceived); m_CurrentSongList.Clear(); } else if (command.Op == "stats") { Callback(m_DataModel.ServerStatus.OnStatsResponseReceived); } else if (command.Op == "status") { Callback(m_DataModel.ServerStatus.OnStatusResponseReceived); } } } m_CurrentResponse.Clear(); }