Beispiel #1
0
        public static bool Perform(object obj, GameObjectReference references, bool perform, bool reportFound)
        {
            bool immediate = false;

            bool report = true;

            if ((obj is RabbitHoleDoorJig) || (obj is PhoneCell))
            {
                report = ErrorTrap.kDebugging;
            }
            else if (obj is Lot)
            {
                immediate = true;
            }
            else if (obj is Sim)
            {
                Sim sim = obj as Sim;
                if (sim.LotHome != null)
                {
                    if ((RecoverMissingSimTask.FindPlaceholderForSim(sim.SimDescription) == null) &&
                        ((sim.SimDescription.CreatedSim == null) || (sim.SimDescription.CreatedSim == sim)))
                    {
                        immediate = true;
                    }
                }
            }

            ReferenceLog log = null;

            if (!perform)
            {
                log = new ReferenceLog("Potential Object Found: " + ErrorTrap.GetQualifiedName(obj), report, immediate);
            }

            if (references == null)
            {
                return(false);
            }

            if ((!ErrorTrap.kDebugging) && (references.Count == 0))
            {
                return(false);
            }

            if (perform)
            {
                log = new ReferenceLog("Destroyed Object Found: " + ErrorTrap.GetQualifiedName(obj), report, immediate);
            }

            log.Perform     = perform;
            log.ReportFound = reportFound;

            if ((!ErrorTrap.kDebugging) && (obj is Lot))
            {
                return(false);
            }

            List <DereferenceStack> stack = new List <DereferenceStack>();

            foreach (KeyValuePair <object, FieldInfo> pair in references)
            {
                stack.Add(new DereferenceStack(pair, new Dictionary <ReferenceWrapper, bool>(), new List <ReferenceWrapper>(), new ReferenceWrapper(obj), false, false));
            }

            bool firstFailure = true;

            int index = 0;

            while (index < stack.Count)
            {
                DereferenceStack stackObject = stack[index];
                index++;

                ReferenceWrapper key = new ReferenceWrapper(stackObject.mReference.Key);

                bool recursion = false;
                if (stackObject.ContainsKey(key))
                {
                    recursion = true;
                }

                if ((perform) && (stackObject.Count == 1))
                {
                    log.DumpLog(false);
                }

                object reference = stackObject.mReference.Key;

                string depth = "";

                for (int i = 0; i < stackObject.Count - 1; i++)
                {
                    depth += " ";
                }

                bool reset = false, success = false;

                foreach (IDereference dereference in DereferenceManager.Dereferences)
                {
                    DereferenceResult result = dereference.IPerform(stackObject.mReference, stackObject.mList, perform);
                    if (result == DereferenceResult.Found)
                    {
                        log.SetFoundSuccess();
                    }

                    if (result != DereferenceResult.Failure)
                    {
                        stackObject.mResult = depth + "  Reference " + result + ": " + reference.GetType() + " " + stackObject.mReference.Value + " (Using " + dereference.GetType().Name + ")";
                        if (report)
                        {
                            log.Add(stackObject.mResult);
                        }

                        success = true;

                        bool checkSuccess = false;

                        if (reference is GameObject)
                        {
                            stackObject.mEndFound = true;

                            checkSuccess = true;

                            GameObject gameObject = reference as GameObject;
                            if ((perform) && (!HasBeenDestroyed(gameObject)) && (!reset) && (!(reference is Sim)))
                            {
                                try
                                {
                                    reset = true;
                                    gameObject.SetObjectToReset();

                                    log.Add(depth + "  Object Reset: " + ErrorTrap.GetQualifiedName(gameObject));
                                }
                                catch //(Exception e)
                                {
                                    //Common.DebugException(gameObject, e);
                                }
                            }
                        }
                        else
                        {
                            switch (result)
                            {
                            case DereferenceResult.End:
                            case DereferenceResult.Found:
                                stackObject.mEndFound = true;
                                break;

                            case DereferenceResult.Continue:
                            case DereferenceResult.ContinueIfReferenced:
                            case DereferenceResult.Ignore:
                                bool unimportant = stackObject.mUnimportant;

                                switch (result)
                                {
                                case DereferenceResult.ContinueIfReferenced:
                                    unimportant = true;
                                    break;

                                case DereferenceResult.Ignore:
                                    unimportant = true;

                                    stackObject.mEndFound = true;
                                    break;
                                }

                                if (!recursion)
                                {
                                    if (ShouldRecurse(reference))
                                    {
                                        bool referenced = false;

                                        GameObjectReference gameReference = ObjectLookup.GetReference(key);
                                        if (gameReference != null)
                                        {
                                            foreach (KeyValuePair <object, FieldInfo> pair in gameReference)
                                            {
                                                stack.Insert(index, new DereferenceStack(pair, stackObject, key, unimportant, stackObject.mEndFound));
                                                referenced = true;
                                            }
                                        }

                                        if (!referenced)
                                        {
                                            checkSuccess = true;

                                            if (result == DereferenceResult.ContinueIfReferenced)
                                            {
                                                stackObject.mEndFound = true;
                                            }
                                        }
                                        else
                                        {
                                            stackObject.mBridge = true;
                                        }
                                    }
                                    else
                                    {
                                        stackObject.mEndFound = true;
                                    }
                                }
                                else if (result == DereferenceResult.ContinueIfReferenced)
                                {
                                    stackObject.mEndFound = true;
                                }
                                else
                                {
                                    checkSuccess = true;
                                }
                                break;

                            default:
                                if (recursion)
                                {
                                    checkSuccess = true;
                                }
                                break;
                            }
                        }

                        if (checkSuccess)
                        {
                            switch (result)
                            {
                            case DereferenceResult.End:
                            case DereferenceResult.Ignore:
                                break;

                            default:
                                if (recursion)
                                {
                                    if (!object.ReferenceEquals(key.mObject, obj))
                                    {
                                        log.SetFailure("A");
                                    }
                                    else
                                    {
                                        stackObject.mEndFound = true;
                                    }
                                }
                                else
                                {
                                    log.SetFailure("B");
                                }
                                break;
                            }
                        }
                    }
                }

                if (!success)
                {
                    bool mustRecurse = false;

                    string priority = "UNHANDLED";
                    if (recursion)
                    {
                        priority = "Recursion";

                        if (object.ReferenceEquals(key.mObject, obj))
                        {
                            stackObject.mEndFound = true;
                        }
                        else
                        {
                            stackObject.mBridge = true;
                        }
                    }
                    else if ((reference.GetType().IsArray) ||
                             (reference is IList) ||
                             (reference is IDictionary) ||
                             (reference is ICollection) ||
                             (reference.GetType().Name.Contains("ForgetfulList")) ||
                             (reference.GetType().Name.Contains("PairedListDictionary")))
                    {
                        priority    = "Bridge";
                        mustRecurse = true;

                        stackObject.mBridge = true;
                    }
                    else if (stackObject.mUnimportant)
                    {
                        priority = "Ancillary";

                        if ((reference is GameObject) || (reference is SimDescription))
                        {
                            recursion = true;
                        }
                        else
                        {
                            mustRecurse = true;
                        }

                        stackObject.mBridge = true;
                    }
                    else
                    {
                        log.ImportantFound();

                        log.SetFailure("C");
                    }

                    stackObject.mResult = depth + "  " + priority + " Reference: " + ErrorTrap.GetQualifiedName(reference) + " " + stackObject.mReference.Value;

                    if (report)
                    {
                        log.Add(stackObject.mResult);
                    }

                    bool referenced = false;
                    if (!recursion)
                    {
                        if (ShouldRecurse(reference))
                        {
                            GameObjectReference gameReference = ObjectLookup.GetReference(key);
                            if (gameReference != null)
                            {
                                foreach (KeyValuePair <object, FieldInfo> pair in gameReference)
                                {
                                    stack.Insert(index, new DereferenceStack(pair, stackObject, key, stackObject.mUnimportant, stackObject.mEndFound));
                                    referenced = true;
                                }
                            }
                        }
                        else
                        {
                            stackObject.mEndFound = true;

                            mustRecurse = false;
                        }
                    }

                    if (!referenced)
                    {
                        if (mustRecurse)
                        {
                            log.SetFailure("D");
                        }
                    }
                    else
                    {
                        stackObject.mBridge = true;
                    }
                }

                if ((!perform) && (!log.IsTotalSuccess) && (firstFailure))
                {
                    firstFailure = false;
                    log.Add(depth + "  RETAINED " + log.FailureReason);
                }
            }

            bool first = true;

            foreach (DereferenceStack stackObject in stack)
            {
                if (stackObject.mEndFound)
                {
                    continue;
                }

                if (stackObject.mBridge)
                {
                    continue;
                }

                log.EndMissing();

                if (first)
                {
                    first = false;

                    log.Add("  OPEN ENDED");
                }

                log.Add(stackObject.mResult);
            }

            log.DumpLog(false);

            Logger.ForceRecord();

            return(log.IsTotalSuccess);
        }
Beispiel #2
0
 public DereferenceStack(KeyValuePair <object, FieldInfo> reference, DereferenceStack frame, ReferenceWrapper obj, bool unimportant, bool endFound)
     : this(reference, frame.mLookup, frame.mList, obj, unimportant, endFound)
 {
 }