| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- using System;
- using System.Linq;
- using System.Reflection;
- using System.Runtime.InteropServices;
- using Urho;
- using Type = System.Type;
- namespace StructsValidator
- {
- class Program
- {
- static string codeContent;
- static void Main(string[] args)
- {
- //get all structs from Urho.dll
- var structs = typeof (UrhoObject).Assembly.GetTypes().Where(t => t.IsValueType && !t.IsPrimitive && !t.IsEnum);
-
- // only those with Sequential layout
- structs = structs.Where(t => t.IsLayoutSequential).ToArray();
- AppendC(
- @"using namespace Urho3D;
- void check_size(int actual, int expected, const char * typeName)
- {
- if (actual != expected)
- printf(""sizeof(%s) is %d but %d is expected"", typeName, actual, expected);
- }
- void check_offset(int actual, int expected, const char* typeName, const char* fieldName)
- {
- if (actual != expected)
- printf(""offset(%s, %s) is %d but %d is expected"", typeName, fieldName, actual, expected);
- }
- int main()
- {");
- foreach (var type in structs)
- {
- AddTest(type);
- }
- AppendC("}");
- //TODO: flush codeContent, compile and execute.
- }
- static void AddTest(Type type)
- {
- var managedName = type.Name;
- var nativeName = ResolveUrhoType(managedName);
- if (nativeName == null)
- return;
- var size = Marshal.SizeOf(type);
- AppendC($"\n\t// {managedName}:");
- AppendC($"\tcheck_size(sizeof({nativeName}), {size}, \"{managedName}\");");
- foreach (var field in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
- {
- var managedFieldName = field.Name;
- var nativeFieldName = ResolveUrhoTypeField(managedName, managedFieldName);
- var offset = Marshal.OffsetOf(type, managedFieldName);
- AppendC($"\tcheck_offset(offsetof({nativeName}, {nativeFieldName}), {offset}, \"{managedName}\", \"{managedFieldName}\");");
- }
- }
- static string ResolveUrhoTypeField(string typeName, string fieldName)
- {
- fieldName = fieldName.Trim('_');
- fieldName = char.ToLowerInvariant(fieldName[0]) + fieldName.Substring(1);
- if (fieldName.EndsWith("Ptr"))
- fieldName = fieldName.Remove(0, fieldName.Length - 3);
- if (typeName != "CrowdObstacleAvoidanceParams")
- fieldName += "_";
- return fieldName;
- }
- static string ResolveUrhoType(string name)
- {
- string[] ignoredTypes = {
- //TODO: handle these types
- "nuint",
- "nint",
- "BezierConfig",
- "CollisionData",
- "StringHashRef",
- "StringHash",
- "Iterator",
- "AttributeInfo",
- "ProfilerBlock",
- "WeakPtr",
- "VectorBase",
- "dtQueryFilter",
- "RandomAccessIterator",
- "Matrix3",
- "Matrix4",
- "Matrix4d",
- "Quaterniond",
- "Quaternion",
- "Vector2d",
- "Vector3d",
- "Vector4d",
- "UrhoString",
- "CascadeParameters",
- };
- if (name.EndsWith("EventArgs") || ignoredTypes.Contains(name))
- return null;
- if (name == "UrhoString")
- return "String";
- return name;
- }
- static void AppendC(string line)
- {
- codeContent += line + "\n";
- }
- }
- }
|