Skip to content

Instantly share code, notes, and snippets.

View pardeike's full-sized avatar
💭
Innovating 🛠

Andreas Pardeike pardeike

💭
Innovating 🛠
View GitHub Profile
// helper class for scribing ref-deep dicts
public class Scribe_Dictionary<T, S>
{
List<T> tmpKeys;
List<S> tmpVals;
public void Scribe(ref Dictionary<T, S> dict, string name)
{
if (Verse.Scribe.mode == LoadSaveMode.Saving)
{
using HarmonyLib;
using RimWorld;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Verse;
using Verse.Sound;
@pardeike
pardeike / ListAllOpenFiles.swift
Created September 29, 2020 19:16
List all open files in iOS
// see https://developer.apple.com/forums/thread/655225
func openFilePaths() -> [String] {
(0..<getdtablesize()).map { fd in
// Return "" for invalid file descriptors.
var flags: CInt = 0
guard fcntl(fd, F_GETFL, &flags) >= 0 else {
return ""
}
// Return "?" for file descriptors not associated with a path, for
// example, a socket.
@pardeike
pardeike / EnumeratorMethodShowcase.txt
Last active October 1, 2022 20:17
How C# enumerator methods look like at IL code level
// The following C# code from LINQPad (free windows app) uses a method (Test) that
// returns an enumeration. Have a look how the IL code that the compiler generates
// looks like:
static IEnumerable<int> Test()
{
yield return 100;
var n = Rand.Range(200, 500);
yield return n;
yield return 600;
@pardeike
pardeike / Main.cs
Last active November 18, 2020 17:01
Complex reverse patching
/* the following will print
A: val1=123, val2=456
B: val1=123
With C, we also have 456
C: val1=123
B: done
A: done
Press any key to exit
*/
@pardeike
pardeike / argument-passing-matrix.linq
Last active December 22, 2020 13:36
Argument passing matrix
void Main()
{
var obj = new SomeObject();
var val = new SomeValue { n = 999 };
Original_Object(obj);
Original_Value(val);
Original_Object_Ref(ref obj);
Original_Value_Ref(ref val);
Console.WriteLine(val.n);
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>Analyzer</RootNamespace>
<AssemblyName>PerformanceAnalyzer</AssemblyName>
<TargetFramework>net472</TargetFramework>
<LangVersion>8.0</LangVersion>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>..\1.2\Assemblies\</OutputPath>
<Optimize>true</Optimize>
// use with LINQPad
void Main()
{
var f = new Foo();
var n1 = Traverse.Create(f).Field("bar").Field("n").GetValue<int>();
Console.WriteLine($"n1={n1}");
// does not work because `Field("bar") returns a copy of the struct
void Main()
{
Process(typeof(AttackTargetFinder));
}
static Dictionary<FieldInfo, FieldInfo> replacementFields = new Dictionary<FieldInfo, FieldInfo>();
public static void Process(Type type)
{
var aName = new AssemblyName(type.Name + "_Replacement");
var ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.RunAndSave);
void Main()
{
Patches.FieldReplace(typeof(TargetClass), "foo");
// Test code
var tc = new TargetClass();
tc.Test();
tc.Test();
}