示例#1
0
    public CompMethodsInAssemblyType SameAppDomainCompile(string code, bool addSelfAttach = true)
    {
        if (addSelfAttach)
        {
            code = SourceManipulation.AddSelfAttachToSource(code);
        }
        Assembly ass = Compilation.GenerateAssemblyInMemory(code, false);
        CompMethodsInAssemblyType funcs = Compilation.GenerateAllMethodsFromAssembly(ass);

        return(funcs);
    }
示例#2
0
    /// <summary>
    /// Registers a compile time mono to given target.
    /// </summary>
    /// <param name="target">Target to which to attach the runtime mono.</param>
    /// <param name="funcs">Mono information: name, methods and pramaters.</param>
    /// <returns></returns>
    public MonoBehaviour AttachCompiletimeMono(GameObject target, CompMethodsInAssemblyType funcs, MonoBehaviour mono, string source)
    {
        /// Attaches the given mono and registeres in attachedMonos
        var monoData = this.AttachAndAddToDict(funcs, target, mono);

        /// If a mono with the same name exists and the method singnature changed send it to the UI to redraw it.
        if (monoData.changesInMethodSignature)
        {
            ReferenceBuffer.Instance.ManageProcUI.RegisterNewOrChangedMono(this.GenerateButtonInformation(monoData, target, source));
            monoData.changesInMethodSignature = false;
        }
        return(null);
    }
示例#3
0
    /// <summary>
    /// Does two things:
    ///     If attach is true, it attaches the mono to the target and registeres it in attachedMonos
    ///     If attach is false, means that the script is already attached and it only regerteres it in the same collection.
    /// Also if there is a mono with that name already, it remeves the old one and registeres the new one.
    /// </summary>
    /// <param name="funcs"></param>
    /// <param name="target"></param>
    /// <param name="attach"></param>
    /// <param name="alreadyAttachedMono"> If null we need to attach what is passed. If not null - this is the mono that is already attached!</param>
    /// <returns></returns>
    private TargetManagerMonoWithNameAndMethods AttachAndAddToDict(
        CompMethodsInAssemblyType funcs,
        GameObject target,
        MonoBehaviour alreadyAttachedMono)
    {
        this.CreateMonoDataIfNoneExists(target);

        /// Getting exsiting monos for target.
        List <TargetManagerMonoWithNameAndMethods> existingMonosForTarget = this.attachedMonos[target];

        TargetManagerMonoWithNameAndMethods preexistingMono = GetPreexistingMonoWithSameName(target, funcs, existingMonosForTarget);

        this.DestroyIfMonoWithSameNameAttached(preexistingMono, target, funcs, existingMonosForTarget);

        MonoBehaviour attachedMono = alreadyAttachedMono == null?funcs.Attach(target) : alreadyAttachedMono;

        TargetManagerMonoWithNameAndMethods newMonoData = new TargetManagerMonoWithNameAndMethods(funcs.TypeName, attachedMono);

        newMonoData.Methods = funcs.MethodInfos.Select(x => new TargetManagerMethodInfoWithName
        {
            MethodInfo = x.Value.MethodInfo,
            Parameters = x.Value.Parameters,
            Name       = x.Value.MethodInfo.Name,
        }).ToList();

        newMonoData.changesInMethodSignature = this.AreThereChangesInSignature(newMonoData, preexistingMono);

        /// Adding it to the collection for the given target.
        existingMonosForTarget.Add(newMonoData);

        /// Passing the
        if (alreadyAttachedMono == null)
        {
            ReferenceBuffer.Instance.Level.RegisterUpdatedMono(newMonoData);
        }

        return(newMonoData);
    }
示例#4
0
    /// <summary>
    /// Recives a type and extracts the type name,
    /// attach function - function that recives game object and returns monobehaviour,
    /// as well as all methods with paramater types <see cref=CompMethodsInAssemblyType>
    /// </summary>
    public static CompMethodsInAssemblyType GenerateAllMethodsFromMonoType(Type type)
    {
        var result = new CompMethodsInAssemblyType();

        ///Getting the attach method and converting it to Funk that attaches to GameObject and returns the MonoBehaviour
        var attachMethod = type.GetMethod("Attach");

        ///if no attachMethod throw
        if (attachMethod == null)
        {
            Debug.Log("There is not attach method on Type: " + type.Name);
            ///TODO: I also use this to get methods for compile time types that do not need attaching
            ///separate both use cases?
            //throw new Exception("There is not attach method on Type: " + type.Name);
        }
        else
        {
            ///Creating the attach function if we find Attach method in the type
            ///The attach method is used to attach the monobehaviour to GameObject and return the attached Instance
            var attachFunk = (Func <GameObject, MonoBehaviour>)
                             Delegate.CreateDelegate(typeof(Func <GameObject, MonoBehaviour>), attachMethod);
            result.Attach = attachFunk;
        }

        /// Setting the flags for method extraction
        var flags =
            BindingFlags.DeclaredOnly |
            BindingFlags.Public |
            BindingFlags.Instance;

        if (Settings.CompilationIncludePrivate)
        {
            flags = flags | BindingFlags.NonPublic;
        }

        if (Settings.CompilationIncludeStatic)
        {
            flags = flags | BindingFlags.Static;
        }
        ///...

        ///Non Attach methods are gathered here
        var otherMethods = type.GetMethods(flags)
                           .Where(x => x.Name != "Attach");

        ///Gathering the information for method parameters
        var methodInfos = new Dictionary <string, CompMethodInfoWIthParams>();

        foreach (var methodInfo in otherMethods)
        {
            var parameterInfos = methodInfo.GetParameters();
            var parameters     = new List <UiParameterWithType>();

            foreach (var parInfo in parameterInfos)
            {
                parameters.Add(new UiParameterWithType
                {
                    Name = parInfo.Name,
                    Type = parInfo.ParameterType
                });
            }

            methodInfos[methodInfo.Name] = new CompMethodInfoWIthParams
            {
                MethodInfo = methodInfo,
                Parameters = parameters.ToArray(),
            };
        }
        ///...

        result.MethodInfos = methodInfos;
        result.TypeName    = type.Name;

        return(result);
    }
示例#5
0
    private TargetManagerMonoWithNameAndMethods GetPreexistingMonoWithSameName(GameObject target, CompMethodsInAssemblyType funcs, List <TargetManagerMonoWithNameAndMethods> existingMonosForTarget)
    {
        /// Cheking if there is more than one script with given name already registered which should never happen.
        TargetManagerMonoWithNameAndMethods[] existingMonos = existingMonosForTarget.Where(x => x.Name == funcs.TypeName).ToArray();

        if (existingMonos.Length > 1)
        {
            Debug.Log($"There are more that 1 scripts with name {funcs.TypeName} already attached!");
            Debug.Break();
            return(null);
        }

        if (existingMonos.Length == 0)
        {
            return(null);
        }

        ///We have exactly one
        TargetManagerMonoWithNameAndMethods previousMono = existingMonos[0];

        return(previousMono);
    }
示例#6
0
 private void DestroyIfMonoWithSameNameAttached(TargetManagerMonoWithNameAndMethods preexistingMono, GameObject target, CompMethodsInAssemblyType funcs, List <TargetManagerMonoWithNameAndMethods> existingMonosForTarget)
 {
     /// If a mono with the same name is attched, we destroy the old one!
     if (preexistingMono != null)
     {
         Component monoToDestroy = target.GetComponent(preexistingMono.Mono.GetType());
         GameObject.Destroy(monoToDestroy);
         existingMonosForTarget.Remove(existingMonosForTarget.SingleOrDefault(x => x.Name == funcs.TypeName));
         Debug.Log("Old Script is overriden");
     }
 }