Skip to content

Commit 2cd05d7

Browse files
committed
Report only the interface the game declares for a block
The terminal page derived a list of interfaces from the type hierarchy, which put IMyFunctionalBlock on 79 of 85 blocks and read as though every block could be fetched through it. It now shows the interface only where the game declares one, and nothing where it does not, rather than presenting a derived answer as an authoritative one. The sampled subtype is not shown either. A type id covers many subtypes and the extractor reads actions and properties off whichever one it happened to spawn, so naming it would suggest the entry applied to that subtype alone. Also fixes the terminal page never regenerating after a generator change: the staleness check compared the output against the data file only, so a fix produced no output at all until the data happened to change. It now considers DocGen's own build time as well.
1 parent 100a653 commit 2cd05d7

5 files changed

Lines changed: 183 additions & 209 deletions

File tree

Source/DocGen/Services/Terminals.cs

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,27 @@ public class Terminals
2222

2323
public static async Task Update(string fileName, string output, Action<string> updateStatusFn)
2424
{
25-
// Check if regeneration is needed (simple timestamp check)
26-
if (File.Exists(output) && File.GetLastWriteTimeUtc(output) >= File.GetLastWriteTimeUtc(fileName))
25+
// Regenerate when either the data or this generator is newer than the output. Comparing against the
26+
// data alone meant a fix to the generator produced nothing at all until the data happened to change,
27+
// which is silent and very easy to mistake for the fix not working.
28+
if (File.Exists(output))
2729
{
28-
updateStatusFn?.Invoke("Skipping (output up-to-date)");
29-
return;
30+
var outputWritten = File.GetLastWriteTimeUtc(output);
31+
var newestInput = File.GetLastWriteTimeUtc(fileName);
32+
33+
var generator = typeof(Terminals).Assembly.Location;
34+
if (!string.IsNullOrEmpty(generator) && File.Exists(generator))
35+
{
36+
var generatorBuilt = File.GetLastWriteTimeUtc(generator);
37+
if (generatorBuilt > newestInput)
38+
newestInput = generatorBuilt;
39+
}
40+
41+
if (outputWritten >= newestInput)
42+
{
43+
updateStatusFn?.Invoke("Skipping (output up-to-date)");
44+
return;
45+
}
3046
}
3147

3248
updateStatusFn?.Invoke("Loading cache...");
@@ -67,10 +83,16 @@ public void Save(string fileName)
6783
document.AppendLine($"## {GetDisplayName(block)}");
6884
document.AppendLine();
6985

70-
var interfaces = GetFetchableAs(block);
71-
if (interfaces.Any())
86+
// Only what the game itself states. The interface is reported when the game declares one for the
87+
// block and left out otherwise: a dozen blocks carry no such declaration, and working one out
88+
// from the type hierarchy produced answers that looked authoritative without being so.
89+
//
90+
// The sampled subtype is deliberately not shown. A type id covers many subtypes and the extractor
91+
// reads the actions and properties off whichever one it happened to spawn, so naming it would
92+
// suggest the entry applies to that subtype alone when it applies to all of them.
93+
if (!string.IsNullOrEmpty(block.BlockInterfaceType))
7294
{
73-
document.AppendLine("Available as: " + string.Join(", ", interfaces.Select(i => $"`{i}`")));
95+
document.AppendLine($"Interface: `{GetBlockName(block.BlockInterfaceType)}`");
7496
document.AppendLine();
7597
}
7698

@@ -158,27 +180,6 @@ string GetBlockName(string name)
158180
return name;
159181
}
160182

161-
const string TerminalBlockInterface = "IMyTerminalBlock";
162-
163-
/// <summary>
164-
/// The interfaces worth telling someone about: the ones they can actually fetch the block through.
165-
/// </summary>
166-
/// <remarks>
167-
/// Only interfaces descending from <c>IMyTerminalBlock</c> qualify, which drops the cross-cutting ones
168-
/// such as <c>IMyCubeBlock</c>, <c>IMyEntity</c> and <c>IMyInventoryOwner</c> that every block carries
169-
/// and none of which help you find it. <c>IMyTerminalBlock</c> itself is left out because it is true of
170-
/// everything, unless a block has nothing else, in which case it is the honest answer.
171-
/// </remarks>
172-
List<string> GetFetchableAs(BlockInfo block)
173-
{
174-
var interfaces = block.TerminalInterfaces
175-
.Select(GetBlockName)
176-
.Where(name => name != TerminalBlockInterface)
177-
.ToList();
178-
179-
return interfaces.Count > 0 ? interfaces : new List<string> { TerminalBlockInterface };
180-
}
181-
182183
/// <summary>
183184
/// What a block is listed under. The type definition, because it is the one thing every block has:
184185
/// a dozen block classes carry no terminal interface attribute, so the interface name is blank for

docs/spaceengineers/modapi/.mdkapigen

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"Generated": "2026-08-03T18:57:42.1048033Z",
2+
"Generated": "2026-08-03T19:09:29.2055736Z",
33
"Files": [
44
"api-index.js",
55
"build-info.json",

0 commit comments

Comments
 (0)