On Saturday, 9 October 2021 at 06:50:19 UTC, Paulo Pinto wrote:
> You can simulate scope(exit) with an helper struct.
[snip]
Naturally D's scope(exist) is cleaner to write.
Lol, I haven't done this put my C# definitely shows I wish I had a D compiler (and understand C# a bit poorly). This is a somewhat outdated C# compiler, not all of the newest tricks are available:
public struct Ui
{ //...
}
// elsewhere
abstract class Panel
{ // ...
public Ui[] uiState;
// ...
}
The story behind that array is that I wanted a reference to the struct. Later on I came up with a less hackish way to achieve the same:
//Intended for the same as C standard library div_t: result of division.
public struct DivInt
{ public int quot;
public int rem;
}
public class Ref<Struct>
{ public Struct value;
public Ref(){}
public Ref(Struct val){value = val;}
}
Other examples of my programming:
public static class Utility
{ //Because Debug.Assert message does not pop up on web page
[System.Diagnostics.Conditional("DEBUG")]
public static void Assert (bool condition)
{ Assert(condition, "Program in illegal state. Exiting.");
}
[System.Diagnostics.Conditional("DEBUG")]
public static void Assert (bool condition, string message)
{ if (!condition)
{ Window.Alert(message);
throw new InvalidOperationException();
}
}
public static void Swap<T>(ref T a, ref T b)
{ var temp = a;
a = b;
b = temp;
}
//don't use to add many elements sequentially in a loop, as that's inefficient.
public static void Append<T>(ref T[] array, T what)
{ var oldLength = array.Length;
Array.Resize(ref array, oldLength + 1);
array[oldLength] = what;
}
//always rounds down, also when negative.
public static DivInt Div(this int dividee, int divisor)
{ int quot;
int rem;
// Could this be assigned directly to the result value?
quot = Math.DivRem(dividee, divisor, out rem);
if(rem < 0)
{ quot--;
rem += divisor;
}
return new DivInt{quot = quot, rem = rem};
}
public static void Each<T>(this IEnumerable<T> range, Action<T> todo)
{ foreach(T el in range) todo(el);
}
public static IEnumerable<Sequence<T, int>> Enumerate<T>(this IEnumerable<T> range, int startValue)
{ return range.Zip(Enumerable.Range(startValue, int.MaxValue), (x, y) => new Sequence<T, int>(x, y));
}
public static IEnumerable<Sequence<T, int>> Enumerate<T>(this IEnumerable<T> range)
{ return range.Enumerate(0);
}
}
My way of serializing and deserializing data to/from files would probably get red pen marks from fairly much everything. Representive deserialization here, struct data is commented in real life but not here because didn't bother to translate:
public struct PillarInstallation
{ public Slab pillar;
public Vector3D gap;
public float angle;
public Ref<StoneCutType>[] sideCutTypes
// other member functions...
public static PillarInstallation Deserialize
( byte[] from,
int fromI,
YhkVersion yhkVersion,
int pillarI,
Dictionary<string, int> textureChecker
)
{ int fromIAtStart = fromI;
PillarInstallation result = new PillarInstallation();
result.pillar = Slab.Deserialize(from, fromI, textureChecker);
fromI += Slab.serializedSize;
result.gap = Vector3D.Deserialize(from, fromI);
fromI += Vector3D.serializedSize;
if (yhkVersion.Encompasses(new YhkVersion(8)))
{ result.angle = Utility.DeserializeFloat(from, fromI);
fromI += 4;
} else result.angle = 0;
result.sideCutTypes = new Ref<StoneCutType>[2];
if (yhkVersion.Encompasses(new YhkVersion(12)))
{ for(int i=0; i<result.sideCutTypes.Length; i++) if(from[fromI+i]!=255)
{ var refVar = new Ref<StoneCutType>();
refVar.value = (StoneCutType)from[fromI+i];
result.sideCutTypes[i] = refVar;
}
} else
{ bool interfaceSawed = Utility.DeserializeInt(from, fromI) % 2 > 0;
if (interfaceSawed)
{ var refVar = new Ref<StoneCutType>(StoneCutType.sawed);
result.sideCutTypes[pillarI^1] = refVar;
}
}
fromI += 4;
Utility.Assert(fromIAtStart + GetSerializedSize(yhkVersion) == fromI, "read " + (fromI - fromIAtStart) + " bytes, should have read " + GetSerializedSize(yhkVersion));
return result;
}
}