Start the next song while one is playing - c#

i have a "Player" class, which is supposed to manage my global music player.
This also works so far. The class is at the bottom, if you have any suggestions for improvement, feel free to give it to us.
I want to start a second song while the current song ends.
So a FadeIn into the next song and a FadeOut from the current song, which makes the song quieter.
My approach at the moment is that one song is running in the "waveOutDevice1" object and the second one is waiting in the second object. And as soon as the current song is about to end, the second WavePlayer starts. But I don't know how I can react to it, as soon as the current song is about to end.
Do you have an idea or suggestions?
With kind regards
my Player class:
public class Player
{
#region Properties, Fields
private IWavePlayer waveOutDevice1;
private IWavePlayer waveOutDevice2;
private AudioFileReader fileReader1;
private AudioFileReader fileReader2;
public AudioFile CurrentSong { get; private set; }
public Playlist CurrentPlaylist { get; private set; }
public List<AudioFile> lstPastSongs { get; private set; }
public List<AudioFile> lstNextSongs { get; set; }
public PlaybackState PlaybackState { get; private set; }
public bool Muted { get; private set; }
private float OldVolume = 0.0f;
#endregion
public Player()
{
this.lstNextSongs = new List<AudioFile>();
this.lstPastSongs = new List<AudioFile>();
}
#region Methods
public void Play(int index)
{
if (this.lstNextSongs.Count > 0 && index >= 0 && index < this.lstNextSongs.Count)
{
this.ResetFileReader();
this.CurrentSong = this.lstNextSongs[index];
this.CurrentPlaylist = this.CurrentSong.Playlist;
this.lstNextSongs.RemoveAt(index);
this.fileReader1 = new AudioFileReader(this.CurrentSong.Path);
this.waveOutDevice1 = new WaveOut();
this.waveOutDevice1.PlaybackStopped += WaveOutDevice1_PlaybackStopped;
this.waveOutDevice1.Init(this.fileReader1);
this.PlaybackState = PlaybackState.Playing;
this.waveOutDevice1.Play();
}
}
private void WaveOutDevice1_PlaybackStopped(object sender, StoppedEventArgs e)
{
this.Next();
}
private void ResetFileReader()
{
if (this.fileReader1 != null)
{
this.fileReader1.Dispose();
this.fileReader1 = null;
}
if (this.fileReader2 != null)
{
this.fileReader2.Dispose();
this.fileReader2 = null;
}
if(this.waveOutDevice1 != null)
{
this.waveOutDevice1.Dispose();
this.waveOutDevice1 = null;
}
if(this.waveOutDevice2 != null)
{
this.waveOutDevice2.Dispose();
this.waveOutDevice2 = null;
}
}
public void Pause()
{
if(this.waveOutDevice1 != null)
if (this.waveOutDevice1.PlaybackState == PlaybackState.Playing)
this.waveOutDevice1.Pause();
if(this.waveOutDevice2 != null)
if (this.waveOutDevice2.PlaybackState == PlaybackState.Playing)
this.waveOutDevice2.Pause();
this.PlaybackState = PlaybackState.Paused;
}
public void Continue()
{
if (this.waveOutDevice1 != null)
if (this.waveOutDevice1.PlaybackState == PlaybackState.Paused)
this.waveOutDevice1.Play();
if (this.waveOutDevice2 != null)
if (this.waveOutDevice2.PlaybackState == PlaybackState.Paused)
this.waveOutDevice2.Play();
this.PlaybackState = PlaybackState.Playing;
}
public void Next()
{
if(this.lstNextSongs.Count > 0)
{
if (this.CurrentSong != null)
this.lstPastSongs.Add(this.CurrentSong);
if (GlobalSettings.Shuffle)
{
System.Random random = new System.Random();
int randomNumber = random.Next(0, this.lstNextSongs.Count - 1);
this.Play(randomNumber);
}
else
this.Play(0);
}
else
{
if(GlobalSettings.Replay)
if(GlobalSettings.CurrentPlaylist != null)
for (int i = 0; i < GlobalSettings.CurrentPlaylist.panPlaylist.SongPlaylist.NumberOfSongs; i++)
this.lstNextSongs.AddRange(GlobalSettings.CurrentPlaylist.panPlaylist.SongPlaylist.AllSongs);
}
}
public void Previous()
{
if(this.CurrentSong == null)
{
if(this.lstPastSongs.Count > 0)
{
this.lstNextSongs.Insert(0, this.lstPastSongs[this.lstPastSongs.Count - 1]);
this.lstPastSongs.RemoveAt(this.lstPastSongs.Count - 1);
this.Play(0);
}
}
else
{
if(this.fileReader1 != null)
this._Previous(this.waveOutDevice1, this.fileReader1);
else if(this.fileReader2 != null)
this._Previous(this.waveOutDevice2, this.fileReader2);
}
}
private void _Previous(IWavePlayer waveOutDevice, AudioFileReader fileReader)
{
if (fileReader.CurrentTime.Seconds >= 10 || this.lstPastSongs.Count == 0)
{
waveOutDevice.Pause();
fileReader.CurrentTime = new System.TimeSpan(0, 0, 0);
waveOutDevice.Play();
}
else
{
this.lstNextSongs.Insert(0, this.CurrentSong);
this.lstNextSongs.Insert(0, this.lstPastSongs[this.lstPastSongs.Count - 1]);
this.lstPastSongs.RemoveAt(this.lstPastSongs.Count - 1);
this.Play(0);
}
}
public void SetVolume(int Volume)
{
if (Volume > -1 && Volume < 101)
{
float vol = (float)Volume / 100;
if (this.fileReader1 != null)
this.fileReader1.Volume = vol;
if (this.fileReader2 != null)
this.fileReader2.Volume = vol;
this.Muted = false;
}
}
public void Mute()
{
if(this.Muted)
{
if(this.fileReader1 != null)
{
this.fileReader1.Volume = this.OldVolume;
this.Muted = false;
}
else if(this.fileReader2 != null)
{
this.fileReader2.Volume = this.OldVolume;
this.Muted = false;
}
}
else
{
this.Muted = true;
if(this.fileReader1 != null)
{
this.OldVolume = this.fileReader1.Volume;
this.fileReader1.Volume = 0;
}
else if(this.fileReader2 != null)
{
this.OldVolume = this.fileReader2.Volume;
this.fileReader2.Volume = 0;
}
}
}
#endregion
}

If you can get the duration of the song when it starts playing, you can set a timer for duration - fadeInTime and start your fade when the timer fires.

Another approach is to use a single wave out device and MixingSampleProvider to add in the second song as a new input to the mixer as the first one is ending. You can do this by creating your own wrapper ISampleProvider whose Read method can keep accurate track of where you are up to.

Related

c# linked lists, return multiple entries

I am trying to create a linked list, with like a Bird Survey type thing, and I am trying to have an end output where it returns all the species I've entered and how many times I've entered each one. Right now the output counts each different bird that I enter, but it doesn't give a separate count at the end of the report for each one that I've entered and I'm not sure how to do that. I've been fussing with this for hours now, I feel like I'm super close, please help if you can <3... Here is the code:
class Program
{
public class Node
{
/* You add the type of bird and a count of
* how many times that bird is said.
* Then you use a method to print out
* the types of birds and how many times each bird was said*/
public string bird;
public Node next;
public Node(string i)
{
bird = i;
next = null;
}
public void getReport()
{
Console.Write("|" + bird + "|->");
if (next != null)
{
next.getReport();
}
}
public void AddToEnd(string bird)
{
if (next == null)
{
next = new Node(bird);
}
else
{
next.AddToEnd(bird);
}
}
public class BirdList
{
public Node headNode;
public BirdList()
{
headNode = null;
}
public void AddToEnd(string bird) //method to add to the end of a list
{
if (headNode == null)
{
headNode = new Node(bird);
}
else
{
headNode.AddToEnd(bird);
}
}
public void AddToBeginning(string bird) //add to the beginning of a list
{
if (headNode == null)
{
headNode = new Node(bird);
}
else
{
Node temp = new Node(bird);
temp.next = headNode;
headNode = temp;
}
}
public void getReport()
{
if (headNode != null)
{
headNode.getReport();
}
}
public int getCount(string bird)
{
Node current = headNode;
int count = 0;
while (current!= null)
{
if (current.bird == bird)
{
count++;
}
current = current.next;
}
return count;
}
}
static void Main(string[] args)
{
BirdList birdList = new BirdList();
string userInput = "";
while (userInput != "done")
{
Console.WriteLine("Please enter a bird:");
userInput = Console.ReadLine();
if (userInput == "done")
{
break;
}
birdList.AddToEnd(userInput);
Console.WriteLine(birdList.getCount(userInput));
}
birdList.getReport();
Console.ReadLine();
And the output looks something like this:
when you run the report function it does not seem to be instructed to actually count the amount of every individual item it encounters.
The straightforward way of solving this is to iterate over the list and to save every individual string it encounters into a dictionary, and then to increment the value when you find that the dictionary already contains a duplicate.
Node n = birdList.headNode;
Dictionary<string,int> dict = new Dictionary<string,int>();
while(n!=null){
if(dict.ContainsKey(n.bird))
{
dict[n.bird]++;
}else{
dict.Add(n.bird,1);
}
n=n.next;
}
The dict should contain all the birds as key, with their amounts as values.
Your code was good, it was just missing a few things. For one, each bird needs a counter. Also there is no need to add the bird in again once it is in the list. I rewrote your code a bit, and placed comments in for you to see. here you go:
class Program
{
public class Node
{
/* You add the type of bird and a count of
* how many times that bird is said.
* Then you use a method to print out
* the types of birds and how many times each bird was said*/
public string bird;
public Node next;
public int count; // each bird needs a counter
public Node(string i)
{
bird = i;
next = null;
count = 0;
}
public void getReport()
{
Console.Write("|" + bird + "|->" + count );
if (next != null)
{
next.getReport();
}
}
public void AddToEnd(string bird)
{
if (this.bird != bird) // if the bird is already in the list, it wont add it in again.
{
if (next == null)
{
next = new Node(bird);
}
else
{
next.AddToEnd(bird);
}
}
}
public class BirdList
{
public Node headNode;
public BirdList()
{
headNode = null;
}
public void AddToEnd(string bird) //method to add to the end of a list if bird is not already in the list.
{
if (headNode == null)
{
headNode = new Node(bird);
}
else
{
headNode.AddToEnd(bird);
}
}
public void AddToBeginning(string bird) //add to the beginning of a list
{
if (headNode == null)
{
headNode = new Node(bird);
}
else
{
Node temp = new Node(bird);
temp.next = headNode;
headNode = temp;
}
}
public void getReport()
{
if (headNode != null)
{
headNode.getReport();
}
}
public int getCount(string bird)
{
Node current = headNode;
int count = 0;
while (current != null)
{
if (current.bird == bird)
{
current.count++; // once the bird is found, increment the counter.
count = current.count; // set the birds counter to the count.
}
current = current.next;
}
return count;
}
}
static void Main(string[] args)
{
BirdList birdList = new BirdList();
string userInput = "";
while (userInput != "done")
{
Console.WriteLine("Please enter a bird:");
userInput = Console.ReadLine();
if (userInput == "done")
{
break;
}
birdList.AddToEnd(userInput);
Console.WriteLine(birdList.getCount(userInput));
}
birdList.getReport();
Console.ReadLine();
}
}
}

Network Map with full detail and hierarchy

I wrote a piece of code to run from the first IP address to the last and retrieve the MAC and Hostname of devices in my network.
But, i do not know how to get the hierachy of then. Information like what router is the device conected (via Cable of WiFi also). And some routers are not managed (they don't have IP - they are just "switchs").
First, i didn't think it was possible, since a "tracert" on the CMD does not show then, but when i call the "Network Complete Map" on Windows Control Panel, they get all the information i need - so there is a way. See the image below:
The "switchs" circled in red have no IP, the "TL-xxxx" are routers with DHCP turned of. The "gateway" is a server that has the DHCP and provides connection to the internet.
Thus far, i wrote the following code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Net;
using System.Runtime.InteropServices;
namespace Network
{
[Serializable] public sealed class Map
{
private bool mMARKED = true;
private long mDB = 0L;
private string mIP = string.Empty;
private string mMAC = string.Empty;
private string mBRAND = string.Empty;
private string mNAME = string.Empty;
public bool Save { get { return this.mMARKED; } set { this.mMARKED = value; } }
public long DBId { get { return this.mDB; } set { this.mDB = value; } }
public string IP { get { return this.mIP; } set { this.mIP = value; } }
public string MAC { get { return this.mMAC; } set { this.mMAC = value; } }
public string BRAND { get { return this.mBRAND; } set { this.mBRAND = value; } }
public string NAME { get { return this.mNAME; } set { this.mNAME = value; } }
}
[Serializable] public sealed class Scanner
{
public const string WebOUIFile = "http://standards-oui.ieee.org/oui.txt";
public const string LocalOUIFileName = "oui.txt";
private const long MaxOUIAge = (TimeSpan.TicksPerDay * 90L);
internal Dictionary<string, string> OUIList;
private List<Map> mDevices = new List<Map>(50);
public List<Map> Devices { get { return this.mDevices; } }
public static Scanner Scan;
public Thread Worker;
public bool AutoSave { get; set; }
private string Node;
private byte mInitial;
public static string UploadPath { get; set; }
public byte Initial { get { return this.mInitial; } set { this.mInitial = value; } }
public byte Current { get; private set; }
public byte Limit { get; set; }
public bool Working { get; private set; }
public string Errors;
public string Message { get; private set; }
public bool UpdatingOUI { get; private set; }
public void Interrupt()
{
this.Working = false;
if (this.Worker != null)
{
this.Worker.Abort();
this.Worker = null;
}
this.Node = string.Empty;
this.Initial = 0;
this.Current = 0;
this.Limit = 0;
this.Working = false;
}
public void ToDestroy()
{
this.Interrupt();
this.Errors = string.Empty;
this.Message = string.Empty;
}
public void Stop(bool immediate) { if (immediate) { this.Interrupt(); } }
[DllImport("iphlpapi.dll", SetLastError = true, CharSet = CharSet.Auto)] private static extern int SendARP(int DestIP, int SrcIP, out long pMacAddr, ref int PhyAddrLen);
public void ToBegin() { }
public void Stop() { this.Stop(true); }
private static int IPToInt(string Expression)
{
try
{
byte[] IPAddress = System.Net.IPAddress.Parse(Expression).GetAddressBytes();
return (Convert.ToInt32(IPAddress[3]) << 24) | (Convert.ToInt32(IPAddress[2]) << 16) | (Convert.ToInt32(IPAddress[1]) << 8) | Convert.ToInt32(IPAddress[0]);
} catch { return 0; }
}
private Map GetBasics(string IPString)
{
int res = Scanner.IPToInt(IPString);
if (res > 0)
{
long mem = 0L;
int PhyAddrLen = 6;
if (Scanner.SendARP(res, 0, out mem, ref PhyAddrLen) == 0)
{
Map dev = new Map();
byte[] macbytes = BitConverter.GetBytes(mem);
dev.IP = IPString;
string Tmp = BitConverter.ToString(macbytes, 0, 3);
if (this.OUIList != null && this.OUIList.ContainsKey(Tmp)) { dev.BRAND = this.OUIList[Tmp]; }
dev.MAC = Tmp + "-" + BitConverter.ToString(macbytes, 3, 3);
try { dev.NAME = Dns.GetHostEntry(IPString).HostName.ToLower(); } catch { dev.NAME = "unknow"; }
return dev;
}
}
return null;
}
private static void GetNode(ref string IP, ref string Node, ref byte Device)
{
string[] NodeComp = IP.Split('.');
Node = NodeComp[0] + "." + NodeComp[1] + "." + NodeComp[2] + ".";
Device = Convert.ToByte(NodeComp[3]);
}
public static Dictionary<string, string> DonwloadOUTFile(bool ForceUpdate = true)
{
Dictionary<string, string> List = null;
try
{
string Aux = Scanner.UploadPath;
if (Aux == null) { Aux = string.Empty; }
else if (Aux != string.Empty)
{
string Tmp = Aux + "~" + Scanner.LocalOUIFileName;
Aux += Scanner.LocalOUIFileName;
bool FileExists = File.Exists(Aux);
if (FileExists && ((DateTime.UtcNow.Ticks - (new FileInfo(Aux)).CreationTimeUtc.Ticks) > Scanner.MaxOUIAge))
{
File.Delete(Aux);
ForceUpdate = true;
}
string Aux2 = string.Empty;
if (ForceUpdate)
{
List = new Dictionary<string, string>(25000);
using (WebClient Downloader = new WebClient()) { Downloader.DownloadFile(Scanner.WebOUIFile, Tmp); }
using (StreamReader Reader = new StreamReader(Tmp))
using (StreamWriter Writer = new StreamWriter(Aux))
{
do
{
Aux = Reader.ReadLine();
if (Aux.ToLower().Contains("(hex)"))
{
Aux2 = Aux.Substring(0, 8).ToUpper();
Aux = Aux.Substring(Aux.LastIndexOf('\t') + 1);
if (!List.ContainsKey(Aux2))
{
List.Add(Aux2, Aux);
Writer.WriteLine(Aux2 + "\t" + Aux);
}
}
} while (Reader.Peek() >= 0);
Reader.Close();
Writer.Close();
}
try { File.Delete(Tmp); } catch { /* NOTHING */ }
}
else if (FileExists)
{
List = new Dictionary<string, string>(25000);
using (StreamReader Reader = new StreamReader(Aux))
{
do
{
Aux = Reader.ReadLine();
if (Aux != null && Aux.Length > 9)
{
Aux2 = Aux.Substring(0, 8);
if (!List.ContainsKey(Aux2)) { List.Add(Aux2, Aux.Substring(9)); }
}
} while (Reader.Peek() >= 0);
Reader.Close();
}
}
}
}
catch
{
if (List != null) { List.Clear(); }
List = null;
}
return List;
}
private void ReadScaner()
{
this.UpdatingOUI = true;
try { this.OUIList = Scanner.DonwloadOUTFile(ForceUpdate: false); } catch { /* NOTHING */ }
this.UpdatingOUI = false;
if (this.OUIList == null || this.OUIList.Count == 0) { this.Errors += "\nErrorOUIFileDownload"; }
Map Dev = null;
this.Current = this.Initial;
if (this.Limit < this.Initial)
{
Dev = this.GetBasics(this.Node + this.Initial.ToString());
if (Dev != null) { this.Devices.Add(Dev); }
}
else
{
bool ToAdd = true;
while (this.Current <= this.Limit)
{
Dev = this.GetBasics(this.Node + this.Current.ToString());
this.Current += 1;
if (Dev != null)
{
ToAdd = true;
foreach (Map iDev in this.Devices)
{
if (iDev.MAC == Dev.MAC)
{
ToAdd = false;
break;
}
}
if (ToAdd) { this.Devices.Add(Dev); }
}
}
}
this.Message = "Finished!";
this.Interrupt();
}
public void GetRange(string IPInitial, byte Limit, bool AutoSave = true)
{
if (!this.Working)
{
this.AutoSave = AutoSave;
this.Working = true;
Scanner.GetNode(ref IPInitial, ref this.Node, ref this.mInitial);
this.Limit = Limit;
this.Worker = new Thread(this.ReadScaner);
this.Worker.IsBackground = true;
this.ToBegin();
this.Worker.Start();
}
}
public static void GetRange(bool AutoSave, string IPInitial, byte Limit)
{
if (Scanner.Scan == null)
{
Scanner.Scan = new Scanner();
Scanner.Scan.GetRange(IPInitial, Limit, AutoSave: AutoSave);
}
}
~Scanner()
{
if (this.OUIList != null)
{
this.OUIList.Clear();
this.OUIList = null;
}
}
}
}
How do i make that code able to get the hierarchy like windows does?

Xamarin Maps displays but doesn't update

I'm attempting to make a google map using Xamarin forms, the pins displays correctly and zooms in onto the user. It displays the inital map when the page starts, but when moving or zooming the map doesn't change and becomes grids if you zoom in enough. I can see my pin on the grid and everything, but I would like the map to load along with the pin.
public partial class IssueMap2 : ContentPage
{
public UIIssueVM Issue { get; set; }
public GeoLocation Location { get; set; }
public bool AllowPinMovment { get; set; }
private ExtendedMap.ExtendedMap map;
public Xamarin.Forms.Maps.Position OrgIssueLocation { get; set; }
bool IsGettingLocation = false;
bool bMapCtrlReady = false;
IGeolocator Locator;
public IssueMap2(UIIssueVM Issue, GeoLocation location)
{
AllowPinMovment = false;
this.Issue = Issue;
this.Location = location;
Title = "Map";
OrgIssueLocation = new Xamarin.Forms.Maps.Position(Issue.Latitude, Issue.Longitude);
Locator = CrossGeolocator.Current;
if (Locator.DesiredAccuracy != 100)
Locator.DesiredAccuracy = 100;
if (Device.RuntimePlatform != Device.WinPhone)
{
InitializeComponent();
map = new ExtendedMap.ExtendedMap()
{
IsShowingUser = true,
HeightRequest = 100,
WidthRequest = 960,
VerticalOptions = LayoutOptions.FillAndExpand
};
map.LongTap += OnMapLongTap;
map.Ready += MapCtrlReady;
slMap.Children.Add(map);
}
}
public void MapCtrlReady(object sender, EventArgs args)
{
bMapCtrlReady = true;
}
public void OnMapLongTap(object sender, ExtendedMap.TapEventArgs args)
{
if (AllowPinMovment == false)
return;
if (Issue == null)
return;
var pos = args.Position;
// Update Issue
Issue.Latitude = pos.Latitude;
Issue.Longitude = pos.Longitude;
Issue.Changed = true;
// Update Pin
map.Pins.Clear();
AddPin(pos, Issue.Title, Issue.Description);
}
protected void AddPin(Xamarin.Forms.Maps.Position pos, String Title, String Desc)
{
// MAP pin does not like it if labels are empty
if (Title.Length == 0)
Title = "-";
if (Desc.Length == 0)
Desc = "-";
var pin = new Pin
{
Type = PinType.Place,
Position = pos,
Label = Title,
Address = Desc
};
map.Pins.Add(pin);
}
protected override void OnAppearing()
{
if (Device.RuntimePlatform == Device.WinPhone)
{
aActIndicator.IsRunning = false;
aActIndicator.IsVisible = false;
if (Issue.IsNew == false)
{
var position = new Xamarin.Forms.Maps.Position(Issue.Latitude, Issue.Longitude);
AddPin(position, Issue.Title, Issue.Description);
MoveToPinLocation();
}
else // Issue is new
{
// Move to main location
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Xamarin.Forms.Maps.Position(Location.Latitude, Location.Longitude), Distance.FromMiles(1)));
// Get current location for new item
OnGetLocation();
}
}
}
protected override async void OnDisappearing()
{
if (Locator.IsListening)
{
await Locator.StopListeningAsync();
}
// Map controller crashes sometimes if we are to quick with exiting
await Task.Delay(500);
while (bMapCtrlReady == false)
{
await Task.Delay(500);
}
}
void OnButtonCenter(object sender, EventArgs args)
{
MoveToPinLocation();
}
void MoveToPinLocation()
{
double KmDistace = 0.5;
if (Issue != null)
{
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Xamarin.Forms.Maps.Position(Issue.Latitude, Issue.Longitude), Distance.FromKilometers(KmDistace)));
}
else
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Xamarin.Forms.Maps.Position(Location.Latitude, Location.Longitude), Distance.FromKilometers(KmDistace)));
}
void OnButtonMainLocation(object sender, EventArgs args)
{
double KmDistace = 0.5;
map.MoveToRegion(MapSpan.FromCenterAndRadius(new Xamarin.Forms.Maps.Position(Location.Latitude, Location.Longitude), Distance.FromKilometers(KmDistace)));
}
void OnButtonGetLocation(object sender, EventArgs args)
{
OnGetLocation();
}
async void OnGetLocation()
{
if (IsGettingLocation == true)
return; // already getting location
try
{
if (Locator.IsListening == true)
{
await Locator.StopListeningAsync();
}
if (Locator.IsGeolocationAvailable == false)
{
lbPosText.Text = "GeoLocation is not available.";
this.ForceLayout();
return;
}
if (Locator.IsGeolocationEnabled == false)
{
lbPosText.Text = "GeoLocation is not enabled.";
this.ForceLayout();
return;
}
IsGettingLocation = true;
IsBusy = true;
slCommands.IsVisible = false;
aActIndicator.IsVisible = true;
aActIndicator.IsRunning = true;
lbPosText.Text = "Searching for GPS location...";
this.ForceLayout();
TimeSpan timeSpan = TimeSpan.FromTicks(120 * 1000);
var position = await Locator.GetPositionAsync(timeSpan);
// Update Issue Position
Issue.Latitude = position.Latitude;
Issue.Longitude = position.Longitude;
Issue.Changed = true;
// Update Pin Postion
var pos = new Xamarin.Forms.Maps.Position(Issue.Latitude, Issue.Longitude);
map.Pins.Clear();
AddPin(pos, Issue.Title, Issue.Description);
UpdateGPSLocationText();
aActIndicator.IsRunning = false;
aActIndicator.IsVisible = false;
IsGettingLocation = false;
IsBusy = false;
slCommands.IsVisible = true;
this.ForceLayout();
// Center map around pin
MoveToPinLocation();
}
catch (Exception /*ex*/)
{
aActIndicator.IsRunning = false;
aActIndicator.IsVisible = false;
IsGettingLocation = false;
IsBusy = false;
slCommands.IsVisible = true;
lbPosText.Text = "Unable to find position!";
lbPosText.IsVisible = true;
this.ForceLayout();
}
}
void UpdateGPSLocationText()
{
String text = String.Format("{0} x {1}", Issue.Longitude, Issue.Latitude);
lbPosText.Text = text;
}
}
}
Android extended map renderer
[assembly: ExportRenderer(typeof(ExtendedMap.ExtendedMap), typeof(ExtendedMapRenderer))]
namespace ExtendedMap.Android
{
public class ExtendedMapRenderer : MapRenderer, IOnMapReadyCallback
{
private GoogleMap _map;
public ExtendedMapRenderer()
{
}
public ExtendedMapRenderer(IntPtr javaReference, JniHandleOwnership jniHandleOwnership)
{
int x = 0;
x++;
}
private void InvokeOnMapReadyBaseClassHack(GoogleMap googleMap)
{
System.Reflection.MethodInfo onMapReadyMethodInfo = null;
Type baseType = typeof(MapRenderer);
foreach (var currentMethod in baseType.GetMethods(System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.DeclaredOnly))
{
if (currentMethod.IsFinal && currentMethod.IsPrivate)
{
if (string.Equals(currentMethod.Name, "OnMapReady", StringComparison.Ordinal))
{
onMapReadyMethodInfo = currentMethod;
break;
}
if (currentMethod.Name.EndsWith(".OnMapReady", StringComparison.Ordinal))
{
onMapReadyMethodInfo = currentMethod;
break;
}
}
}
if (onMapReadyMethodInfo != null)
{
onMapReadyMethodInfo.Invoke(this, new[] { googleMap });
}
}
void IOnMapReadyCallback.OnMapReady(GoogleMap googleMap)
{
InvokeOnMapReadyBaseClassHack(googleMap);
_map = googleMap;
if (_map != null)
{
_map = googleMap;
this.NativeMap = googleMap;
_map.MapClick += googleMap_MapClick;
_map.MapLongClick += googleMap_MapLongClick;
((ExtendedMap)Element).OnReady();
}
}
protected override void OnElementChanged(ElementChangedEventArgs<Map> e)
{
if (_map != null)
_map.MapClick -= googleMap_MapClick;
base.OnElementChanged(e);
if (Control != null)
((MapView)Control).GetMapAsync(this);
}
private void googleMap_MapClick(object sender, GoogleMap.MapClickEventArgs e)
{
((ExtendedMap)Element).OnTap(new Position(e.Point.Latitude, e.Point.Longitude));
}
private void googleMap_MapLongClick(object sender, GoogleMap.MapLongClickEventArgs e)
{
((ExtendedMap)Element).OnLongTap(new Position(e.Point.Latitude, e.Point.Longitude));
}
}
}
I would double check the Google Maps API key on the manifest of your application!
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzr3yCpVgSOXvTgri29nC6KqFbdO73QmoVQWEw" />
As well as your SHA-1 key of your keystore on the Google API Credential Dashboard.

Kruskal's Maze Algorithm - Only Working up to dimension 11x11

I am using https://courses.cs.washington.edu/courses/cse326/07su/prj2/kruskal.html psuedocode as reference when writing my code.
Code is in C#, and my code can only generate mazes up to 11x11, anything more than than it will run, seemingly, forever (e.g. 12x11 or 12x12 won't work)
Grid Properties are just storing the dimension of the size of the maze
public class GridProperties
{
private int xLength;
private int yLength;
public GridProperties(int xlength, int ylength)
{
xLength = xlength;
yLength = ylength;
}
public int getXLength()
{
return this.xLength;
}
public int getYLength()
{
return this.yLength;
}
}
Cell Properties generates the grid
public class CellProperties
{
private GridProperties Grid;
private bool topWall, bottomWall, rightWall, leftWall;
private int? xCoord, yCoord;
private CellProperties topCell, bottomCell, rightCell, leftCell;
private CellProperties topParentCell, bottomParentCell, rightParentCell, leftParentCell;
private HashSet<String> passageID = new HashSet<String>();
public CellProperties(GridProperties grid = null, int? targetXCoord = null, int? targetYCoord = null,
CellProperties tpCell = null, CellProperties bpCell = null,
CellProperties rpCell = null, CellProperties lpCell = null)
{
this.Grid = grid;
this.xCoord = targetXCoord;
this.yCoord = targetYCoord;
this.updatePassageID(this.xCoord.ToString() + this.yCoord.ToString());
this.topWall = true;
this.bottomWall = true;
this.rightWall = true;
this.leftWall = true;
this.topParentCell = tpCell;
this.bottomParentCell = bpCell;
this.rightParentCell = rpCell;
this.leftParentCell = lpCell;
this.topCell = this.setTopCell();
this.bottomCell = this.setBottomCell();
if (this.yCoord == 0)
{
this.rightCell = this.setRightCell();
}
this.leftCell = this.setLeftCell();
}
public CellProperties setTopCell()
{
if (this.Grid == null)
{
return null;
}
if (this.yCoord == this.Grid.getYLength() - 1)
{
return new CellProperties();
}
else
{
return new CellProperties(this.Grid, this.xCoord, this.yCoord + 1, null, this, null, null);
}
}
public CellProperties setBottomCell()
{
if (this.yCoord == 0)
{
return new CellProperties();
}
else
{
return this.bottomParentCell;
}
}
public CellProperties setRightCell()
{
if (this.Grid == null)
{
return null;
}
if (this.xCoord == this.Grid.getXLength() - 1)
{
return new CellProperties();
}
else
{
return new CellProperties(this.Grid, this.xCoord + 1, this.yCoord, null, null, null, this);
}
}
public CellProperties setLeftCell( )
{
if (this.xCoord == 0)
{
return new CellProperties();
}
else
{
if (this.Grid == null)
{
return null;
}
if (this.yCoord == 0)
{
return this.leftParentCell;
}
else
{
CellProperties buffer = this.bottomCell;
for (int depth = 0; depth < this.yCoord - 1; depth++)
{
buffer = buffer.bottomParentCell;
}
buffer = buffer.leftParentCell.topCell;
for (int depth = 0; depth < this.yCoord - 1; depth++)
{
buffer = buffer.topCell;
}
buffer.rightCell = this;
return buffer;
}
}
}
public GridProperties getGrid()
{
return this.Grid;
}
public CellProperties getBottomCell()
{
return this.bottomCell;
}
public CellProperties getTopCell()
{
return this.topCell;
}
public CellProperties getLeftCell()
{
return this.leftCell;
}
public CellProperties getRightCell()
{
return this.rightCell;
}
public void setBottomWall(Boolean newBottomWall)
{
this.bottomWall = newBottomWall;
}
public void setTopWall(Boolean newTopWall)
{
this.topWall = newTopWall;
}
public void setLeftWall(Boolean newLeftWall)
{
this.leftWall = newLeftWall;
}
public void setRightWall(Boolean newRightWall)
{
this.rightWall = newRightWall;
}
public Boolean getBottomWall()
{
return this.bottomWall;
}
public Boolean getTopWall()
{
return this.topWall;
}
public Boolean getLeftWall()
{
return this.leftWall;
}
public Boolean getRightWall()
{
return this.rightWall;
}
public void updatePassageID(String newPassageID)
{
this.passageID.Add(newPassageID);
}
public void setPassageID(HashSet<String> newPassageID)
{
this.passageID = new HashSet<string>(newPassageID);
}
public HashSet<String> getPassageID()
{
return this.passageID;
}
}
This class is where the magic happens ... or suppose to happen.
public class KruskalMazeGenerator
{
private CellProperties Cell0x0;
private CellProperties CurrentCell;
private CellProperties NeighbourCell;
private int WallsDown;
private int TotalNumberOfCells;
private Random rnd = new Random();
private int rndXCoord, rndYCoord;
private String rndSide;
public KruskalMazeGenerator(CellProperties cell0x0)
{
Cell0x0 = cell0x0;
WallsDown = 0;
TotalNumberOfCells = Cell0x0.getGrid().getXLength() * Cell0x0.getGrid().getYLength();
}
public void selectRandomCellCoords()
{
this.rndXCoord = rnd.Next(0, this.Cell0x0.getGrid().getXLength());
this.rndYCoord = rnd.Next(0, this.Cell0x0.getGrid().getYLength());
}
public void selectRandomSide(String[] possibleSides)
{
if (possibleSides.Length != 0)
{
this.rndSide = possibleSides[rnd.Next(0, possibleSides.Length)];
}
}
public void selectRandomCurrentCell()
{
this.selectRandomCellCoords();
this.CurrentCell = this.Cell0x0;
for (int xWalk = 0; xWalk < this.rndXCoord; xWalk++)
{
this.CurrentCell = this.CurrentCell.getRightCell();
}
for (int xWalk = 0; xWalk < this.rndYCoord; xWalk++)
{
this.CurrentCell = this.CurrentCell.getTopCell();
}
}
public CellProperties checkWallBetweenCurrentAndNeighbour(List<String> possibleSides)
{
if (this.rndSide == "top")
{
if (this.CurrentCell.getTopCell() == null || this.CurrentCell.getTopCell().getGrid() == null)
{
possibleSides.Remove("top");
this.selectRandomSide(possibleSides.ToArray());
return this.checkWallBetweenCurrentAndNeighbour(possibleSides);
}
return this.CurrentCell.getTopCell();
}
else if (this.rndSide == "bottom")
{
if (this.CurrentCell.getBottomCell() == null || this.CurrentCell.getBottomCell().getGrid() == null)
{
possibleSides.Remove("bottom");
this.selectRandomSide(possibleSides.ToArray());
return this.checkWallBetweenCurrentAndNeighbour(possibleSides);
}
return this.CurrentCell.getBottomCell();
}
else if (this.rndSide == "left")
{
if (this.CurrentCell.getLeftCell() == null || this.CurrentCell.getLeftCell().getGrid() == null)
{
possibleSides.Remove("left");
this.selectRandomSide(possibleSides.ToArray());
return this.checkWallBetweenCurrentAndNeighbour(possibleSides);
}
return this.CurrentCell.getLeftCell();
}
else if (this.rndSide == "right")
{
if (this.CurrentCell.getRightCell() == null || this.CurrentCell.getRightCell().getGrid() == null)
{
possibleSides.Remove("right");
this.selectRandomSide(possibleSides.ToArray());
return this.checkWallBetweenCurrentAndNeighbour(possibleSides);
}
return this.CurrentCell.getRightCell();
}
return null;
}
public void selectRandomNeigbhourCell()
{
this.selectRandomSide(new String[4] { "top", "bottom", "left", "right" });
this.NeighbourCell = this.checkWallBetweenCurrentAndNeighbour(new List<String>(new String[4] { "top", "bottom", "left", "right" }));
}
public void checkForDifferentPassageID()
{
if (!this.CurrentCell.getPassageID().SetEquals(this.NeighbourCell.getPassageID()))
{
if (this.rndSide == "top")
{
this.CurrentCell.setTopWall(false);
this.NeighbourCell.setBottomWall(false);
this.unionAndResetPassageID();
this.WallsDown += 1;
}
else if (this.rndSide == "bottom")
{
this.CurrentCell.setBottomWall(false);
this.NeighbourCell.setTopWall(false);
this.unionAndResetPassageID();
this.WallsDown += 1;
}
else if (this.rndSide == "left")
{
this.CurrentCell.setLeftWall(false);
this.NeighbourCell.setRightWall(false);
this.unionAndResetPassageID();
this.WallsDown += 1;
}
else if (this.rndSide == "right")
{
this.CurrentCell.setRightWall(false);
this.NeighbourCell.setLeftWall(false);
this.unionAndResetPassageID();
this.WallsDown += 1;
}
}
}
public void unionAndResetPassageID()
{
HashSet<String> oldCurrentPassageID = new HashSet<String>(this.CurrentCell.getPassageID());
HashSet<String> oldNeighbourPassageID = new HashSet<String>(this.NeighbourCell.getPassageID());
HashSet <String> newPassageID = new HashSet<String>();
newPassageID = this.CurrentCell.getPassageID();
newPassageID.UnionWith(this.NeighbourCell.getPassageID());
CellProperties xwalkCell = new CellProperties();
CellProperties ywalkCell = new CellProperties();
for (int xWalk = 0; xWalk < this.Cell0x0.getGrid().getXLength(); xWalk++)
{
xwalkCell = xWalk == 0 ? this.Cell0x0 : xwalkCell.getRightCell();
for (int yWalk = 0; yWalk < this.Cell0x0.getGrid().getYLength(); yWalk++)
{
xwalkCell.setBottomWall(xWalk == 0 && yWalk == 0 ? false : xwalkCell.getBottomWall());
xwalkCell.setBottomWall(xWalk == this.Cell0x0.getGrid().getXLength() - 1 && yWalk == this.Cell0x0.getGrid().getYLength() - 1 ? false : xwalkCell.getBottomWall());
ywalkCell = yWalk == 0 ? xwalkCell : ywalkCell.getTopCell();
if (ywalkCell.getPassageID().SetEquals(oldCurrentPassageID) ||
ywalkCell.getPassageID().SetEquals(oldNeighbourPassageID))
{
ywalkCell.setPassageID(newPassageID);
}
}
}
}
public CellProperties createMaze()
{
while (this.WallsDown < this.TotalNumberOfCells - 1)
{
this.selectRandomCurrentCell();
this.selectRandomNeigbhourCell();
if (this.NeighbourCell != null)
{
this.checkForDifferentPassageID();
}
}
return this.Cell0x0;
}
}
then this is my visual representation class
public class drawGrid : CellProperties
{
private CellProperties Cell0x0 = new CellProperties();
private CellProperties yWalkBuffer = new CellProperties();
private CellProperties xWalkBuffer = new CellProperties();
private String bottomWall = "";
private String topWall = "";
private String leftAndrightWalls = "";
public drawGrid(CellProperties cell0x0)
{
Cell0x0 = cell0x0;
}
private void WallDrawingReset()
{
this.bottomWall = "\n";
this.topWall = "\n";
this.leftAndrightWalls = "\n";
}
private void Draw()
{
// draw bottom wall
{
if (this.bottomWall == "\n")
{
Console.Write("");
}
else
{
Console.Write(this.bottomWall);
}
}
Console.Write(this.leftAndrightWalls);
// draw top wall
{
if (topWall == "\n")
{
Console.Write("");
}
else
{
Console.Write(this.topWall);
}
}
}
public void yWalk()
{
for (int yWalk = 0; yWalk < this.Cell0x0.getGrid().getYLength(); yWalk++)
{
this.yWalkBuffer = yWalk == 0 ? this.Cell0x0 : this.yWalkBuffer.getTopCell();
this.WallDrawingReset();
this.xWalk(yWalk);
this.Draw();
}
}
private void xWalk(int yWalk)
{
for (int xWalk = 0; xWalk < this.Cell0x0.getGrid().getXLength(); xWalk++)
{
this.xWalkBuffer = xWalk == 0 ? this.yWalkBuffer : this.xWalkBuffer.getRightCell();
if (yWalk == 0)
{
this.bottomWall = xWalkBuffer.getBottomWall() ? this.bottomWall + "----" : this.bottomWall + " ";
this.topWall = xWalkBuffer.getTopWall() ? this.topWall + "----" : this.topWall + " ";
}
else
{
this.topWall = this.xWalkBuffer.getTopWall() ? this.topWall + "----" : this.topWall + " ";
}
if (xWalk == 0)
{
leftAndrightWalls = this.xWalkBuffer.getLeftWall() ? this.leftAndrightWalls + "| " : this.leftAndrightWalls + " ";
leftAndrightWalls = this.xWalkBuffer.getRightWall() ? this.leftAndrightWalls + "| " : this.leftAndrightWalls + " ";
}
else
{
leftAndrightWalls = this.xWalkBuffer.getRightWall() ? this.leftAndrightWalls + "| " : this.leftAndrightWalls + " ";
}
}
}
}
this is how i call them
class Program
{
static void Main(string[] args)
{
{
CellProperties cell = new CellProperties(new GridProperties(12, 11), 0, 0, null, null, null, null);
drawGrid draw = new drawGrid(cell);
draw.yWalk();
KruskalMazeGenerator kmaze = new KruskalMazeGenerator(cell);
cell = kmaze.createMaze();
Console.WriteLine("Final");
draw = new drawGrid(cell);
draw.yWalk();
}
Console.ReadKey();
}
}
Since I got you guys here, please don't mind pitching in what I can improve on as in coding style and other things that you are displeased with.
Thanks in advance.
Error seems to be here:
this.updatePassageID(this.xCoord.ToString() + this.yCoord.ToString());
Image those two scenarios:
xCoord = 1 and yCoord = 11.
xCoord = 11 and yCoord = 1.
both those result in newPassageID of 111.
So simply change the line to
this.updatePassageID(this.xCoord.ToString() + "|" + this.yCoord.ToString());
or written more sexy:
this.updatePassageID($"{xCoord}|{yCoord}");
With this you will receive
1|11 for the first scenario and 11|1 for the second which differs.
Edit based on comments:
I saw that your code is looping endlessly in the method createMaze. This method calls a method called checkForDifferentPassageID in there you check if two collections are equal or not. Once I saw that those collections are of type HashSet<string>, I thought that maybe your strings you put into the HashSet arent as unique as you think they are and there we go. So overall it took me like 10 minutes.

Performance issues with repeatable loops as control part

In my application, i need to show made calls to the user. The user can arrange some filters, according to what they want to see. The problem is that i find it quite hard to filter the calls without losing performance. This is what i am using now :
private void ProcessFilterChoice()
{
_filteredCalls = ServiceConnector.ServiceConnector.SingletonServiceConnector.Proxy.GetAllCalls().ToList();
if (cboOutgoingIncoming.SelectedIndex > -1)
GetFilterPartOutgoingIncoming();
if (cboInternExtern.SelectedIndex > -1)
GetFilterPartInternExtern();
if (cboDateFilter.SelectedIndex > -1)
GetFilteredCallsByDate();
wbPdf.Source = null;
btnPrint.Content = "Pdf preview";
}
private void GetFilterPartOutgoingIncoming()
{
if (cboOutgoingIncoming.SelectedItem.ToString().Equals("Outgoing"))
for (int i = _filteredCalls.Count - 1; i > -1; i--)
{
if (_filteredCalls[i].Caller.E164.Length > 4 || _filteredCalls[i].Caller.E164.Equals("0"))
_filteredCalls.RemoveAt(i);
}
else if (cboOutgoingIncoming.SelectedItem.ToString().Equals("Incoming"))
for (int i = _filteredCalls.Count - 1; i > -1; i--)
{
if (_filteredCalls[i].Called.E164.Length > 4 || _filteredCalls[i].Called.E164.Equals("0"))
_filteredCalls.RemoveAt(i);
}
}
private void GetFilterPartInternExtern()
{
if (cboInternExtern.SelectedItem.ToString().Equals("Intern"))
for (int i = _filteredCalls.Count - 1; i > -1; i--)
{
if (_filteredCalls[i].Called.E164.Length > 4 || _filteredCalls[i].Caller.E164.Length > 4 || _filteredCalls[i].Caller.E164.Equals("0"))
_filteredCalls.RemoveAt(i);
}
else if (cboInternExtern.SelectedItem.ToString().Equals("Extern"))
for (int i = _filteredCalls.Count - 1; i > -1; i--)
{
if ((_filteredCalls[i].Called.E164.Length < 5 && _filteredCalls[i].Caller.E164.Length < 5) || _filteredCalls[i].Called.E164.Equals("0"))
_filteredCalls.RemoveAt(i);
}
}
private void GetFilteredCallsByDate()
{
DateTime period = DateTime.Now;
switch (cboDateFilter.SelectedItem.ToString())
{
case "Today":
period = DateTime.Today;
break;
case "Last week":
period = DateTime.Today.Subtract(new TimeSpan(7, 0, 0, 0));
break;
case "Last month":
period = DateTime.Today.AddMonths(-1);
break;
case "Last year":
period = DateTime.Today.AddYears(-1);
break;
default:
return;
}
for (int i = _filteredCalls.Count - 1; i > -1; i--)
{
if (_filteredCalls[i].Start < period)
_filteredCalls.RemoveAt(i);
}
}
_filtered calls is a list of "calls". Calls is a class that looks like this :
[DataContract]
public class Call
{
private User caller, called;
private DateTime start, end;
private string conferenceId;
private int id;
private bool isNew = false;
[DataMember]
public bool IsNew
{
get { return isNew; }
set { isNew = value; }
}
[DataMember]
public int Id
{
get { return id; }
set { id = value; }
}
[DataMember]
public string ConferenceId
{
get { return conferenceId; }
set { conferenceId = value; }
}
[DataMember]
public DateTime End
{
get { return end; }
set { end = value; }
}
[DataMember]
public DateTime Start
{
get { return start; }
set { start = value; }
}
[DataMember]
public User Called
{
get { return called; }
set { called = value; }
}
[DataMember]
public User Caller
{
get { return caller; }
set { caller = value; }
}
Can anyone direct me to a better solution or make some suggestions.
Try using a foreach loop instead of an explicit for loop with an iterator variable. If _filteredCalls is a List, then _filteredCalls[i] will take O(n) time. Using a foreach will use the built in iterator of the list and will likely get you a speed increase.
Edit: I see you are actually looping backward through _filteredCalls, and also modifying the list.
So something like this would be better:
_filteredCalls = _filteredCalls.Where(c => c.Caller.E164.Length > 4 || c.Caller.E164.Equals("0"))

Categories