Advertisement
Alior

C# side of call controller

Jun 6th, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 6.89 KB | None | 0 0
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using System.Threading;
  5. using System.Net.Sockets;
  6. using System;
  7. using System.Net;
  8. using System.Diagnostics;
  9.  
  10. public class CallController : MonoBehaviour
  11. {
  12.     private static CallController controller = null;
  13.     private static CallController Instance
  14.     {
  15.         get
  16.         {
  17.             return controller;
  18.         }
  19.     }
  20.  
  21.     [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
  22.     private static void Init()
  23.     {
  24.         var go = new GameObject("Call controller");
  25.         DontDestroyOnLoad(go);
  26.  
  27.         controller = go.AddComponent<CallController>();
  28.     }
  29.  
  30.     private interface IOnCompleteCommandHandler
  31.     {
  32.         void OnComplete(CallController callController);
  33.     }
  34.  
  35.     private abstract class Command
  36.     {
  37.         public virtual float CommandTimeout
  38.         {
  39.             get
  40.             {
  41.                 return 4.0f;
  42.             }
  43.         }
  44.  
  45.         public abstract void Execute(CallController callController, Socket socket);
  46.     }
  47.  
  48.     private class CallCommand : Command, IOnCompleteCommandHandler
  49.     {
  50.         private readonly string number;
  51.  
  52.         public CallCommand(string number)
  53.         {
  54.             this.number = number;
  55.         }
  56.  
  57.         public override void Execute(CallController callController, Socket socket)
  58.         {
  59.             UnityEngine.Debug.Log("Executing call command to number: " + number);
  60.             socket.Send(System.Text.Encoding.ASCII.GetBytes(string.Format("call {0}", number)));
  61.  
  62.             callController.IsCalling = true;
  63.         }
  64.  
  65.         void IOnCompleteCommandHandler.OnComplete(CallController callController)
  66.         {
  67.             callController.IsCalling = false;
  68.         }
  69.     }
  70.  
  71.     Thread controlThread;
  72.  
  73.     private volatile bool isRunning = true;
  74.  
  75.     private object commandLocker = new object();
  76.     private Command command = null;
  77.  
  78.     private object ipLocker = new object();
  79.     private string ip = "192.168.0.110";
  80.     public string Ip
  81.     {
  82.         get
  83.         {
  84.             lock (ipLocker)
  85.                 return ip;
  86.         }
  87.  
  88.         set
  89.         {
  90.             lock (ipLocker)
  91.                 ip = value;
  92.         }
  93.     }
  94.  
  95.  
  96.     private object isCallingLocker = new object();
  97.     private bool isCalling = false;
  98.     public bool IsCalling
  99.     {
  100.         get
  101.         {
  102.             lock (isCallingLocker)
  103.                 return isCalling;
  104.         }
  105.  
  106.         private set
  107.         {
  108.             lock (isCallingLocker)
  109.                 isCalling = value;
  110.         }
  111.     }
  112.  
  113.     private void Start()
  114.     {
  115.         controlThread = new Thread(ControlThread);
  116.         controlThread.IsBackground = true;
  117.         controlThread.Start();
  118.     }
  119.  
  120.     private void AddCommand(Command command)
  121.     {
  122.         lock (commandLocker)
  123.         {
  124.             if (this.command != null)
  125.             {
  126.                 UnityEngine.Debug.Log("There is a command. You can't assign another one while this one is not finished");
  127.                 return;
  128.             }
  129.  
  130.             this.command = command;
  131.         }
  132.     }
  133.  
  134.     public void Call(string number)
  135.     {
  136.         if (IsCalling)
  137.         {
  138.             UnityEngine.Debug.LogError("Can't call. We are already calling!");
  139.             return;
  140.         }
  141.  
  142.         AddCommand(new CallCommand(number));
  143.     }
  144.  
  145.     private void ControlThread()
  146.     {
  147.         byte[] buffer = new byte[65535];
  148.         while (isRunning)
  149.         {
  150.             Thread.Sleep(200);
  151.  
  152.             IPAddress ipAddress = default(IPAddress);
  153.             EndPoint endPoint = default(EndPoint);
  154.  
  155.             try
  156.             {
  157.                 ipAddress = IPAddress.Parse(Ip);
  158.                 endPoint = new IPEndPoint(ipAddress, 5551);
  159.             }
  160.             catch (System.Threading.ThreadAbortException abort)
  161.             {
  162.                 UnityEngine.Debug.Log("Exiting control thread");
  163.                 return;
  164.             }
  165.             catch (System.Exception ex)
  166.             {
  167.                 UnityEngine.Debug.LogException(ex);
  168.                 continue;
  169.             }
  170.  
  171.             Command commandToExecute = null;
  172.             lock (commandLocker)
  173.             {
  174.                 if (command == null)
  175.                     continue;
  176.  
  177.                 commandToExecute = command;
  178.                 command = null;
  179.             }
  180.  
  181.             try
  182.             {
  183.                 using (Socket socket = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp))
  184.                 {
  185.                     UnityEngine.Debug.Log("Executing command");
  186.  
  187.                     socket.Connect(endPoint);
  188.                     commandToExecute.Execute(this, socket);
  189.                     string receivedString = string.Empty;
  190.                     Stopwatch stopwatch = new Stopwatch();
  191.                     stopwatch.Start();
  192.                     do
  193.                     {
  194.                         if (socket.Available > 0)
  195.                         {
  196.                             int received = socket.Receive(buffer);
  197.                             if (received <= 0)
  198.                                 continue;
  199.  
  200.                             receivedString = System.Text.Encoding.UTF8.GetString(buffer, 0, received);
  201.  
  202.                             var callString = "calling";
  203.                             if (receivedString.StartsWith(callString))
  204.                             {
  205.                                 UnityEngine.Debug.Log("Reseting timeout. Got some result");
  206.                                 stopwatch.Reset();
  207.                                 stopwatch.Start();
  208.                             }
  209.  
  210.                             var finishString = "command finished";
  211.                             if (receivedString.StartsWith(finishString))
  212.                                 break;
  213.                         }
  214.  
  215.                         if (stopwatch.ElapsedMilliseconds > commandToExecute.CommandTimeout * 1000)
  216.                         {
  217.                             UnityEngine.Debug.LogError("Command has been timed out");
  218.                             break;
  219.                         }
  220.  
  221.                     } while (isRunning);
  222.  
  223.                     if (commandToExecute is IOnCompleteCommandHandler)
  224.                         (commandToExecute as IOnCompleteCommandHandler).OnComplete(this);
  225.  
  226.                     UnityEngine.Debug.Log("Command execution has finished");
  227.                 }
  228.             }
  229.             catch (System.Threading.ThreadAbortException abort)
  230.             {
  231.                 UnityEngine.Debug.Log("Exiting control thread");
  232.                 return;
  233.             }
  234.             catch (System.Exception ex)
  235.             {
  236.                 UnityEngine.Debug.LogError("Error executing command");
  237.             }
  238.         }
  239.     }
  240.  
  241.     private void OnDestroy()
  242.     {
  243.         isRunning = false;
  244.         if (controlThread != null)
  245.             controlThread.Abort();
  246.     }
  247. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement