HoloLens Unity program

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
5
down vote

favorite












I recently finished writing an HoloLens proof-of-concept program. It involves generating a user interface based on a connection with an OPC server. OPC involves industrial PLCs, one or more PLCs send their data to an OPC server, and the OPC-client connects and process all the information in the form of JSON.



An example is this:



string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";


The code I've made generates a canvas with a panel. All the variables inside the JSON code get added to the panel in the form of a UI/Image. The function updateTags() continuously updates the data that gets sent using UDP. It functions like I want it to, but I'm wondering if there's a way to reduce the amount of code.



using UnityEngine;
using System;
using System.IO;
using System.Text;
using System.Linq;
using HoloToolkit.Unity;
using System.Collections.Generic;
using UnityEngine.UI;
using Newtonsoft.Json;
using System.Collections;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;
#if !UNITY_EDITOR
using Windows.Networking.Sockets;
using Windows.Networking.Connectivity;
using Windows.Networking;

#endif

public class UDPCommunication : Singleton<UDPCommunication>

// Connection variables
private string port = "8000";
private string externalIP = "172.16.24.251";
private string externalPort = "8001";
public static int size = 0;
public static List<Dictionary<string, string>> abc = new List<Dictionary<string, string>>();
public static List<string> varz;
public GameObject mainGameobject;
public GameObject upd1;
public GameObject upd2;
public GameObject upd3;
public GameObject upd4;
public GameObject canvas;
public GameObject Panel;
public GameObject image;
public GameObject imagetext;
public GameObject numbertext;
public Image testimg;
private GameObject getImageTags;
private GameObject getNumberTags;
private GameObject canvases;
private GameObject panels;
private GameObject tiles;
private GameObject texts;
private float scaler = 0.0125f;
// UI/Text elements
const string TurnOn = "on";
private uint sliderVal;
// Sets up a Queue
private string receivedmsg;
public readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();
private void Awake()




IEnumerator updateTags()

yield return new WaitUntil(() => receivedmsg != null);

//string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";
//string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";

while (true)

var data = JToken.Parse(receivedmsg);
foreach (var value in data)

foreach (JArray arr in value)

for (int i = 0; i < arr.Count; i++)

foreach (var item in arr[i])

var itemproperties = item.Parent;
foreach (JToken token in itemproperties)

var prop = token as JProperty;
var plc = (JObject)prop.Value;
string canvass = "Canvas" + i.ToString();
upd1 = transform.Find(canvass).gameObject;
upd2 = transform.Find("Canvas" + i + "/Panel").gameObject;
foreach (KeyValuePair<string, JToken> val in plc)

var plcvarkey = val.Key;
var plcvarvalue = val.Value;
if (plcvarvalue is JObject)

foreach (KeyValuePair<string, JToken> plcvvobj in (JObject)plcvarvalue)

upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvvobj.Key + "/" + plcvvobj.Key + "value").gameObject;
upd4.GetComponent<Text>().text = plcvvobj.Value.ToString();



else

upd3 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey).gameObject;
//upd3.GetComponent<Image>().color = Color.green;
if (plcvarvalue.ToString() == "True")

upd3.GetComponent<Image>().color = Color.green;

if (plcvarvalue.ToString() == "False")

upd3.GetComponent<Image>().color = Color.red;

if (Regex.IsMatch(plcvarvalue.ToString(), @"^d+$"))

upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey + "/" + plcvarkey + "value").gameObject;
upd4.GetComponent<Text>().text = plcvarvalue.ToString();








yield return new WaitForSeconds(0.5f);


#if !UNITY_EDITOR
// Socket initialization
DatagramSocket socket;
#endif
#if !UNITY_EDITOR


IEnumerator initGUI()

yield return new WaitUntil(() => receivedmsg != null);
createUserInterface(receivedmsg);
Debug.Log("left initgui");

// use this for initialization
async void Start()

/*StartCoroutine(SendSliderValue());
Button btn_on = led1_button_on.GetComponent<Button>();
Button btn_off = led1_button_off.GetComponent<Button>();
Button btn1_on = led3_button_on.GetComponent<Button>();
Button btn1_off = led3_button_off.GetComponent<Button>();

btn_on.onClick.AddListener(delegate TaskWithParameters("Led1 on"); );
btn_off.onClick.AddListener(delegate TaskWithParameters("Led1 off"); );
btn1_on.onClick.AddListener(delegate TaskWithParameters("Led3 on"); );
btn1_off.onClick.AddListener(delegate TaskWithParameters("Led3 off"); );*/
//string json = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";

Debug.Log("Waiting for a connection...");
socket = new DatagramSocket();
socket.MessageReceived += Socket_MessageReceived;

//createUserInterface(receivedmsg);
HostName IP = null;
try

var icp = NetworkInformation.GetInternetConnectionProfile();

IP = Windows.Networking.Connectivity.NetworkInformation.GetHostNames()
.SingleOrDefault(
hn =>
hn.IPInformation?.NetworkAdapter != null && hn.IPInformation.NetworkAdapter.NetworkAdapterId
== icp.NetworkAdapter.NetworkAdapterId);

await socket.BindEndpointAsync(IP, port);

catch (Exception e)

Debug.Log(e.ToString());
Debug.Log(SocketError.GetStatus(e.HResult).ToString());
return;

SendMessage("test");
StartCoroutine(initGUI());
StartCoroutine(updateTags());



void TaskWithParameters(string message)

Debug.Log("sending Message");
SendMessage(message);


private async System.Threading.Tasks.Task SendMessage(string message)

using (var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(externalIP), externalPort))

using (var writer = new Windows.Storage.Streams.DataWriter(stream))

var data = Encoding.UTF8.GetBytes(message);
writer.WriteBytes(data);
await writer.StoreAsync();
Debug.Log("Sent: " + message);



#else


// Use this for initialization.
void Start()



#endif
// Update is called once per frame.
void Update()

// Dequeues items until there are no more items on the queue.
while (ExecuteOnMainThread.Count > 0)

ExecuteOnMainThread.Dequeue().Invoke();



IEnumerator SendSliderValue()

Debug.Log("entered slider class");
GameObject theplayer = GameObject.Find("Hololens-Slider");
TubeSliderManager test = theplayer.GetComponent<TubeSliderManager>();
while (true)

sliderVal = test.CurrentValue;
string s = "Slidervalue" + sliderVal.ToString();
SendMessage(s);
yield return new WaitForSeconds(0.5f);




#if !UNITY_EDITOR

//this method gets called when a message is received
private async void Socket_MessageReceived(Windows.Networking.Sockets.DatagramSocket sender, Windows.Networking.Sockets.DatagramSocketMessageReceivedEventArgs args)

// Read the received message.
Stream streamIn = args.GetDataStream().AsStreamForRead();
StreamReader reader = new StreamReader(streamIn);
receivedmsg = await reader.ReadLineAsync();
//Debug.Log("MESSAGE: " + message);
// if the count is zero, the message will be relayed to the setStuff method, which processes the string continuously.
// The message contains a JSON string which is received from the server.
if (ExecuteOnMainThread.Count == 0)

ExecuteOnMainThread.Enqueue(() =>

//Debug.Log(receivedmsg);
//pass msg to function here
);


#endif

public void createUserInterface(string jsonstring)

Debug.Log("entered create UI");
var root = JToken.Parse(jsonstring);
IterateJtoken(root);
canvases = new GameObject[abc.Count];
panels = new GameObject[abc.Count];
for (int i = 0; i < abc.Count; i++)

canvases[i] = Instantiate(canvas, transform.position, transform.rotation);
canvases[i].name = "Canvas" + i;
canvases[i].transform.SetParent(mainGameobject.transform, false);
canvases[i].transform.position += new Vector3(i * 14, 0, 30);
panels[i] = Instantiate(Panel, transform.position, transform.rotation);
panels[i].name = "Panel";
panels[i].transform.SetParent(canvases[i].transform, false);
for (int z = 0; z < abc[i].Count; z++)

tiles = new GameObject[abc[i].Count];
texts = new GameObject[abc[i].Count];
tiles[z] = Instantiate(image, transform.position, transform.rotation);
tiles[z].name = abc[i].ElementAt(z).Key;
tiles[z].transform.SetParent(panels[i].transform, false);
texts[z] = Instantiate(imagetext, transform.position, transform.rotation);
texts[z].name = abc[i].ElementAt(z).Key + "text";
texts[z].transform.SetParent(tiles[z].transform, false);
texts[z].GetComponent<Text>().text = abc[i].ElementAt(z).Key;
texts[z].transform.position += new Vector3(44 * scaler, -4 * scaler, 0);
if (Regex.IsMatch(abc[i].ElementAt(z).Value, @"^d+$"))

numbertext = Instantiate(imagetext, transform.position, transform.rotation);
numbertext.name = abc[i].ElementAt(z).Key + "value";
numbertext.transform.SetParent(tiles[z].transform, false);
texts[z].transform.position += new Vector3(0, 19.5f * scaler, 0);
numbertext.transform.position += new Vector3(77 * scaler, -18.5f * scaler, 0);







public void IterateJtoken(JToken jtoken)

foreach (var value in jtoken)

foreach (JArray test in value)

for (int i = 0; i < test.Count; i++)

foreach (var item in test[i])

var itemproperties = item.Parent;
foreach (JToken token in itemproperties)

if (token is JProperty)

var prop = token as JProperty;
//Console.WriteLine(prop.Name); //PLC name
var plc = (JObject)prop.Value;
Dictionary<string, string> variables = new Dictionary<string, string>();
foreach (KeyValuePair<string, JToken> val in plc)

if (val.Value is JObject)

JObject nestedobj = (JObject)val.Value;
foreach (JProperty nestedvariables in nestedobj.Properties())

size++;
//variables[nestedvariables.Name] = nestedvariables.Value.ToString();
var nestedVariableName = nestedvariables.Name;
var nestedVariableValue = nestedvariables.Value;
variables.Add(nestedVariableName, nestedVariableValue.ToString());
//Console.WriteLine(nestedVariableName+" "+nestedVariableValue);



else

size++;
//variables[val.Key] = val.Value.ToString();
var variableName = val.Key;
var variableValue = val.Value;
variables.Add(variableName, variableValue.ToString());
//Console.WriteLine(variableName+" "+variableValue);



abc.Add(new Dictionary<string, string>(variables));










The code's actually quite simple. For the function createUserInterface, I generate a few public Gameobjects, canvas, Panel, image and imagetext. At the start of the function, the function IterateJtoken() gets called. This function deserializes the JSON String I mentioned in the above example. It fills up the public List of dictionaries which I've named 'abc'. Based on how the List is filled, the createUserInterface builds a user interface with the following hierarchy (manager is the empty gameobject I attach the script to):



enter image description here



As for the updateTags function, the public string I've called receivedmsg gets updated every 0.5 seconds. For instance, if a tag is true, the image turns green and for false it turns red.



An example:



enter image description here



As you can see in the picture above, if I input the following string:



string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";


The code will generate 2 canvases with each their own panel and all the variables like 'test123' as images.



I would like to know if there is a way to make the methods updateTags(), createUserInterface() and IterateJToken() more efficiently.







share|improve this question



























    up vote
    5
    down vote

    favorite












    I recently finished writing an HoloLens proof-of-concept program. It involves generating a user interface based on a connection with an OPC server. OPC involves industrial PLCs, one or more PLCs send their data to an OPC server, and the OPC-client connects and process all the information in the form of JSON.



    An example is this:



    string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";


    The code I've made generates a canvas with a panel. All the variables inside the JSON code get added to the panel in the form of a UI/Image. The function updateTags() continuously updates the data that gets sent using UDP. It functions like I want it to, but I'm wondering if there's a way to reduce the amount of code.



    using UnityEngine;
    using System;
    using System.IO;
    using System.Text;
    using System.Linq;
    using HoloToolkit.Unity;
    using System.Collections.Generic;
    using UnityEngine.UI;
    using Newtonsoft.Json;
    using System.Collections;
    using Newtonsoft.Json.Linq;
    using System.Text.RegularExpressions;
    #if !UNITY_EDITOR
    using Windows.Networking.Sockets;
    using Windows.Networking.Connectivity;
    using Windows.Networking;

    #endif

    public class UDPCommunication : Singleton<UDPCommunication>

    // Connection variables
    private string port = "8000";
    private string externalIP = "172.16.24.251";
    private string externalPort = "8001";
    public static int size = 0;
    public static List<Dictionary<string, string>> abc = new List<Dictionary<string, string>>();
    public static List<string> varz;
    public GameObject mainGameobject;
    public GameObject upd1;
    public GameObject upd2;
    public GameObject upd3;
    public GameObject upd4;
    public GameObject canvas;
    public GameObject Panel;
    public GameObject image;
    public GameObject imagetext;
    public GameObject numbertext;
    public Image testimg;
    private GameObject getImageTags;
    private GameObject getNumberTags;
    private GameObject canvases;
    private GameObject panels;
    private GameObject tiles;
    private GameObject texts;
    private float scaler = 0.0125f;
    // UI/Text elements
    const string TurnOn = "on";
    private uint sliderVal;
    // Sets up a Queue
    private string receivedmsg;
    public readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();
    private void Awake()




    IEnumerator updateTags()

    yield return new WaitUntil(() => receivedmsg != null);

    //string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";
    //string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";

    while (true)

    var data = JToken.Parse(receivedmsg);
    foreach (var value in data)

    foreach (JArray arr in value)

    for (int i = 0; i < arr.Count; i++)

    foreach (var item in arr[i])

    var itemproperties = item.Parent;
    foreach (JToken token in itemproperties)

    var prop = token as JProperty;
    var plc = (JObject)prop.Value;
    string canvass = "Canvas" + i.ToString();
    upd1 = transform.Find(canvass).gameObject;
    upd2 = transform.Find("Canvas" + i + "/Panel").gameObject;
    foreach (KeyValuePair<string, JToken> val in plc)

    var plcvarkey = val.Key;
    var plcvarvalue = val.Value;
    if (plcvarvalue is JObject)

    foreach (KeyValuePair<string, JToken> plcvvobj in (JObject)plcvarvalue)

    upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvvobj.Key + "/" + plcvvobj.Key + "value").gameObject;
    upd4.GetComponent<Text>().text = plcvvobj.Value.ToString();



    else

    upd3 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey).gameObject;
    //upd3.GetComponent<Image>().color = Color.green;
    if (plcvarvalue.ToString() == "True")

    upd3.GetComponent<Image>().color = Color.green;

    if (plcvarvalue.ToString() == "False")

    upd3.GetComponent<Image>().color = Color.red;

    if (Regex.IsMatch(plcvarvalue.ToString(), @"^d+$"))

    upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey + "/" + plcvarkey + "value").gameObject;
    upd4.GetComponent<Text>().text = plcvarvalue.ToString();








    yield return new WaitForSeconds(0.5f);


    #if !UNITY_EDITOR
    // Socket initialization
    DatagramSocket socket;
    #endif
    #if !UNITY_EDITOR


    IEnumerator initGUI()

    yield return new WaitUntil(() => receivedmsg != null);
    createUserInterface(receivedmsg);
    Debug.Log("left initgui");

    // use this for initialization
    async void Start()

    /*StartCoroutine(SendSliderValue());
    Button btn_on = led1_button_on.GetComponent<Button>();
    Button btn_off = led1_button_off.GetComponent<Button>();
    Button btn1_on = led3_button_on.GetComponent<Button>();
    Button btn1_off = led3_button_off.GetComponent<Button>();

    btn_on.onClick.AddListener(delegate TaskWithParameters("Led1 on"); );
    btn_off.onClick.AddListener(delegate TaskWithParameters("Led1 off"); );
    btn1_on.onClick.AddListener(delegate TaskWithParameters("Led3 on"); );
    btn1_off.onClick.AddListener(delegate TaskWithParameters("Led3 off"); );*/
    //string json = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";

    Debug.Log("Waiting for a connection...");
    socket = new DatagramSocket();
    socket.MessageReceived += Socket_MessageReceived;

    //createUserInterface(receivedmsg);
    HostName IP = null;
    try

    var icp = NetworkInformation.GetInternetConnectionProfile();

    IP = Windows.Networking.Connectivity.NetworkInformation.GetHostNames()
    .SingleOrDefault(
    hn =>
    hn.IPInformation?.NetworkAdapter != null && hn.IPInformation.NetworkAdapter.NetworkAdapterId
    == icp.NetworkAdapter.NetworkAdapterId);

    await socket.BindEndpointAsync(IP, port);

    catch (Exception e)

    Debug.Log(e.ToString());
    Debug.Log(SocketError.GetStatus(e.HResult).ToString());
    return;

    SendMessage("test");
    StartCoroutine(initGUI());
    StartCoroutine(updateTags());



    void TaskWithParameters(string message)

    Debug.Log("sending Message");
    SendMessage(message);


    private async System.Threading.Tasks.Task SendMessage(string message)

    using (var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(externalIP), externalPort))

    using (var writer = new Windows.Storage.Streams.DataWriter(stream))

    var data = Encoding.UTF8.GetBytes(message);
    writer.WriteBytes(data);
    await writer.StoreAsync();
    Debug.Log("Sent: " + message);



    #else


    // Use this for initialization.
    void Start()



    #endif
    // Update is called once per frame.
    void Update()

    // Dequeues items until there are no more items on the queue.
    while (ExecuteOnMainThread.Count > 0)

    ExecuteOnMainThread.Dequeue().Invoke();



    IEnumerator SendSliderValue()

    Debug.Log("entered slider class");
    GameObject theplayer = GameObject.Find("Hololens-Slider");
    TubeSliderManager test = theplayer.GetComponent<TubeSliderManager>();
    while (true)

    sliderVal = test.CurrentValue;
    string s = "Slidervalue" + sliderVal.ToString();
    SendMessage(s);
    yield return new WaitForSeconds(0.5f);




    #if !UNITY_EDITOR

    //this method gets called when a message is received
    private async void Socket_MessageReceived(Windows.Networking.Sockets.DatagramSocket sender, Windows.Networking.Sockets.DatagramSocketMessageReceivedEventArgs args)

    // Read the received message.
    Stream streamIn = args.GetDataStream().AsStreamForRead();
    StreamReader reader = new StreamReader(streamIn);
    receivedmsg = await reader.ReadLineAsync();
    //Debug.Log("MESSAGE: " + message);
    // if the count is zero, the message will be relayed to the setStuff method, which processes the string continuously.
    // The message contains a JSON string which is received from the server.
    if (ExecuteOnMainThread.Count == 0)

    ExecuteOnMainThread.Enqueue(() =>

    //Debug.Log(receivedmsg);
    //pass msg to function here
    );


    #endif

    public void createUserInterface(string jsonstring)

    Debug.Log("entered create UI");
    var root = JToken.Parse(jsonstring);
    IterateJtoken(root);
    canvases = new GameObject[abc.Count];
    panels = new GameObject[abc.Count];
    for (int i = 0; i < abc.Count; i++)

    canvases[i] = Instantiate(canvas, transform.position, transform.rotation);
    canvases[i].name = "Canvas" + i;
    canvases[i].transform.SetParent(mainGameobject.transform, false);
    canvases[i].transform.position += new Vector3(i * 14, 0, 30);
    panels[i] = Instantiate(Panel, transform.position, transform.rotation);
    panels[i].name = "Panel";
    panels[i].transform.SetParent(canvases[i].transform, false);
    for (int z = 0; z < abc[i].Count; z++)

    tiles = new GameObject[abc[i].Count];
    texts = new GameObject[abc[i].Count];
    tiles[z] = Instantiate(image, transform.position, transform.rotation);
    tiles[z].name = abc[i].ElementAt(z).Key;
    tiles[z].transform.SetParent(panels[i].transform, false);
    texts[z] = Instantiate(imagetext, transform.position, transform.rotation);
    texts[z].name = abc[i].ElementAt(z).Key + "text";
    texts[z].transform.SetParent(tiles[z].transform, false);
    texts[z].GetComponent<Text>().text = abc[i].ElementAt(z).Key;
    texts[z].transform.position += new Vector3(44 * scaler, -4 * scaler, 0);
    if (Regex.IsMatch(abc[i].ElementAt(z).Value, @"^d+$"))

    numbertext = Instantiate(imagetext, transform.position, transform.rotation);
    numbertext.name = abc[i].ElementAt(z).Key + "value";
    numbertext.transform.SetParent(tiles[z].transform, false);
    texts[z].transform.position += new Vector3(0, 19.5f * scaler, 0);
    numbertext.transform.position += new Vector3(77 * scaler, -18.5f * scaler, 0);







    public void IterateJtoken(JToken jtoken)

    foreach (var value in jtoken)

    foreach (JArray test in value)

    for (int i = 0; i < test.Count; i++)

    foreach (var item in test[i])

    var itemproperties = item.Parent;
    foreach (JToken token in itemproperties)

    if (token is JProperty)

    var prop = token as JProperty;
    //Console.WriteLine(prop.Name); //PLC name
    var plc = (JObject)prop.Value;
    Dictionary<string, string> variables = new Dictionary<string, string>();
    foreach (KeyValuePair<string, JToken> val in plc)

    if (val.Value is JObject)

    JObject nestedobj = (JObject)val.Value;
    foreach (JProperty nestedvariables in nestedobj.Properties())

    size++;
    //variables[nestedvariables.Name] = nestedvariables.Value.ToString();
    var nestedVariableName = nestedvariables.Name;
    var nestedVariableValue = nestedvariables.Value;
    variables.Add(nestedVariableName, nestedVariableValue.ToString());
    //Console.WriteLine(nestedVariableName+" "+nestedVariableValue);



    else

    size++;
    //variables[val.Key] = val.Value.ToString();
    var variableName = val.Key;
    var variableValue = val.Value;
    variables.Add(variableName, variableValue.ToString());
    //Console.WriteLine(variableName+" "+variableValue);



    abc.Add(new Dictionary<string, string>(variables));










    The code's actually quite simple. For the function createUserInterface, I generate a few public Gameobjects, canvas, Panel, image and imagetext. At the start of the function, the function IterateJtoken() gets called. This function deserializes the JSON String I mentioned in the above example. It fills up the public List of dictionaries which I've named 'abc'. Based on how the List is filled, the createUserInterface builds a user interface with the following hierarchy (manager is the empty gameobject I attach the script to):



    enter image description here



    As for the updateTags function, the public string I've called receivedmsg gets updated every 0.5 seconds. For instance, if a tag is true, the image turns green and for false it turns red.



    An example:



    enter image description here



    As you can see in the picture above, if I input the following string:



    string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";


    The code will generate 2 canvases with each their own panel and all the variables like 'test123' as images.



    I would like to know if there is a way to make the methods updateTags(), createUserInterface() and IterateJToken() more efficiently.







    share|improve this question























      up vote
      5
      down vote

      favorite









      up vote
      5
      down vote

      favorite











      I recently finished writing an HoloLens proof-of-concept program. It involves generating a user interface based on a connection with an OPC server. OPC involves industrial PLCs, one or more PLCs send their data to an OPC server, and the OPC-client connects and process all the information in the form of JSON.



      An example is this:



      string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";


      The code I've made generates a canvas with a panel. All the variables inside the JSON code get added to the panel in the form of a UI/Image. The function updateTags() continuously updates the data that gets sent using UDP. It functions like I want it to, but I'm wondering if there's a way to reduce the amount of code.



      using UnityEngine;
      using System;
      using System.IO;
      using System.Text;
      using System.Linq;
      using HoloToolkit.Unity;
      using System.Collections.Generic;
      using UnityEngine.UI;
      using Newtonsoft.Json;
      using System.Collections;
      using Newtonsoft.Json.Linq;
      using System.Text.RegularExpressions;
      #if !UNITY_EDITOR
      using Windows.Networking.Sockets;
      using Windows.Networking.Connectivity;
      using Windows.Networking;

      #endif

      public class UDPCommunication : Singleton<UDPCommunication>

      // Connection variables
      private string port = "8000";
      private string externalIP = "172.16.24.251";
      private string externalPort = "8001";
      public static int size = 0;
      public static List<Dictionary<string, string>> abc = new List<Dictionary<string, string>>();
      public static List<string> varz;
      public GameObject mainGameobject;
      public GameObject upd1;
      public GameObject upd2;
      public GameObject upd3;
      public GameObject upd4;
      public GameObject canvas;
      public GameObject Panel;
      public GameObject image;
      public GameObject imagetext;
      public GameObject numbertext;
      public Image testimg;
      private GameObject getImageTags;
      private GameObject getNumberTags;
      private GameObject canvases;
      private GameObject panels;
      private GameObject tiles;
      private GameObject texts;
      private float scaler = 0.0125f;
      // UI/Text elements
      const string TurnOn = "on";
      private uint sliderVal;
      // Sets up a Queue
      private string receivedmsg;
      public readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();
      private void Awake()




      IEnumerator updateTags()

      yield return new WaitUntil(() => receivedmsg != null);

      //string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";
      //string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";

      while (true)

      var data = JToken.Parse(receivedmsg);
      foreach (var value in data)

      foreach (JArray arr in value)

      for (int i = 0; i < arr.Count; i++)

      foreach (var item in arr[i])

      var itemproperties = item.Parent;
      foreach (JToken token in itemproperties)

      var prop = token as JProperty;
      var plc = (JObject)prop.Value;
      string canvass = "Canvas" + i.ToString();
      upd1 = transform.Find(canvass).gameObject;
      upd2 = transform.Find("Canvas" + i + "/Panel").gameObject;
      foreach (KeyValuePair<string, JToken> val in plc)

      var plcvarkey = val.Key;
      var plcvarvalue = val.Value;
      if (plcvarvalue is JObject)

      foreach (KeyValuePair<string, JToken> plcvvobj in (JObject)plcvarvalue)

      upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvvobj.Key + "/" + plcvvobj.Key + "value").gameObject;
      upd4.GetComponent<Text>().text = plcvvobj.Value.ToString();



      else

      upd3 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey).gameObject;
      //upd3.GetComponent<Image>().color = Color.green;
      if (plcvarvalue.ToString() == "True")

      upd3.GetComponent<Image>().color = Color.green;

      if (plcvarvalue.ToString() == "False")

      upd3.GetComponent<Image>().color = Color.red;

      if (Regex.IsMatch(plcvarvalue.ToString(), @"^d+$"))

      upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey + "/" + plcvarkey + "value").gameObject;
      upd4.GetComponent<Text>().text = plcvarvalue.ToString();








      yield return new WaitForSeconds(0.5f);


      #if !UNITY_EDITOR
      // Socket initialization
      DatagramSocket socket;
      #endif
      #if !UNITY_EDITOR


      IEnumerator initGUI()

      yield return new WaitUntil(() => receivedmsg != null);
      createUserInterface(receivedmsg);
      Debug.Log("left initgui");

      // use this for initialization
      async void Start()

      /*StartCoroutine(SendSliderValue());
      Button btn_on = led1_button_on.GetComponent<Button>();
      Button btn_off = led1_button_off.GetComponent<Button>();
      Button btn1_on = led3_button_on.GetComponent<Button>();
      Button btn1_off = led3_button_off.GetComponent<Button>();

      btn_on.onClick.AddListener(delegate TaskWithParameters("Led1 on"); );
      btn_off.onClick.AddListener(delegate TaskWithParameters("Led1 off"); );
      btn1_on.onClick.AddListener(delegate TaskWithParameters("Led3 on"); );
      btn1_off.onClick.AddListener(delegate TaskWithParameters("Led3 off"); );*/
      //string json = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";

      Debug.Log("Waiting for a connection...");
      socket = new DatagramSocket();
      socket.MessageReceived += Socket_MessageReceived;

      //createUserInterface(receivedmsg);
      HostName IP = null;
      try

      var icp = NetworkInformation.GetInternetConnectionProfile();

      IP = Windows.Networking.Connectivity.NetworkInformation.GetHostNames()
      .SingleOrDefault(
      hn =>
      hn.IPInformation?.NetworkAdapter != null && hn.IPInformation.NetworkAdapter.NetworkAdapterId
      == icp.NetworkAdapter.NetworkAdapterId);

      await socket.BindEndpointAsync(IP, port);

      catch (Exception e)

      Debug.Log(e.ToString());
      Debug.Log(SocketError.GetStatus(e.HResult).ToString());
      return;

      SendMessage("test");
      StartCoroutine(initGUI());
      StartCoroutine(updateTags());



      void TaskWithParameters(string message)

      Debug.Log("sending Message");
      SendMessage(message);


      private async System.Threading.Tasks.Task SendMessage(string message)

      using (var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(externalIP), externalPort))

      using (var writer = new Windows.Storage.Streams.DataWriter(stream))

      var data = Encoding.UTF8.GetBytes(message);
      writer.WriteBytes(data);
      await writer.StoreAsync();
      Debug.Log("Sent: " + message);



      #else


      // Use this for initialization.
      void Start()



      #endif
      // Update is called once per frame.
      void Update()

      // Dequeues items until there are no more items on the queue.
      while (ExecuteOnMainThread.Count > 0)

      ExecuteOnMainThread.Dequeue().Invoke();



      IEnumerator SendSliderValue()

      Debug.Log("entered slider class");
      GameObject theplayer = GameObject.Find("Hololens-Slider");
      TubeSliderManager test = theplayer.GetComponent<TubeSliderManager>();
      while (true)

      sliderVal = test.CurrentValue;
      string s = "Slidervalue" + sliderVal.ToString();
      SendMessage(s);
      yield return new WaitForSeconds(0.5f);




      #if !UNITY_EDITOR

      //this method gets called when a message is received
      private async void Socket_MessageReceived(Windows.Networking.Sockets.DatagramSocket sender, Windows.Networking.Sockets.DatagramSocketMessageReceivedEventArgs args)

      // Read the received message.
      Stream streamIn = args.GetDataStream().AsStreamForRead();
      StreamReader reader = new StreamReader(streamIn);
      receivedmsg = await reader.ReadLineAsync();
      //Debug.Log("MESSAGE: " + message);
      // if the count is zero, the message will be relayed to the setStuff method, which processes the string continuously.
      // The message contains a JSON string which is received from the server.
      if (ExecuteOnMainThread.Count == 0)

      ExecuteOnMainThread.Enqueue(() =>

      //Debug.Log(receivedmsg);
      //pass msg to function here
      );


      #endif

      public void createUserInterface(string jsonstring)

      Debug.Log("entered create UI");
      var root = JToken.Parse(jsonstring);
      IterateJtoken(root);
      canvases = new GameObject[abc.Count];
      panels = new GameObject[abc.Count];
      for (int i = 0; i < abc.Count; i++)

      canvases[i] = Instantiate(canvas, transform.position, transform.rotation);
      canvases[i].name = "Canvas" + i;
      canvases[i].transform.SetParent(mainGameobject.transform, false);
      canvases[i].transform.position += new Vector3(i * 14, 0, 30);
      panels[i] = Instantiate(Panel, transform.position, transform.rotation);
      panels[i].name = "Panel";
      panels[i].transform.SetParent(canvases[i].transform, false);
      for (int z = 0; z < abc[i].Count; z++)

      tiles = new GameObject[abc[i].Count];
      texts = new GameObject[abc[i].Count];
      tiles[z] = Instantiate(image, transform.position, transform.rotation);
      tiles[z].name = abc[i].ElementAt(z).Key;
      tiles[z].transform.SetParent(panels[i].transform, false);
      texts[z] = Instantiate(imagetext, transform.position, transform.rotation);
      texts[z].name = abc[i].ElementAt(z).Key + "text";
      texts[z].transform.SetParent(tiles[z].transform, false);
      texts[z].GetComponent<Text>().text = abc[i].ElementAt(z).Key;
      texts[z].transform.position += new Vector3(44 * scaler, -4 * scaler, 0);
      if (Regex.IsMatch(abc[i].ElementAt(z).Value, @"^d+$"))

      numbertext = Instantiate(imagetext, transform.position, transform.rotation);
      numbertext.name = abc[i].ElementAt(z).Key + "value";
      numbertext.transform.SetParent(tiles[z].transform, false);
      texts[z].transform.position += new Vector3(0, 19.5f * scaler, 0);
      numbertext.transform.position += new Vector3(77 * scaler, -18.5f * scaler, 0);







      public void IterateJtoken(JToken jtoken)

      foreach (var value in jtoken)

      foreach (JArray test in value)

      for (int i = 0; i < test.Count; i++)

      foreach (var item in test[i])

      var itemproperties = item.Parent;
      foreach (JToken token in itemproperties)

      if (token is JProperty)

      var prop = token as JProperty;
      //Console.WriteLine(prop.Name); //PLC name
      var plc = (JObject)prop.Value;
      Dictionary<string, string> variables = new Dictionary<string, string>();
      foreach (KeyValuePair<string, JToken> val in plc)

      if (val.Value is JObject)

      JObject nestedobj = (JObject)val.Value;
      foreach (JProperty nestedvariables in nestedobj.Properties())

      size++;
      //variables[nestedvariables.Name] = nestedvariables.Value.ToString();
      var nestedVariableName = nestedvariables.Name;
      var nestedVariableValue = nestedvariables.Value;
      variables.Add(nestedVariableName, nestedVariableValue.ToString());
      //Console.WriteLine(nestedVariableName+" "+nestedVariableValue);



      else

      size++;
      //variables[val.Key] = val.Value.ToString();
      var variableName = val.Key;
      var variableValue = val.Value;
      variables.Add(variableName, variableValue.ToString());
      //Console.WriteLine(variableName+" "+variableValue);



      abc.Add(new Dictionary<string, string>(variables));










      The code's actually quite simple. For the function createUserInterface, I generate a few public Gameobjects, canvas, Panel, image and imagetext. At the start of the function, the function IterateJtoken() gets called. This function deserializes the JSON String I mentioned in the above example. It fills up the public List of dictionaries which I've named 'abc'. Based on how the List is filled, the createUserInterface builds a user interface with the following hierarchy (manager is the empty gameobject I attach the script to):



      enter image description here



      As for the updateTags function, the public string I've called receivedmsg gets updated every 0.5 seconds. For instance, if a tag is true, the image turns green and for false it turns red.



      An example:



      enter image description here



      As you can see in the picture above, if I input the following string:



      string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";


      The code will generate 2 canvases with each their own panel and all the variables like 'test123' as images.



      I would like to know if there is a way to make the methods updateTags(), createUserInterface() and IterateJToken() more efficiently.







      share|improve this question













      I recently finished writing an HoloLens proof-of-concept program. It involves generating a user interface based on a connection with an OPC server. OPC involves industrial PLCs, one or more PLCs send their data to an OPC server, and the OPC-client connects and process all the information in the form of JSON.



      An example is this:



      string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";


      The code I've made generates a canvas with a panel. All the variables inside the JSON code get added to the panel in the form of a UI/Image. The function updateTags() continuously updates the data that gets sent using UDP. It functions like I want it to, but I'm wondering if there's a way to reduce the amount of code.



      using UnityEngine;
      using System;
      using System.IO;
      using System.Text;
      using System.Linq;
      using HoloToolkit.Unity;
      using System.Collections.Generic;
      using UnityEngine.UI;
      using Newtonsoft.Json;
      using System.Collections;
      using Newtonsoft.Json.Linq;
      using System.Text.RegularExpressions;
      #if !UNITY_EDITOR
      using Windows.Networking.Sockets;
      using Windows.Networking.Connectivity;
      using Windows.Networking;

      #endif

      public class UDPCommunication : Singleton<UDPCommunication>

      // Connection variables
      private string port = "8000";
      private string externalIP = "172.16.24.251";
      private string externalPort = "8001";
      public static int size = 0;
      public static List<Dictionary<string, string>> abc = new List<Dictionary<string, string>>();
      public static List<string> varz;
      public GameObject mainGameobject;
      public GameObject upd1;
      public GameObject upd2;
      public GameObject upd3;
      public GameObject upd4;
      public GameObject canvas;
      public GameObject Panel;
      public GameObject image;
      public GameObject imagetext;
      public GameObject numbertext;
      public Image testimg;
      private GameObject getImageTags;
      private GameObject getNumberTags;
      private GameObject canvases;
      private GameObject panels;
      private GameObject tiles;
      private GameObject texts;
      private float scaler = 0.0125f;
      // UI/Text elements
      const string TurnOn = "on";
      private uint sliderVal;
      // Sets up a Queue
      private string receivedmsg;
      public readonly static Queue<Action> ExecuteOnMainThread = new Queue<Action>();
      private void Awake()




      IEnumerator updateTags()

      yield return new WaitUntil(() => receivedmsg != null);

      //string json = ""PC_Station": ["PLC_1": "DB1": "test123": 30, "STOP": false, "START": true, "Start_1": false, "Stop_1": true, "Led1": false, "Led2": false, "Led3": false, "Counter": 3880, "Sliderval": 60]";
      //string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";

      while (true)

      var data = JToken.Parse(receivedmsg);
      foreach (var value in data)

      foreach (JArray arr in value)

      for (int i = 0; i < arr.Count; i++)

      foreach (var item in arr[i])

      var itemproperties = item.Parent;
      foreach (JToken token in itemproperties)

      var prop = token as JProperty;
      var plc = (JObject)prop.Value;
      string canvass = "Canvas" + i.ToString();
      upd1 = transform.Find(canvass).gameObject;
      upd2 = transform.Find("Canvas" + i + "/Panel").gameObject;
      foreach (KeyValuePair<string, JToken> val in plc)

      var plcvarkey = val.Key;
      var plcvarvalue = val.Value;
      if (plcvarvalue is JObject)

      foreach (KeyValuePair<string, JToken> plcvvobj in (JObject)plcvarvalue)

      upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvvobj.Key + "/" + plcvvobj.Key + "value").gameObject;
      upd4.GetComponent<Text>().text = plcvvobj.Value.ToString();



      else

      upd3 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey).gameObject;
      //upd3.GetComponent<Image>().color = Color.green;
      if (plcvarvalue.ToString() == "True")

      upd3.GetComponent<Image>().color = Color.green;

      if (plcvarvalue.ToString() == "False")

      upd3.GetComponent<Image>().color = Color.red;

      if (Regex.IsMatch(plcvarvalue.ToString(), @"^d+$"))

      upd4 = transform.Find("Canvas" + i + "/Panel/" + plcvarkey + "/" + plcvarkey + "value").gameObject;
      upd4.GetComponent<Text>().text = plcvarvalue.ToString();








      yield return new WaitForSeconds(0.5f);


      #if !UNITY_EDITOR
      // Socket initialization
      DatagramSocket socket;
      #endif
      #if !UNITY_EDITOR


      IEnumerator initGUI()

      yield return new WaitUntil(() => receivedmsg != null);
      createUserInterface(receivedmsg);
      Debug.Log("left initgui");

      // use this for initialization
      async void Start()

      /*StartCoroutine(SendSliderValue());
      Button btn_on = led1_button_on.GetComponent<Button>();
      Button btn_off = led1_button_off.GetComponent<Button>();
      Button btn1_on = led3_button_on.GetComponent<Button>();
      Button btn1_off = led3_button_off.GetComponent<Button>();

      btn_on.onClick.AddListener(delegate TaskWithParameters("Led1 on"); );
      btn_off.onClick.AddListener(delegate TaskWithParameters("Led1 off"); );
      btn1_on.onClick.AddListener(delegate TaskWithParameters("Led3 on"); );
      btn1_off.onClick.AddListener(delegate TaskWithParameters("Led3 off"); );*/
      //string json = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";

      Debug.Log("Waiting for a connection...");
      socket = new DatagramSocket();
      socket.MessageReceived += Socket_MessageReceived;

      //createUserInterface(receivedmsg);
      HostName IP = null;
      try

      var icp = NetworkInformation.GetInternetConnectionProfile();

      IP = Windows.Networking.Connectivity.NetworkInformation.GetHostNames()
      .SingleOrDefault(
      hn =>
      hn.IPInformation?.NetworkAdapter != null && hn.IPInformation.NetworkAdapter.NetworkAdapterId
      == icp.NetworkAdapter.NetworkAdapterId);

      await socket.BindEndpointAsync(IP, port);

      catch (Exception e)

      Debug.Log(e.ToString());
      Debug.Log(SocketError.GetStatus(e.HResult).ToString());
      return;

      SendMessage("test");
      StartCoroutine(initGUI());
      StartCoroutine(updateTags());



      void TaskWithParameters(string message)

      Debug.Log("sending Message");
      SendMessage(message);


      private async System.Threading.Tasks.Task SendMessage(string message)

      using (var stream = await socket.GetOutputStreamAsync(new Windows.Networking.HostName(externalIP), externalPort))

      using (var writer = new Windows.Storage.Streams.DataWriter(stream))

      var data = Encoding.UTF8.GetBytes(message);
      writer.WriteBytes(data);
      await writer.StoreAsync();
      Debug.Log("Sent: " + message);



      #else


      // Use this for initialization.
      void Start()



      #endif
      // Update is called once per frame.
      void Update()

      // Dequeues items until there are no more items on the queue.
      while (ExecuteOnMainThread.Count > 0)

      ExecuteOnMainThread.Dequeue().Invoke();



      IEnumerator SendSliderValue()

      Debug.Log("entered slider class");
      GameObject theplayer = GameObject.Find("Hololens-Slider");
      TubeSliderManager test = theplayer.GetComponent<TubeSliderManager>();
      while (true)

      sliderVal = test.CurrentValue;
      string s = "Slidervalue" + sliderVal.ToString();
      SendMessage(s);
      yield return new WaitForSeconds(0.5f);




      #if !UNITY_EDITOR

      //this method gets called when a message is received
      private async void Socket_MessageReceived(Windows.Networking.Sockets.DatagramSocket sender, Windows.Networking.Sockets.DatagramSocketMessageReceivedEventArgs args)

      // Read the received message.
      Stream streamIn = args.GetDataStream().AsStreamForRead();
      StreamReader reader = new StreamReader(streamIn);
      receivedmsg = await reader.ReadLineAsync();
      //Debug.Log("MESSAGE: " + message);
      // if the count is zero, the message will be relayed to the setStuff method, which processes the string continuously.
      // The message contains a JSON string which is received from the server.
      if (ExecuteOnMainThread.Count == 0)

      ExecuteOnMainThread.Enqueue(() =>

      //Debug.Log(receivedmsg);
      //pass msg to function here
      );


      #endif

      public void createUserInterface(string jsonstring)

      Debug.Log("entered create UI");
      var root = JToken.Parse(jsonstring);
      IterateJtoken(root);
      canvases = new GameObject[abc.Count];
      panels = new GameObject[abc.Count];
      for (int i = 0; i < abc.Count; i++)

      canvases[i] = Instantiate(canvas, transform.position, transform.rotation);
      canvases[i].name = "Canvas" + i;
      canvases[i].transform.SetParent(mainGameobject.transform, false);
      canvases[i].transform.position += new Vector3(i * 14, 0, 30);
      panels[i] = Instantiate(Panel, transform.position, transform.rotation);
      panels[i].name = "Panel";
      panels[i].transform.SetParent(canvases[i].transform, false);
      for (int z = 0; z < abc[i].Count; z++)

      tiles = new GameObject[abc[i].Count];
      texts = new GameObject[abc[i].Count];
      tiles[z] = Instantiate(image, transform.position, transform.rotation);
      tiles[z].name = abc[i].ElementAt(z).Key;
      tiles[z].transform.SetParent(panels[i].transform, false);
      texts[z] = Instantiate(imagetext, transform.position, transform.rotation);
      texts[z].name = abc[i].ElementAt(z).Key + "text";
      texts[z].transform.SetParent(tiles[z].transform, false);
      texts[z].GetComponent<Text>().text = abc[i].ElementAt(z).Key;
      texts[z].transform.position += new Vector3(44 * scaler, -4 * scaler, 0);
      if (Regex.IsMatch(abc[i].ElementAt(z).Value, @"^d+$"))

      numbertext = Instantiate(imagetext, transform.position, transform.rotation);
      numbertext.name = abc[i].ElementAt(z).Key + "value";
      numbertext.transform.SetParent(tiles[z].transform, false);
      texts[z].transform.position += new Vector3(0, 19.5f * scaler, 0);
      numbertext.transform.position += new Vector3(77 * scaler, -18.5f * scaler, 0);







      public void IterateJtoken(JToken jtoken)

      foreach (var value in jtoken)

      foreach (JArray test in value)

      for (int i = 0; i < test.Count; i++)

      foreach (var item in test[i])

      var itemproperties = item.Parent;
      foreach (JToken token in itemproperties)

      if (token is JProperty)

      var prop = token as JProperty;
      //Console.WriteLine(prop.Name); //PLC name
      var plc = (JObject)prop.Value;
      Dictionary<string, string> variables = new Dictionary<string, string>();
      foreach (KeyValuePair<string, JToken> val in plc)

      if (val.Value is JObject)

      JObject nestedobj = (JObject)val.Value;
      foreach (JProperty nestedvariables in nestedobj.Properties())

      size++;
      //variables[nestedvariables.Name] = nestedvariables.Value.ToString();
      var nestedVariableName = nestedvariables.Name;
      var nestedVariableValue = nestedvariables.Value;
      variables.Add(nestedVariableName, nestedVariableValue.ToString());
      //Console.WriteLine(nestedVariableName+" "+nestedVariableValue);



      else

      size++;
      //variables[val.Key] = val.Value.ToString();
      var variableName = val.Key;
      var variableValue = val.Value;
      variables.Add(variableName, variableValue.ToString());
      //Console.WriteLine(variableName+" "+variableValue);



      abc.Add(new Dictionary<string, string>(variables));










      The code's actually quite simple. For the function createUserInterface, I generate a few public Gameobjects, canvas, Panel, image and imagetext. At the start of the function, the function IterateJtoken() gets called. This function deserializes the JSON String I mentioned in the above example. It fills up the public List of dictionaries which I've named 'abc'. Based on how the List is filled, the createUserInterface builds a user interface with the following hierarchy (manager is the empty gameobject I attach the script to):



      enter image description here



      As for the updateTags function, the public string I've called receivedmsg gets updated every 0.5 seconds. For instance, if a tag is true, the image turns green and for false it turns red.



      An example:



      enter image description here



      As you can see in the picture above, if I input the following string:



      string json1 = ""PC_Station": ["PLC_0": "DB1": "test123": 0, "STOP": false,"Frap": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0,"PLC_1": "DB1": "test123": 55, "STOP": false, "START": false, "Start_1": false, "Stop_1": false, "Led1": true, "Led2": false, "Led3": true, "Counter": 4002, "Sliderval": 0]";


      The code will generate 2 canvases with each their own panel and all the variables like 'test123' as images.



      I would like to know if there is a way to make the methods updateTags(), createUserInterface() and IterateJToken() more efficiently.









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jul 31 at 4:21









      Jamal♦

      30.1k11114225




      30.1k11114225









      asked Jul 30 at 14:25









      hoek rand

      261




      261

























          active

          oldest

          votes











          Your Answer




          StackExchange.ifUsing("editor", function ()
          return StackExchange.using("mathjaxEditing", function ()
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          );
          );
          , "mathjax-editing");

          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "196"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: false,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );








           

          draft saved


          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200588%2fhololens-unity-program%23new-answer', 'question_page');

          );

          Post as a guest



































          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes










           

          draft saved


          draft discarded


























           


          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200588%2fhololens-unity-program%23new-answer', 'question_page');

          );

          Post as a guest













































































          Popular posts from this blog

          Greedy Best First Search implementation in Rust

          Function to Return a JSON Like Objects Using VBA Collections and Arrays

          C++11 CLH Lock Implementation