void appendIn(utList <tListEntry> list, System.Object target, bool paused)
        {
            tListEntry listEntry = new tListEntry();

            listEntry.target            = target;
            listEntry.paused            = paused;
            listEntry.markedForDeletion = false;
            MethodInfo method = target.GetType().GetMethod(updateSelector);

            listEntry.impMethod = (TICK_IMP)Delegate.CreateDelegate(typeof(TICK_IMP), target, method);

            utNode <tListEntry> listElement = new utNode <tListEntry> ();

            listElement.next = listElement.prev = null;
            listElement.obj  = listEntry;

            list.DL_APPEND(listElement);

            tHashUpdateEntry hashElement = new tHashUpdateEntry();

            hashElement.target = target;
            hashElement.list   = list;
            hashElement.entry  = listElement;
            hashForUpdates.HASH_ADD_INT(target.GetHashCode(), hashElement);
        }
        void priorityIn(utList <tListEntry> list, System.Object target, int priority, bool paused)
        {
            tListEntry listEntry = new tListEntry();

            listEntry.target   = target;
            listEntry.priority = priority;
            listEntry.paused   = paused;
            MethodInfo method = target.GetType().GetMethod(updateSelector);

            listEntry.impMethod         = (TICK_IMP)Delegate.CreateDelegate(typeof(TICK_IMP), target, method);
            listEntry.markedForDeletion = false;

            utNode <tListEntry> listElement = new utNode <tListEntry> ();

            listElement.next = listElement.prev = null;
            listElement.obj  = listEntry;


            if (list.head == null)
            {
                list.DL_APPEND(listElement);
            }
            else
            {
                bool added = false;
                for (utNode <tListEntry> elem = list.head; elem != null; elem = elem.next)
                {
                    if (priority < elem.obj.priority)
                    {
                        if (elem == list.head)
                        {
                            list.DL_PREPEND(listElement);
                        }
                        else
                        {
                            listElement.next = elem;
                            listElement.prev = elem.prev;

                            elem.prev.next = listElement;
                            elem.prev      = listElement;
                        }
                        added = true;
                        break;
                    }
                }

                if (!added)
                {
                    list.DL_APPEND(listElement);
                }
            }
            tHashUpdateEntry hashElement = new tHashUpdateEntry();

            hashElement.target = target;
            hashElement.list   = list;
            hashElement.entry  = listElement;
            hashForUpdates.HASH_ADD_INT(target.GetHashCode(), hashElement);
        }
        public CCEventDispatcher()
        {
            // events enabled by default
            _dispatchEvents = true;

            // delegates
            _keyboardDelegates = new utList <tListEntry>();
            _mouseDelegates    = new utList <tListEntry>();

            _delegatesToBeAdded   = new utList <tListAddedEntry>();
            _delegatesToBeRemoved = new utList <tListDeletedEntry>();

            _locked = false;
        }
        public bool removeDelegate <T>(System.Object aDelegate, utList <T> list) where T : tDelegateEntry
        {
            utNode <T> entry;

            for ((entry) = (list.head); (entry != null); (entry) = entry.next)
            {
                if (entry.obj.aDelegate == aDelegate)
                {
                    list.DL_DELETE(entry);
                    return(true);
                }
            }
            return(false);
        }
        public void removeAllDelegatesFromList(utList <tListEntry> list)
        {
            NSUtils.Assert(!_locked, "BUG. Open a ticket. Can't call this function when processing events.");

            lock (this) {
                utNode <tListEntry> entry, tmp;
                entry = list.head;
                while (entry != null)
                {
                    tmp = entry.next;
                    list.DL_DELETE(entry);
                    entry = tmp;
                    tmp   = null;
                }
            }
        }
        public void addLaterDelegate(System.Object aDelegate, int priority, utList <tListEntry> list)
        {
            // XXX: Since, "remove" is "executed" after "add", it is not needed to check if the delegate was already added for removal.
            // In fact, if you remove it now, it could be a bug, since EventDispatcher doesn't support updated priority.
            // And the only way to update the priority is by deleting, re-adding the delegate with a new priority
            tListAddedEntry listEntry = new tListAddedEntry();

            listEntry.aDelegate     = aDelegate;
            listEntry.priority      = priority;
            listEntry.listToBeAdded = list;

            utNode <tListAddedEntry> listElement = new utNode <tListAddedEntry> ();

            listElement.next = listElement.prev = null;
            listElement.obj  = listEntry;

            _delegatesToBeAdded.DL_APPEND(listElement);
        }
        public void removeLaterDelegate(System.Object aDelegate, utList <tListEntry> list)
        {
            // Only add it if it was not already added for deletion
            if (!removeDelegate <tListAddedEntry>(aDelegate, _delegatesToBeAdded))
            {
                tListDeletedEntry listEntry = new tListDeletedEntry();

                listEntry.aDelegate       = aDelegate;
                listEntry.listToBeDeleted = list;


                utNode <tListDeletedEntry> listElement = new utNode <tListDeletedEntry> ();
                listElement.next = listElement.prev = null;
                listElement.obj  = listEntry;

                _delegatesToBeRemoved.DL_APPEND(listElement);
            }
        }
        public void addDelegate(System.Object aDelegate, int priority, utList <tListEntry> list)
        {
            tListEntry listEntry = new tListEntry();

            listEntry.aDelegate = aDelegate;
            listEntry.priority  = priority;

            utNode <tListEntry> listElement = new utNode <tListEntry> ();

            listElement.next = listElement.prev = null;
            listElement.obj  = listEntry;

            bool added = false;

            for (utNode <tListEntry> elem = list.head; elem != null; elem = elem.next)
            {
                if (priority < elem.obj.priority)
                {
                    if (elem == list.head)
                    {
                        list.DL_PREPEND(listElement);
                    }
                    else
                    {
                        listElement.next = elem;
                        listElement.prev = elem.prev;

                        elem.prev.next = listElement;
                        elem.prev      = listElement;
                    }

                    added = true;
                    break;
                }
            }

            // Not added? priority has the higher value. Append it.
            if (!added)
            {
                list.DL_APPEND(listElement);
            }
        }
        //----------init------------
        public CCScheduler()
        {
            _timeScale = 1.0f;

            // used to trigger CCTimer#update
            updateSelector = "update";
//			impMethod = (TICK_IMP) [CCTimerTargetSelector instanceMethodForSelector:updateSelector];

            // updates with priority
            updates0       = new utList <tListEntry>();
            updatesNeg     = new utList <tListEntry>();
            updatesPos     = new utList <tListEntry>();
            hashForUpdates = new UTHash <int, tHashUpdateEntry>();

            // selectors with interval
            currentTarget         = null;
            currentTargetSalvaged = false;
            hashForTimers         = new UTHash <int, tHashTimerEntry>();
            updateHashLocked      = false;
            _paused = false;
        }