ATVO by Appgineering
Download
Read-only

Performance Issue - Trying to track it down

10 posts 5,639 views Started 23 May 2020, 16:25
Showing 1–10 of 10 posts
Kyle H.
Original poster

Hi all - working on changing up one of my important scripts, it gets slow after 15 minutes or so because of this error:

"Unable to cast object of type 'System.String' to type 'ATVO.ThemesSDK.Data.Results.IEntitySessionResult'.

I understand this is because of a casting error somewhere, I'm just not quite sure what I've done incorrectly. Need a fresh set of eyes - anyone see the issue?

using System; 
using ATVO.ThemesSDK; 
using ATVO.ThemesSDK.Data.Entity; 
using ATVO.ThemeEditor.ThemeModels; 
using ATVO.ThemeEditor.Controls; 
using ATVO.ThemeEditor.Scripting.DotNET;
using ATVO.ThemesSDK.Data.Enums;
using ATVO.ThemesSDK.Data.Results;

namespace Scripts
{
	public class Script : IScript
	{
	
		public object Execute(ThemeContentItem item, object value, string parameter, ISimulation sim)
		{
			// Bind to "entitysessionresult_obj" to get the IEntitySessionResult as the value
			
			// Cast to IEntitySessionResult type
			IEntitySessionResult result = (IEntitySessionResult) value;
			if (value == null)
			{
    			// do something appropriate, in this case probably just return nothing
    			return null;
			}
		
			
			var flags = result.Session.Flags;
			var type = result.Session.Type;
			var gap = result.LiveClassGap;
			var pos = result.LiveClassPosition;
			var best = result.FastestLapTime;
			var min = 0;
 			float sectime;
 			var laps = result.LiveClassGapLaps;
			

			if (type == SessionType.Practice)
				
			{
			
				 if (best > 60)
				 {
				     min = (int) (best / 60);
				            sectime = best % 60;
				            return min + ":" + sectime.ToString("00.000");
				 }
				 
				 if (best != 0.000)
				 {
				 return best.ToString("0.000");
				 }
	
				 else
				 return ("");	
				 
			}

			if (type == SessionType.Qualify)
				
			{

		

				 if (best > 60)
				 {
				     min = (int) (best / 60);
				            sectime = best % 60;
				            return min + ":" + sectime.ToString("00.000");
				 }
				 
				 if (best != 0.000)
				 {
				 return best.ToString("0.000");
				 }
	
				 else
				 return ("");	
				 
			}

			if (type == SessionType.Race)
				
			{
			
			
				
			if	(result.DidNotStart)
				return "DNS ";
				
			if	(result.Out)
				return "OUT ";
				
			if (result.LiveGap == 0.000 && pos != 1)
				return "";
	
			if (flags.HasFlag(SessionFlags.Caution) || flags.HasFlag(SessionFlags.CautionWaving))
    			return "";
					
			if	(result.Finished && pos == 1)
				return gap.ToString("WIN ");
				
			if	(result.Finished && pos != 1)
				return gap.ToString("0.000");
					
			// Optional: there is no gap for P1 so show nothing
			if (pos == 1)
				return "LDR ";
				
			// If car is lapped AND this is a race session,
			// then show nr of gap laps instead of gap time
			if (laps > 0 && type == SessionType.Race)
			{
				if (laps == 1)
					return "-1 Lap"; // to avoid incorrect "1 Laps"
				else
					return -laps + " Laps";
			}
		
		
		if	(result.Entity?.Car?.Movement?.IsInPits == true && type == SessionType.Race)
				return "PIT ";
			
			
			else
			return gap.ToString("-0.000");
			
		
	
		}
		else
		return "";
	}	
  }
}
Nick Thissen Appgineering
Reply #1
· edited

There is only one such cast in the very beginning. My guess is you are accidentally using this script on another binding as well? Otherwise I cannot explain why it would suddenly give you a string instead of an IEntitySessionResult object. Unless there's a bug somewhere.

There is also a "mistake" that you cast value before you check if it is null. If value is null (which I can see happening in some cases) then this cast will already throw an exception (but a different one).

You can probably fix it just by checking the type of the value first. Or casting it in a different way. You have several options, as a bonus I think they all do the null check automatically:

  1. Use "is" to check the type, then cast only if it is the correct type. Probably no need for null check anymore.
if (value is IEntitySessionResult)
{
    var result = (IEntitySessionResult)value;

    // continue
}
else
{
    return "";
}
  1. Use "as" to do a "safe" cast: if the type is not right, this will not error but just make result null. This is basically shorthand for option 1.
var result = value as IEntitySessionResult;
if (result == null)
{
    return "";
}

// continue
  1. Or maybe even this one (not sure if we support this more recent C# feature) where the type check and cast is done at the same time:
if (value is IEntitySessionResult result)
{
    // continue
}
else 
{
    return "";
}
Kyle H.
Reply #2
· edited

I tried the second method and the error has gone away - I'm going to test everything tonight to be sure it doesn't slow. Thank you! Not sure I ever would have caught that properly.

Kyle

Edit

I can confirm this solved my problem. Thanks Nick!

Emmanuel S.
Reply #3
· edited

I think i've got the same problem on a lot of my scripts ....
To understand, you replace

IEntitySessionResult result = (IEntitySessionResult) value;

by

var result = value as IEntitySessionResult;
if (result == null)
{
    return "";
}

??

Emmanuel S.
Reply #4
· edited

I check this morning and it is different !
I've got no errors return on Script Performance and Event Log.

But my computer needs more and more time to do what I want in ATVO. At start if I show Widget driver it is on time, but after a moment, it takes 2/3 seconds then 10 seconds to show until ATVO is totaly freeze.

I use 19 scripts on this one, and I begin to look to stop use scripts for stop this freeze issue.

A capture of my Script Performance:

But informations on overlay, when it appears are in good time, PIT or speed ....

Computer: laptop with gtx 1070 / i7-6700HQ / 16 Go Ram

Nick Thissen Appgineering
Reply #5

Can you show some of these scripts (the worst ones)?

Emmanuel S.
Reply #6
· edited

"""Edit: I doing some tests, cause I think the problems comes from an error of manipulation of me. I change somes informations dirct in the XML like add actions in StoryBoard cause it is quick, but I think I do some little errors that don't stop system.
So I do my theme again without touch anything in XML an I will say if it is OK."""

ClassColor, I bind ClassColor

using System;
using ATVO.ThemesSDK;
using ATVO.ThemeEditor.ThemeModels;
using ATVO.ThemeEditor.Scripting.DotNET;
using System.Windows.Media;
using ATVO.ThemesSDK.Data.Entity;
using ATVO.ThemesSDK.Data.Results;

namespace Scripts
{
 public class SC_ClassColor : IScript
 {
 public object Execute(ThemeContentItem item, object value, string parameter, ISimulation sim)
 {
 if (value == null)
 {
     // do something appropriate, in this case probably just return nothing
     return null;
 } 
 

//IEntitySessionResult result = (IEntitySessionResult) value; 

//var Classcolor = result.Entity.Car.Class.Color;
var Classcolor = value.ToString();
 var numClasses = sim.Session.ClassManager.Classes.Count;
 var hex = "#ffe617";

 if (numClasses == 1)
 return (Color) ColorConverter.ConvertFromString(hex);
 
 else 
 
 return (Color) ColorConverter.ConvertFromString(Classcolor);
 }
 }
}
Emmanuel S.
Reply #7

Stand_Name_TD, Bind EntitySessionResult

using System;
using ATVO.ThemesSDK;
using ATVO.ThemeEditor.ThemeModels;
using ATVO.ThemeEditor.Scripting.DotNET;
using ATVO.ThemesSDK.Data.Results;
using ATVO.ThemesSDK.Data.Entity;
using System.Drawing;
using System.Windows;

namespace Scripts
{
	public class SC_Stand_Name_TD : IScript
	{
		public object Execute(ThemeContentItem item, object value, string parameter, ISimulation sim)
		{ if (value == null)
				{
			    // do something appropriate, in this case probably just return nothing
			    return null;
				}

// If you bind to 'entitysessionresult_object':

var result = (IEntitySessionResult)value; 
var entity = result.Entity;
var sname = result.Entity.Drivers[0].ShortName;

//var id = entity.Id;

var name = entity.Name;
int nameL = name.Length;
if (nameL < 5)
{name = name+"    ";
nameL = name.Length;}
var first = name.Substring(0,4);
int temp = nameL - 4;
int temp1 = nameL - 5;
var end = name.Substring(temp,4);

 

// If it's a team session:
// - id will be Team ID, name will be Team name

// If it's a single driver session:
// - id will be driver customer ID, name will be driver name
if (entity is ITeam)
{

if (first == "Team" || first == "TEAM" || first == "team")
name = name.Substring(5,temp1);
nameL = name.Length;
if (end == "Team" || end == "TEAM" || end == "team")
name =  name.Substring(0,temp1);
nameL = name.Length;
if (nameL > 20)
name = name.Substring(0,20);

return name;

//if (nameL > 25 && first == "Team" || first == "TEAM" || first == "team")
//return name.Substring(5,19);
//return name;

//if (first == "Team" || first == "TEAM" || first == "team")
//return name.Substring(5,temp1);

//if (nameL > 25 && end == "Team" || end == "TEAM" || end == "team")
//return name.Substring(0,19)+nameL;

//if (end == "Team" || end == "TEAM" || end == "team")
//return name.Substring(0,temp1 + nameL);

//else
//return name;
}
return sname;
		}
	}
}
Emmanuel S.
Reply #8

Font Size use to override font in a label

using System;
using ATVO.ThemesSDK;
using ATVO.ThemeEditor.ThemeModels;
using ATVO.ThemeEditor.Scripting.DotNET;
using ATVO.ThemesSDK.Data.Results;
using ATVO.ThemesSDK.Data.Entity;
using System.Drawing;
using System.Windows;

namespace Scripts
{
	public class SC_Stand_FontSize : IScript
	{
		public object Execute(ThemeContentItem item, object value, string parameter, ISimulation sim)
		{ if (value == null)
				{
			    // do something appropriate, in this case probably just return nothing
			    return null;
				}

// If you bind to 'entitysessionresult_object':

var result = (IEntitySessionResult)value; 
var entity = result.Entity;

 
// If it's a team session:
// - id will be Team ID, name will be Team name

// If it's a single driver session:
// - id will be driver customer ID, name will be driver name
if (entity is ITeam)
{
return 17;
}
return 24;
		}
	}
}
Lukas R.
Reply #9

Ooh, very helpful! That's just saved my theme as well! That's one for '101 on ATVO scripting' book ??

Emmanuel S. wrote:
I think i've got the same problem on a lot of my scripts ....
To understand, you replace

IEntitySessionResult result = (IEntitySessionResult) value;

by

var result = value as IEntitySessionResult;
if (result == null)
{
    return "";
}

??

Archive · Read-only

New replies have moved to Discord.