Add more code :-)

develop
LEdoian 3 years ago
parent 85066e197c
commit 35c4937632

@ -71,9 +71,9 @@ namespace QuickPlay
[NonSerialized]
public static readonly AppConfiguration defaultConfiguration = new AppConfiguration
{
playerConfigUrl = "file:///dev/null",
playerConfigUrl = "http://www.ms.mff.cuni.cz/~turinskp/znelky.ini",
};
public PlayerConfiguration GetPlayerConfig()
public async Task<PlayerConfiguration> GetPlayerConfig()
{
IPlayerConfigurationProvider cfgProvider;
if (playerConfigUrl.StartsWith("http:") || playerConfigUrl.StartsWith("https:"))
@ -84,11 +84,13 @@ namespace QuickPlay
string filename = playerConfigUrl.Substring("file://".Length);
var reader = new StreamReader(filename);
cfgProvider = new FileConfigurationProvider(reader);
} else if (playerConfigUrl == "default") {
cfgProvider = new DummyConfigurationProvider();
} else
{
throw new InvalidOperationException("Schema of player config URL not supported");
}
return cfgProvider.GetConfigurationAsync().Result; // Bad code, but hopefully we dont hang.
return await cfgProvider.GetConfigurationAsync();
}
// We want to compare by values.
@ -116,10 +118,10 @@ namespace QuickPlay
/// </summary>
public class PlayerConfiguration
{
public Dictionary<string, IPlayable> songs;
public string playerName;
public Dictionary<string, IPlayable> songs = new Dictionary<string, IPlayable>();
public string playerName = "";
public PlayerType playerType;
public string playerConnectionDetails; // This is opaque to this class, the player will make sense of it.
public string playerConnectionDetails = ""; // This is opaque to this class, the player will make sense of it.
public static PlayerConfiguration FromFile(StreamReader reader)
{
@ -199,7 +201,15 @@ namespace QuickPlay
sealed class DummyConfigurationProvider : IPlayerConfigurationProvider
{
public Task<PlayerConfiguration> GetConfigurationAsync() => null;
public Task<PlayerConfiguration> GetConfigurationAsync()
{
PlayerConfiguration cfg = new PlayerConfiguration();
cfg.playerType = PlayerType.MPD;
cfg.playerName = "Dummy player";
cfg.playerConnectionDetails = "127.0.0.1";
return Task.FromResult(cfg);
}
}
class Song: IPlayable

@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Android.Content;
// MPD client abstractions and simplifications
namespace QuickPlay
@ -16,6 +18,17 @@ namespace QuickPlay
float CurrentProgress { get; }
bool IsReady { get; }
void SetReasonableOptions(); //TODO
/// <summary>
/// Attach to the real player.
///
/// Since this operation can be asynchronous, we cannot put it in th
/// constructor. And this allows for some tweaks before connecting.
/// </summary>
/// <param name="context">
/// Context to run possible services from.
/// </param>
/// <returns></returns>
Task ConnectAsync(Context context);
}
/// <summary>
/// A simple dataclass to hold auxiliary data of the Playable objects.
@ -45,4 +58,11 @@ namespace QuickPlay
ILayout LayOut(ICollection<IPlayable> playables);
}
public class CannotConnectException: Exception
{
public CannotConnectException(string msg, Exception e) : base(msg, e) { }
public CannotConnectException(string msg) : base(msg) { }
public CannotConnectException() : base() { }
}
}

@ -29,14 +29,25 @@ namespace QuickPlay
private Android.Support.V7.Widget.RecyclerView recyclerView;
private IPlayer currentPlayer;
protected override void OnCreate(Bundle savedInstanceState)
protected override async void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
// App initialization
appConfig = AppConfiguration.loadConfiguration();
currentPlayer = appConfig.GetPlayerConfig().GetPlayer();
var playerConfig = await appConfig.GetPlayerConfig();
currentPlayer = playerConfig.GetPlayer();
try
{
await currentPlayer.ConnectAsync(this);
} catch (CannotConnectException e)
{
//TODO: View a toast with details and change some colors?
Console.WriteLine("This is bad.");
var t = Toast.MakeText(this, e.Message + ": " + e.InnerException.Message ?? "", ToastLength.Long);
t.Show();
}
// UI initialization
SetContentView(Resource.Layout.activity_main);
@ -87,5 +98,17 @@ namespace QuickPlay
}
return base.OnOptionsItemSelected(item);
}
/// <summary>
/// A callback for all player updates.
///
/// The update should be easy on resources, so no need to have separate
/// partial updates. This simply performs full update of the activity
/// state and views.
/// </summary>
public void OnPlayerUpdate()
{
throw new NotImplementedException("Activity should update.");
}
}
}

@ -11,7 +11,7 @@ using System.Text;
namespace QuickPlay
{
[Service(Exported = true, Name = "cz.ledoian.quickplay.mpdmonior")]
[Service]
class MpdMonitorService : Service
{
public override void OnCreate()

@ -6,11 +6,20 @@ using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Threading;
using MpcCore;
using System.Net.Sockets;
namespace QuickPlay
{
class MpdPlayer: IPlayer
{
MpcCoreClient mpd;
Thread serviceThread;
// MpcCore uses strings, so be it
string mpdIP, mpdPort;
public Dictionary<string, IPlayable> Songs { get; private set; }
public float CurrentProgress { get {
throw new NotImplementedException();
@ -29,8 +38,34 @@ namespace QuickPlay
}
public MpdPlayer(PlayerConfiguration cfg)
{
//TODO
// Populate known fields/properties
Songs = cfg.songs;
// NOTE: We separate the port by '@', since ':' could be part of IPv6 and we do not want to complicate parsing.
var connDetails = cfg.playerConnectionDetails.Split('@');
if (connDetails.Length > 2) throw new InvalidOperationException("Bad connection details");
mpdIP = connDetails[0];
mpdPort = connDetails.Length >=2 ? connDetails[1] : "6600"; // XXX: Unneccessary default here...
// Connecting and monitoring remote player is done in ConnectAsync.
}
public async Task ConnectAsync(Context ctx)
{
// Create a persistent connection
var conn = new MpcCoreConnection(mpdIP, mpdPort);
mpd = new MpcCoreClient(conn);
try
{
await mpd.ConnectAsync();
} catch (SocketException e)
{
throw new CannotConnectException("MPD connect failed", e);
}
// Start the monitoring service
Console.WriteLine("Hello! Will run thr.");
serviceThread = new Thread(() =>
{
var intent = new Intent(ctx, typeof(MpdMonitorService));
});
Console.WriteLine("Thread possibly started");
}
}
}
Loading…
Cancel
Save