Space Engineers

Space Engineers

Not enough ratings
GPS Ingame Scripting API - Example (V2)
   
Award
Favorite
Favorited
Unfavorite
File Size
Posted
364.061 KB
28 Jul, 2021 @ 5:02am
1 Change Note ( view )

Subscribe to download
GPS Ingame Scripting API - Example (V2)

Description
An example of how to use the GPS Ingame Scripting API.
Keeps a gps marker at the position of the executing block.

GPSInterface Documentation
class GPSInterfaceV2

GPSInterfaceV2(IMyTerminalBlock)
Initializes the GPSInterfaceV2 with the specified custom data block.

AddGps(string name, Vector3D position, string description, bool persistent, bool showOnHud): Future<int>
Creates a new gps marker.

Clear(): Future<bool>
Deletes all gps markers created by this custom data block.

EditGps(int id, Vector3D position): Future<int>
Moves a gps marker.

GetInterfaceBlock(): IMyTerminalBlock
Returns the custom data block.

IsActive(): Future<bool>
Checks if the mod is active. If the mod is used the future returns true, if not it will never finish.

List(): Future<List<GPS_Entry>
Returns all non-persistent GPS markers created by this custom data block.

RemoveGps(int id): Future<bool>
Removes a gps marker.

Update(): void
Must be called once in the main method to update the futures.


Future<T>

Finished(): bool
Returns true if a result exists or an error occurred, false otherwise.

Failed(): bool
Returns true if an error occurred, false otherwise.

GetError(): string
Returns the error, or null if not present.

Result(): T
Returns the delayed result, if present. If not present, an exception is thrown. Before this method is called, it should be checked with Finished and Failed whether a result is available or not.


GPSInterfaceV2 - Source


Use this code to create markers, or write your own interface. The mod and the scripts communicate via the custom data field, as seen here:

sealed class GPSInterfaceV2 { private static readonly string Version = "0"; private readonly IMyTerminalBlock TerminalBlock; private readonly List < IFuture > Active = new List < IFuture > (); private readonly List < IFuture > Scheduled = new List < IFuture > (); public GPSInterfaceV2(IMyTerminalBlock terminalBlock) { TerminalBlock = terminalBlock; } public IMyTerminalBlock GetInterfaceBlock() => TerminalBlock; public void Update() { if (IsOutReady()) { string[] lines = TerminalBlock.CustomData.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None); for (int i = 1; i < lines.Length; i++) { if (i > Active.Count) { break; } Active.Handle(lines);
}
Active.Clear();
}
if (!IsInReady()) {
TerminalBlock.CustomData = "[Gps-Scripting:IN]Version:" + Version;
foreach(IFuture future in Scheduled) {
future.AppendTo(TerminalBlock);
Active.Add(future);
}
Scheduled.Clear();
}
}

private bool IsInReady() => TerminalBlock.CustomData.StartsWith("[Gps-Scripting:IN]Version:" + Version);
private bool IsOutReady() => TerminalBlock.CustomData.StartsWith("[Gps-Scripting:OUT]Version:" + Version);

private void Command(IFuture future) {
if (IsInReady()) {
future.AppendTo(TerminalBlock);
Active.Add(future);
} else {
Scheduled.Add(future);
}
}

public Future < bool > IsActive() {
Future < bool > r = new FutureBoolean("Active?");
Command(r);
return r;
}

public Future < int > AddGps(string name, Vector3D position, string description = "", bool persistent = false, bool showOnHud = true) {
Future < int > r = new FutureInt(string.Format("Add:{0}:{1}:{2}:{3}:{4}:{5}:{6}", name, description, position.X, position.Y, position.Z, persistent ? "Y" : "N", showOnHud ? "Y" : "N", -1));
Command(r);
return r;
}

public Future < int > EditGps(int gpsHash, Vector3D position) {
Future < int > r = new FutureInt(string.Format("Edit:{0}:{1}:{2}:{3}", gpsHash, position.X, position.Y, position.Z));
Command(r);
return r;
}

public Future < List < GPS_Entry >> List() {
Future < List < GPS_Entry >> r = new FutureListGPS_Entry(string.Format("List"));
Command(r);
return r;
}

public Future < bool > RemoveGps(int gpsHash) {
Future < bool > r = new FutureBoolean(string.Format("Remove:{0}", gpsHash));
Command(r);
return r;
}

public Future < bool > Clear() {
Future < bool > r = new FutureBoolean("Clear");
Command(r);
return r;
}

interface IFuture {
void AppendTo(IMyTerminalBlock terminalBlock);
void Handle(string line);
}
public abstract class Future < T >: IFuture {
private string cache;
private T result;
readonly string InLine;
private string error;

protected Future(string inLine) {
InLine = inLine;
}

public void AppendTo(IMyTerminalBlock terminalBlock) => terminalBlock.CustomData += "\r\n" + InLine;

public void Handle(string line) {
cache = line;
try {
result = Handle0(line, out error);
} catch (Exception e) {
error = e.Message;
}
}

protected abstract T Handle0(string line, out string error);

public T Result() {
if (Failed()) {
throw new Exception("Future failed: " + error);
}
if (Finished()) {
return result;
}
throw new Exception("Future not finished");
}

public bool Finished() => cache != null;
public bool Failed() => error != null;

public string GetError() => error;
}
private class FutureBoolean: Future < bool > {
public FutureBoolean(string inLine): base(inLine) {}
protected override bool Handle0(string line, out string error) {
error = null;
return line.Equals("Ok");
}
}

private class FutureInt: Future < int > {
public FutureInt(string inLine): base(inLine) {}
protected override int Handle0(string line, out string error) {
try {
error = null;
return int.Parse(line);
} catch (ArgumentException) {
error = line;
return -1;
}
}
}

private class FutureListGPS_Entry: Future < List < GPS_Entry >> {
public FutureListGPS_Entry(string inLine): base(inLine) {}
protected override List < GPS_Entry > Handle0(string line, out string error) {
error = null;
return line.Split(new string[] {
"::"
}, StringSplitOptions.None).Where(e => e.Length > 0).Select(i => new GPS_Entry(i)).ToList();
}
}

public sealed class GPS_Entry {
public readonly string Name;
public readonly double X;
public readonly double Y;
public readonly double Z;

public GPS_Entry(string item) {
string[] items = item.Split(new char[] {
':'
}).Select(e => e.Trim()).ToArray();
Name = items[0];
X = double.Parse(items[1]);
Y = double.Parse(items[2]);
Z = double.Parse(items[3]);
}
}
}