Skip to content

Commit

Permalink
trygetcomponent
Browse files Browse the repository at this point in the history
  • Loading branch information
Xytabich committed Sep 26, 2021
1 parent 3bd78c0 commit 256a289
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 85 deletions.
168 changes: 83 additions & 85 deletions Assets/Katsudon/Builder/Extensions/Unity/CallGetComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,104 +45,102 @@ bool IOperationBuider.Process(IMethodDescriptor method)
}
includeInactive = method.PopStack();
}
IVariable typeVariable;

bool isGameObject = methodInfo.DeclaringType == typeof(GameObject);
IVariable typeVariable = null;
if(!methodInfo.IsGenericMethod)
{
typeVariable = method.PopStack();
}
var targetVariable = method.PopStack();
BuildGetComponent(method, assemblies, methodInfo, getterName, targetVariable,
typeVariable, includeInactive, (type) => method.GetOrPushOutVariable(type));
return true;
}
return false;
}

if(methodInfo.IsGenericMethod)
public static void BuildGetComponent(IMethodDescriptor method, AssembliesInfo assemblies, MethodInfo methodInfo,
string getterName, IVariable targetVariable, IVariable typeVariable, IVariable includeInactive, Func<Type, IVariable> outCtor)
{
bool isGameObject = methodInfo.DeclaringType == typeof(GameObject);
if(methodInfo.IsGenericMethod)
{
var searchType = methodInfo.GetGenericArguments()[0];
if(Utils.IsUdonAsm(searchType))
{
var searchType = methodInfo.GetGenericArguments()[0];
if(Utils.IsUdonAsm(searchType))
{
var targetVariable = method.PopStack();
BuildGetUdonComponent(method, targetVariable, isGameObject, getterName,
method.machine.GetConstVariable(assemblies.GetTypeInfo(searchType).guid),
includeInactive, method.GetOrPushOutVariable(searchType)
);
return true;
}
else if(searchType != typeof(UdonBehaviour))
{
var targetVariable = method.PopStack();
ExternCall(method,
GetGenericExternName(isGameObject, includeInactive == null, getterName),
targetVariable, method.machine.GetConstVariable(searchType, typeof(Type)),
true, includeInactive,
method.GetOrPushOutVariable(searchType)
);
return true;
}
else
{
typeVariable = method.machine.GetConstVariable(searchType, typeof(Type));
}
BuildGetUdonComponent(method, targetVariable, isGameObject, getterName,
method.machine.GetConstVariable(assemblies.GetTypeInfo(searchType).guid),
includeInactive, outCtor(searchType)
);
return;
}
else if(searchType != typeof(UdonBehaviour))
{
ExternCall(method,
GetGenericExternName(isGameObject, includeInactive == null, getterName),
targetVariable, method.machine.GetConstVariable(searchType, typeof(Type)),
true, includeInactive,
outCtor(searchType)
);
return;
}
else
{
typeVariable = method.PopStack();
typeVariable = method.machine.GetConstVariable(searchType, typeof(Type));
}
}

if(typeVariable is IConstVariable constVariable)//TODO: move to GetComponentT part
{
if(Utils.IsUdonAsm((Type)constVariable.value))
{
var targetVariable = method.PopStack();

if(typeVariable is IConstVariable constVariable)//TODO: move to GetComponentT part
{
if(Utils.IsUdonAsm((Type)constVariable.value))
{
BuildGetUdonComponent(method, targetVariable, isGameObject, getterName,
typeVariable, includeInactive, method.GetOrPushOutVariable(typeof(Component)));
return true;
}
else
{
ExternCall(method,
GetExternName(isGameObject, includeInactive == null, getterName),
targetVariable, typeVariable,
false, includeInactive,
method.GetOrPushOutVariable(typeof(Component))
);
return true;
}
}
else
{
var outVariable = method.GetOrPushOutVariable(typeof(Component));
/*
Component GetComponent(Type|Guid searchType)
{
if(searchType.GetType() != typeof(Guid)) return GetComponent(searchType);
BuildGetUdonComponent(method, targetVariable, isGameObject, getterName,
typeVariable, includeInactive, outCtor(typeof(Component)));
}
else
{
ExternCall(method,
GetExternName(isGameObject, includeInactive == null, getterName),
targetVariable, typeVariable,
false, includeInactive,
outCtor(typeof(Component))
);
}
}
else
{
var outVariable = outCtor(typeof(Component));
/*
Component GetComponent(Type|Guid searchType)
{
if(searchType.GetType() != typeof(Guid)) return GetComponent(searchType);
// ... search by guid
}
*/
var typeOfType = method.GetTmpVariable(typeof(Type));
typeVariable.Allocate();
method.machine.AddExtern("SystemObject.__GetType__SystemType", typeOfType, typeVariable.OwnType());
var guidCondition = method.GetTmpVariable(typeof(bool));
method.machine.BinaryOperatorExtern(BinaryOperator.Inequality, typeOfType,
method.machine.GetConstVariable(typeof(Guid), typeof(Type)), guidCondition);
var guidSearchLabel = new EmbedAddressLabel();
method.machine.AddBranch(guidCondition, guidSearchLabel);
// ... search by guid
}
*/
var typeOfType = method.GetTmpVariable(typeof(Type));
typeVariable.Allocate();
method.machine.AddExtern("SystemObject.__GetType__SystemType", typeOfType, typeVariable.OwnType());
var guidCondition = method.GetTmpVariable(typeof(bool));
method.machine.BinaryOperatorExtern(BinaryOperator.Inequality, typeOfType,
method.machine.GetConstVariable(typeof(Guid), typeof(Type)), guidCondition);
var guidSearchLabel = new EmbedAddressLabel();
method.machine.AddBranch(guidCondition, guidSearchLabel);

typeVariable.Allocate();
ExternCall(method,
GetExternName(isGameObject, includeInactive == null, getterName),
targetVariable, typeVariable,
false, includeInactive,
outVariable
);
var endLabel = new EmbedAddressLabel();
method.machine.AddJump(endLabel);
typeVariable.Allocate();
ExternCall(method,
GetExternName(isGameObject, includeInactive == null, getterName),
targetVariable, typeVariable,
false, includeInactive,
outVariable
);
var endLabel = new EmbedAddressLabel();
method.machine.AddJump(endLabel);

method.machine.ApplyLabel(guidSearchLabel);
BuildGetUdonComponent(method, targetVariable, isGameObject, getterName, typeVariable, includeInactive, outVariable);
method.machine.ApplyLabel(guidSearchLabel);
BuildGetUdonComponent(method, targetVariable, isGameObject, getterName, typeVariable, includeInactive, outVariable);

method.machine.ApplyLabel(endLabel);
return true;
}
}
method.machine.ApplyLabel(endLabel);
}
return false;
}

private static string GetExternName(bool gameObject, bool defaultCall, string getterName)
Expand Down
49 changes: 49 additions & 0 deletions Assets/Katsudon/Builder/Extensions/Unity/CallTryGetComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using System.Reflection;
using System.Reflection.Emit;
using Katsudon.Info;
using UnityEngine;

namespace Katsudon.Builder.Extensions.UnityExtensions
{
[OperationBuilder]
public class CallTryGetComponent : IOperationBuider
{
public int order => 15;

private AssembliesInfo assemblies;

private CallTryGetComponent(AssembliesInfo assemblies)
{
this.assemblies = assemblies;
}

bool IOperationBuider.Process(IMethodDescriptor method)
{
var methodInfo = method.currentOp.argument as MethodInfo;
if(methodInfo.Name == nameof(Component.TryGetComponent) &&
(methodInfo.DeclaringType == typeof(Component) || methodInfo.DeclaringType == typeof(GameObject)))
{
var componentOutVariable = method.PopStack();
IVariable typeVariable = null;
if(!methodInfo.IsGenericMethod)
{
typeVariable = method.PopStack();
}
var targetVariable = method.PopStack();
CallGetComponent.BuildGetComponent(method, assemblies, methodInfo, nameof(Component.GetComponent),
targetVariable, typeVariable, null, _ => componentOutVariable);
method.machine.AddExtern("UnityEngineObject.__op_Inequality__UnityEngineObject_UnityEngineObject__SystemBoolean",
() => method.GetOrPushOutVariable(typeof(bool)), componentOutVariable.OwnType(), method.machine.GetConstVariable(null).OwnType());
return true;
}
return false;
}

public static void Register(IOperationBuildersRegistry container, IModulesContainer modules)
{
var builder = new CallTryGetComponent(modules.GetModule<AssembliesInfo>());
container.RegisterOpBuilder(OpCodes.Call, builder);
container.RegisterOpBuilder(OpCodes.Callvirt, builder);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 256a289

Please sign in to comment.