Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,6 @@ GameData/RemoteTech/Plugins/RemoteTech.xml
GameData/RemoteTech/Versioning/RemoteTech.version
GameData/build.txt
src/RemoteTech/RemoteTech.sln.ide/

# In-game test plugin build output (the source lives under tests/)
GameData/RemoteTech.Tests/
40 changes: 40 additions & 0 deletions RemoteTech.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RemoteTech", "src\RemoteTech\RemoteTech.csproj", "{67470554-F754-4664-AC7C-D002943ACD72}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RemoteTech.Tests", "tests\RemoteTech.Tests\RemoteTech.Tests.csproj", "{A7585803-6434-436E-BFC1-B09A520425D7}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RemoteTech.InGameTests", "tests\RemoteTech.InGameTests\RemoteTech.InGameTests.csproj", "{C5C1CBBB-83DD-4850-A6F8-6823AB14B54E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{065AC022-06A2-4079-9DEC-051B87D76A08}"
ProjectSection(SolutionItems) = preProject
CHANGES.md = CHANGES.md
CONTRIBUTING.md = CONTRIBUTING.md
README.md = README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{67470554-F754-4664-AC7C-D002943ACD72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{67470554-F754-4664-AC7C-D002943ACD72}.Debug|Any CPU.Build.0 = Debug|Any CPU
{67470554-F754-4664-AC7C-D002943ACD72}.Release|Any CPU.ActiveCfg = Release|Any CPU
{67470554-F754-4664-AC7C-D002943ACD72}.Release|Any CPU.Build.0 = Release|Any CPU
{A7585803-6434-436E-BFC1-B09A520425D7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A7585803-6434-436E-BFC1-B09A520425D7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A7585803-6434-436E-BFC1-B09A520425D7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A7585803-6434-436E-BFC1-B09A520425D7}.Release|Any CPU.Build.0 = Release|Any CPU
{C5C1CBBB-83DD-4850-A6F8-6823AB14B54E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C5C1CBBB-83DD-4850-A6F8-6823AB14B54E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C5C1CBBB-83DD-4850-A6F8-6823AB14B54E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C5C1CBBB-83DD-4850-A6F8-6823AB14B54E}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
12 changes: 0 additions & 12 deletions RemoteTech.slnx

This file was deleted.

141 changes: 83 additions & 58 deletions src/RemoteTech/API/API.cs

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions src/RemoteTech/AddOns/Kerbalism.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@

namespace RemoteTech.AddOns
{
/// <summary> Simple class to detect if Kerbalism is loaded </summary>
/// <summary>
/// Simple class to detect if Kerbalism is loaded
/// </summary>
public static class Kerbalism
{
private static readonly Type API;
Expand All @@ -21,7 +23,9 @@ static Kerbalism()
}
}

/// <summary> Returns true if Kerbalism is detected for the current game </summary>
/// <summary>
/// Returns true if Kerbalism is detected for the current game
/// </summary>
public static bool Exists
{
get { return API != null; }
Expand Down
39 changes: 20 additions & 19 deletions src/RemoteTech/AntennaManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ public class AntennaManager : IDisposable, IEnumerable<IAntenna>
public event Action<IAntenna> OnRegister = delegate { };
public event Action<IAntenna> OnUnregister = delegate { };

public IEnumerable<IAntenna> this[ISatellite s] { get { return For(s.Guid); } }
public IEnumerable<IAntenna> this[Vessel v] { get { return For(v.id); } }
public IEnumerable<IAntenna> this[Guid g] { get { return For(g); } }
public IReadOnlyList<IAntenna> this[ISatellite s] { get { return For(s.Guid); } }
public IReadOnlyList<IAntenna> this[Vessel v] { get { return For(v.id); } }
public IReadOnlyList<IAntenna> this[Guid g] { get { return For(g); } }

private readonly Dictionary<Guid, List<IAntenna>> mLoadedAntennaCache =
new Dictionary<Guid, List<IAntenna>>();
private readonly Dictionary<Guid, List<IAntenna>> mProtoAntennaCache =
new Dictionary<Guid, List<IAntenna>>();
private readonly Dictionary<Guid, List<ProtoAntenna>> mProtoAntennaCache =
new Dictionary<Guid, List<ProtoAntenna>>();

public AntennaManager()
{
Expand All @@ -35,6 +35,15 @@ public AntennaManager()
public void Dispose()
{
GameEvents.onVesselGoOnRails.Remove(OnVesselGoOnRails);

foreach (List<ProtoAntenna> antennas in mProtoAntennaCache.Values)
{
foreach (ProtoAntenna antenna in antennas)
{
antenna.Dispose();
}
}
mProtoAntennaCache.Clear();
}

public void Register(Guid key, IAntenna antenna)
Expand Down Expand Up @@ -98,7 +107,7 @@ public void RegisterProtos(Vessel v)
{
if (!mProtoAntennaCache.ContainsKey(key))
{
mProtoAntennaCache[key] = new List<IAntenna>();
mProtoAntennaCache[key] = new List<ProtoAntenna>();
}
ProtoAntenna proto = new ProtoAntenna(v, pps, ppms);
mProtoAntennaCache[key].Add(proto);
Expand All @@ -113,25 +122,22 @@ public void UnregisterProtos(Guid key)

if (!mProtoAntennaCache.ContainsKey(key)) return;

foreach (IAntenna a in mProtoAntennaCache[key])
foreach (ProtoAntenna a in mProtoAntennaCache[key])
{
OnUnregister.Invoke(a);
a.Dispose();
}

mProtoAntennaCache.Remove(key);
}

private IEnumerable<IAntenna> For(Guid key)
private IReadOnlyList<IAntenna> For(Guid key)
{
if (mLoadedAntennaCache.ContainsKey(key))
{
return mLoadedAntennaCache[key];
}
if (mProtoAntennaCache.ContainsKey(key))
{
return mProtoAntennaCache[key];
}
return Enumerable.Empty<IAntenna>();
return [];
}

private void OnVesselGoOnRails(Vessel v)
Expand Down Expand Up @@ -163,11 +169,6 @@ public static bool IsAntenna(this ProtoPartModuleSnapshot ppms)
ppms.GetBool("IsRTActive");
}

public static bool IsAntenna(this PartModule pm)
{
return pm.Fields.GetValue<bool>("IsRTAntenna") &&
pm.Fields.GetValue<bool>("IsRTPowered") &&
pm.Fields.GetValue<bool>("IsRTActive");
}
public static bool IsAntenna(this PartModule pm) => pm is IAntenna;
}
}
146 changes: 146 additions & 0 deletions src/RemoteTech/Collections/ArrayMap.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
using System;
using System.Collections;
using System.Collections.Generic;

namespace RemoteTech.Collections;

public class ArrayMap<K, V> : IEnumerable<KeyValuePair<K, V>>
{
private readonly Dictionary<K, int> indices;
private readonly List<K> keys;
private readonly List<V> values;

public int Count => values.Count;
public V this[K key]
{
get => values[indices[key]];
set
{
if (indices.TryGetValue(key, out var index))
{
keys[index] = key;
values[index] = value;
}
else
{
index = values.Count;
indices.Add(key, index);
keys.Add(key);
values.Add(value);
}
}
}

public ReadOnlySpan<K> Keys => keys.AsReadOnlySpan();
public Span<V> Values => values.AsSpan();

public ArrayMap()
{
indices = [];
keys = [];
values = [];
}

public ArrayMap(int capacity)
{
indices = new(capacity);
keys = new(capacity);
values = new(capacity);
}

public bool TryGetValue(K key, out V value)
{
value = default;
if (!indices.TryGetValue(key, out var index))
return false;

value = values[index];
return true;
}

public bool ContainsKey(K key) => indices.ContainsKey(key);

public int IndexOf(K key) => indices.TryGetValue(key, out var index) ? index : -1;

public void Add(K key, V value)
{
var count = Count;
indices.Add(key, count);
keys.Add(key);
values.Add(value);
}

public bool TryAdd(K key, V value)
{
if (indices.ContainsKey(key))
return false;

var index = Count;
indices.Add(key, index);
keys.Add(key);
values.Add(value);
return true;
}

public bool Remove(K key)
{
if (!indices.TryGetValue(key, out var index))
return false;

if (index == Count - 1)
{
indices.Remove(key);
keys.RemoveAt(index);
values.RemoveAt(index);
}
else
{
var count = Count;
var other = keys[index] = keys[count - 1];
values[index] = values[count - 1];

indices[other] = index;
indices.Remove(key);
keys.RemoveAt(count - 1);
values.RemoveAt(count - 1);
}

return true;
}

public void Clear()
{
indices.Clear();
keys.Clear();
values.Clear();
}

public Enumerator GetEnumerator() => new(this);
IEnumerator<KeyValuePair<K, V>> IEnumerable<KeyValuePair<K, V>>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

public struct Enumerator(ArrayMap<K, V> map) : IEnumerator<KeyValuePair<K, V>>
{
List<K>.Enumerator keys = map.keys.GetEnumerator();
List<V>.Enumerator vals = map.values.GetEnumerator();

public KeyValuePair<K, V> Current => new(keys.Current, vals.Current);
object IEnumerator.Current => Current;

public bool MoveNext() => keys.MoveNext() & vals.MoveNext();

void IEnumerator.Reset()
{
DoReset(ref keys);
DoReset(ref vals);
}

public void Dispose() { }

private static void DoReset<T>(ref T enumerator)
where T : IEnumerator
{
enumerator.Reset();
}
}
}
Loading
Loading