Question: Array offset, and ranges
See original GitHub issueI am in a bit of a pickle when it comes to array ranges. I have managed to clean most of my code. The way my API works is as follows:
Two functions which can read any tag or array (1d, 2d, 3d), although I mostly care for 1d:
These return a Response object which has tagname, value as string or string[], and status. Read and Write.
await myPLC.Read("BaseBOOL", TagType.Bool);
await myPLC.Read("BaseBOOLArray", TagType.Bool, 128);
await myPLC.Write("BaseDINT", TagType.Dint, 545437493);
ReadTag and WriteTag also return a Response object, but value is an actual type:
await myPLC.ReadTag<DintPlcMapper, int>("BaseDINT");
await myPLC.WriteTag<DintPlcMapper, int>("BaseDINT", 545437492);
[Response: BaseDINT -545437484 Success]
So far so good, Read and Write for single tags, I have cleaned up and have almost no code duplication. For arrays is another story. I have went about how to solve this for a few days but I can’t seem to be able to get it right.
For Array Read Write ranges, for example I only want to read/write from 0 to 10:
await myPLC.Read("BaseSTRINGArray", TagType.String, 128, 0, 10);
await myPLC.Write("BaseSTRINGArray", TagType.String, boolList.ToArray(), 128, 0, 10);
I wanted to have one function that can read an array that is the easy part, however I want to get a range, I can do this easily when I am explictily casting Array.ConvertAll but there is too much code duplication my example below I have for each data type. So I am wondering if there is a better way.
private async Task<Response<string[]>> _ReadArray<M, T>(string tagName, int arrayLength, int startIndex = 0, int count = 0) where M : IPlcMapper<T>, new()
{
var results = await ReadTag<M, T>(tagName, new int[] { arrayLength });
if (results.Status == "Success")
{
string[] arrString = Array.ConvertAll<T, string>(results.Value, Convert.ToString);
// Sanity check to make sure we don't try to access items indices bigger than array
if (startIndex + count > arrayLength)
{
return new Response<string[]>(tagName, "Failure, Out of bounds");
}
if (count > 0)
{
List<T> tagValueList = new List<T>(arrString);
return new Response<string[]>(tagName, tagValueList.GetRange(startIndex, count).ToArray(), "Success");
}
return new Response<string[]>(tagName, arrString, "Success");
}
else
{
return new Response<string[]>(tagName, "Failure");
}
}
My question to you guys, how do you deal with ranges, is there an easier way, or do you think my solution could work somehow?
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (1 by maintainers)
Top GitHub Comments
@TheFern2 - where you are heading with this looks like there will be a bit of friction with making use of the
TagOfT
class - you might want instead to useTag
and do all of the mapping yourself.@timyhac Thanks, looks like that might be the best route.