Report post

Are you sure you want to report the post shown below? This will send an email to the ATVO administrators. Please include a short reason for reporting.

Users reporting for no reason may be locked out.


Post

Posted by Nick Thissen
on
Perhaps you can make it work easier using the Custom Data Set items. A Custom Data Set is an object in your theme in which you can simply store some raw values (a list of data). Then you can use this as a dataset in a Widget.

You could use a script to dynamically fill the data in a Custom Data Set.

The downside is that a Custom Data Set has only one item per row (one value), there's no way to store for example driver name AND points separately. You can get around that with multiple Custom Data Sets, but then you'd have to create multiple Widgets to show this information. For example one Widget (ticker) that shows the driver names, then another Widget (ticker) for the points, maybe another for car numbers, etc.


I had some downtime at work, here is a quick and dirty example I came up with. Not sure if it compiles but it should be close. You'll need four Custom Data Set objects, a spreadsheet for the standings and a spreadsheet for the point system, see the script.

using System;
using System.Data;
using ATVO.ThemesSDK;
using ATVO.ThemesSDK.Data.Entity;
using ATVO.ThemeEditor.ThemeModels;
using ATVO.ThemeEditor.Scripting.DotNET;
using System.Collections.Generic;

namespace Scripts
{
public class ChampPointScript : IScript
{
private Dictionary<int, int> _pointSystem = new Dictionary<int, int>();
private Dictionary<int, ChampDriver> _standings = new Dictionary<int, ChampDriver>();

public object Execute(ThemeContentItem item, object value, string parameter, ISimulation sim)
{
// Make sure point system and standings are loaded
LoadPointSystem(item.Theme);
LoadStandings(item.Theme);

// Update the points
UpdateSessionStandings(sim);

// Sort by points and assign position
// This updates positions for drivers in the session AND drivers not in the session
UpdateChampPositions();

// Also update the champ results for drivers in the session
// in case you are showing these somewhere else (in another widget)
UpdateSessionChampResults();

// Finally update our Custom Data Sets so the widgets are showing the new results
UpdateDataSets(item.Theme);
}

private void UpdateSessionStandings(ISimulation sim)
{
// Loop through entity results in the session and update the standings
foreach (var result in sim.Session.Current.Results)
{
ChampDriver driver;

// Check if there is a driver in the session who was NOT in the standings csv
if (!_standings.ContainsKey(result.Entity.Id))
{
// This driver isn't in the standings yet, let's add him
driver = new ChampDriver();
driver.CustomerId = result.Entity.Id;
driver.Name = result.Entity.Name;
driver.CarNumber = result.Entity.Car.Number;
driver.ChampPoints = 0;
_standings.Add(driver.CustomerId, driver);
}
else
{
// Otherwise, grab him from memory
driver = _standings[result.Entity.Id];
}

// Link him to the session entity
driver.Entity = result.Entity;

// Add the champ points obtained during this race
driver.LiveChampPoints = driver.ChampPoints + _pointSystem[result.Position]; // Or result.LivePosition to update during a lap
}
}

private void UpdateChampPositions()
{
// Sort the standings by live champ points and assign positions in order
var sorted = _standings.Values.OrderByDescending(d => d.LiveChampPoints);

int position = 1;
foreach (var driver in sorted)
{
driver.LiveChampPosition = position;
position += 1;
}
}

private void UpdateSessionChampResults()
{
foreach (var driver in _standings.Values)
{
// If this driver is in the session, he has his Entity linked up
// If not, Entity is null
if (driver.Entity != null)
{
// update the ChampionshipResult object
var champ = driver.Entity.ChampionshipResult;

champ.Position = driver.ChampPosition; // previous pos
champ.LivePosition = driver.LiveChampPosition; // updated pos
champ.Points = driver.ChampPoints; // previous points
champ.LivePoints = driver.LiveChampPoints; // updated points
}
}
}

private void UpdateDataSets(ITheme theme)
{
// Assuming you have four Custom Data Set items:
var cds_pos = theme.CustomDataSets.Find("cds_pos"); // for champ position
var cds_name = theme.CustomDataSets.Find("cds_name"); // for driver name
var cds_carnum = theme.CustomDataSets.Find("cds_carnum"); // for car num
var cds_points = theme.CustomDataSets.Find("cds_points"); // for champ points

// Clear their data
cds_pos.Data.Clear();
cds_name.Data.Clear();
cds_carnum.Data.Clear();
cds_points.Data.Clear();

// Add the new data in order
foreach (var driver in _standings.Values.OrderBy(d => d.LiveChampPosition))
{
cds_pos.Data.Add(new CustomDataSetItem(driver.LiveChampPosition));
cds_name.Data.Add(new CustomDataSetItem(driver.Name));
cds_carnum.Data.Add(new CustomDataSetItem(driver.CarNumber));
cds_points.Data.Add(new CustomDataSetItem(driver.LiveChampPoints));
}
}

private void LoadPointSystem(ITheme theme)
{
if (_pointSystem.Count == 0)
{
// Read point system from an embedded spreadsheet
// Two columns: position, points
var sheet = theme.Spreadsheets.Find("pointsystem.csv");

foreach (var row in sheet.Table.Data.Rows.OfType<DataRow>())
{
var position = row[0];
var points = row[1];
_pointSystem.Add(position, points);
}
}
}

private void LoadStandings(ITheme theme)
{
if (_standings.Count == 0)
{
// Read current standings from embedded csv
// Columns: customer_id, position, carnumber, drivername, points
var sheet = theme.Spreadsheets.Find("standings.csv");

foreach (var row in sheet.Table.Data.Rows.OfType<DataRow>())
{
var custid = row[0];
var position = row[1];
var carnum = row[2];
var name = row[3];
var points = row[4];

var driver = new ChampDriver();
driver.CustomerId = custid;
driver.ChampPosition = position;
driver.CarNumber = carnum;
driver.Name = name;
driver.ChampPoints = points;

_standings.Add(custid, driver);
}
}
}

public class ChampDriver
{
public IEntity Entity {get;set;}
public int CustomerId {get;set;}
public string CarNumber {get;set;}
public string Name {get;set;}

public int ChampPosition {get;set;}
public int ChampPoints {get;set;}
public int LiveChampPosition {get;set;}
public int LiveChampPoints {get;set;}
}
}
}


This assumes a simple point system with just a relation between current race position and number of points obtained. In your RX example it will be more complicated, but maybe you can figure it out. You'd need to grab the results for each heat and check how many points to obtain.


Note I have no idea about performance for this code. It is constantly updating the data in the Custom Data Sets, if those are bound to a ticker or something it will cause a lot of UI updates. It may work fine, or it may cause lag, no idea, but best not to call this script too often. You could call it every few seconds using a Timer or something.