Example #1
0
 public HookUID(HOOK_ID evt, object reg, bool once = false)
 {
     uid       = LastID++;
     hook      = evt;
     registrar = reg;
     SingleUse = once;
 }
        /// <summary>
        /// Registers a hook that will fire only once and then be removed.
        /// </summary>
        /// <param name="evt">The event to hook.</param>
        /// <param name="cb">The callback to fire for this event.</param>
        /// <returns></returns>
        public static HookUID Once(HOOK_ID evt, Sisco_Hook_Delegate cb)
        {
            HookUID hook = register(evt, cb);

            hook.SingleUse = true;
            return(hook);
        }
        /// <summary>
        /// Unhook a previous hook you installed.
        /// </summary>
        /// <param name="registrar">Unique identifier used for grouping many hooks into a category for efficient removal later.</param>
        /// <param name="hook">Id of the event to unhook.</param>
        /// <param name="cb">The function to call.</param>
        /// <returns>(BOOL) Whether the event was successfully unhooked.</returns>
        public static bool unregister(object registrar, HOOK_ID hook, Sisco_Hook_Delegate cb)
        {
            if (registrar == null)
            {
                registrar = Get_Assembly_Registrar(Assembly.GetCallingAssembly());
            }
            HookUID UID = null;

            try
            {
                bool hk_success = false;
                if (SiscosHooks.Events.ContainsKey(hook))
                {
                    // Since all hooks are given a unique id and mapped to it in the events list now, we need to find this delegates id and remove it that way.
                    UID = SiscosHooks.Events[hook].FirstOrDefault(kv => (kv.Value == cb)).Key;
                    if (UID != null)
                    {
                        hk_success = SiscosHooks.Events[hook].Remove(UID);
                    }
                    if (!hk_success)
                    {
                        Log("Failed to remove hook from Events list: {0}", UID);
                        return(false);
                    }
                    else
                    {
                        // Update the number of registered instances for this event.
                        EventCounter[(int)hook] = SiscosHooks.Events[hook].Count;
                    }
                }

                bool tr_success = false;
                if (SiscosHooks.Tracker.ContainsKey(registrar))
                {
                    //add this hook to their list.
                    tr_success = SiscosHooks.Tracker[registrar].Remove(UID);
                    if (!tr_success)
                    {
                        Log("Failed to remove {0} from tracker.", UID);
                    }
                }

                return(tr_success && hk_success);
            }
            catch (Exception ex)
            {
                Log(ex);
            }

            return(false);
        }
Example #4
0
        // ugh, oh god is this awful.
        // Update: not so awful now that it caches the name...
        public override string ToString()
        {
            if (name != null) return name;

            Type type = typeof(HOOK_ID);
            FieldInfo[] fields = type.GetFields(BindingFlags.Static | BindingFlags.Public);

            foreach (FieldInfo field in fields)
            {
                if (field.FieldType != typeof(HOOK_ID)) continue;
                HOOK_ID hk = (HOOK_ID)field.GetValue(this);
                if (hk.id != id) continue;
                name = field.Name;
                break;
            }

            return name;
        }
        /// <summary>
        /// Unhook ALL of the previous hooks you installed with a specified registrar object.
        /// </summary>
        /// <param name="registrar">Unique identifier used for grouping many hooks into a category for efficient removal later.</param>
        /// <param name="hook">Id of the event to unhook. Leave this blank to remove ALL hooked events.</param>
        /// <returns>(BOOL) Whether the events was successfully unhooked.</returns>
        public static bool unregister_all(object registrar, HOOK_ID hook)
        {
            if (registrar == null)
            {
                registrar = Get_Assembly_Registrar(Assembly.GetCallingAssembly());
            }

            try
            {
                // create the callback list for this hook type if it doesn't exist.
                if (!SiscosHooks.Events.ContainsKey(hook))
                {
                    SiscosHooks.Events[hook] = new Dictionary <HookUID, Sisco_Hook_Delegate>();
                }

                // create this registrar's hooks list if it doesn't exist.
                List <HookUID> hooks_list;
                if (!SiscosHooks.Tracker.ContainsKey(registrar))
                {
                    return(false);
                }
                SiscosHooks.Tracker.TryGetValue(registrar, out hooks_list);

                var trash = new List <HookUID>(hooks_list);
                foreach (HookUID UID in trash)
                {
                    if (hook != HOOK_ID.NONE && UID.hook != hook)
                    {
                        continue;
                    }
                    bool b = unregister(UID);
                    if (!b)
                    {
                        Log("Failed to unregister {0}", UID);
                    }
                }
            }
            catch (Exception ex)
            {
                Log(ex.Message);
            }

            return(false);
        }
        //[Obsolete("Use register(Hook_ID, Callback, Registrar) or register(Hook_ID, Callback) instead!", true)]
        //public static bool register(object registrar, HOOK_ID hook, Sisco_Hook_Delegate cb) { return (register(hook, cb, null) != null); }

        /// <summary>
        /// Register your own function to be called whenever a specified event triggers.
        /// </summary>
        /// <param name="registrar">Identifier used for grouping many hooks into a category for efficient removal later.</param>
        /// <param name="hook">The event to hook.</param>
        /// <param name="cb">The function to call.</param>
        /// <returns>A <see cref="HookUID"/> for the newly registered hook or <c>null</c> upon failure.</returns>
        public static HookUID register(HOOK_ID hook, Sisco_Hook_Delegate cb, object registrar = null)
        {
            HookUID UID = null;

            if (registrar == null)
            {
                registrar = Get_Assembly_Registrar(Assembly.GetCallingAssembly());
            }
            if (hook == null)
            {
                Log("Attempted to register for NULL event!");
                return(null);
            }

            try
            {
                // create the callback list for this hook type if it doesn't exist.
                if (!SiscosHooks.Events.ContainsKey(hook))
                {
                    SiscosHooks.Events[hook] = new Dictionary <HookUID, Sisco_Hook_Delegate>();
                }
                UID = new HookUID(hook, registrar);
                SiscosHooks.Events[hook].Add(UID, cb);
                EventCounter[(int)hook] = SiscosHooks.Events[hook].Count;

                if (registrar != null)
                {
                    // create this registrar's hooks list if it doesn't exist.
                    if (!SiscosHooks.Tracker.ContainsKey(registrar))
                    {
                        return(null);
                    }
                    //add this hook to their list.
                    SiscosHooks.Tracker[registrar].Add(UID);
                }
                return(UID);
            }
            catch (Exception ex)
            {
                Log(ex);
            }

            return(null);
        }
        public static _hook_result call(HOOK_ID hook, object sender, ref object returnValue, object[] args)
        {
            try
            {
#if DEBUG
                SLog.Info("[SiscosHooks] {0}({1})", hook, Get_Arg_String(args));
#endif

                _hook_result result = new _hook_result(args);
                Dictionary <HookUID, Sisco_Hook_Delegate> cb_list;
                bool r = Events.TryGetValue((HOOK_ID)hook, out cb_list);
                if (r == false)
                {
                    return(new _hook_result());           //no abort
                }
                List <HookUID> TRASH = null;

                foreach (KeyValuePair <HookUID, Sisco_Hook_Delegate> kvp in cb_list)
                {
                    try
                    {
                        HookUID UID = kvp.Key;
                        UID.hasFired = true;

                        Sisco_Hook_Delegate act = kvp.Value;
                        if (act == null)
                        {
                            continue;
                        }
                        Sisco_Return ret = act(ref sender, ref result.args, ref returnValue);
                        // If this hook is a singleuse hook then we need to put it in our trashbin so we know to unregister it at the end of this function.
                        if (UID.SingleUse)
                        {
                            if (TRASH == null)
                            {
                                TRASH = new List <HookUID>();
                            }
                            TRASH.Add(UID);
                        }

                        if (ret != null)
                        {
                            if (ret.early_return)
                            {
                                result.abort = true;
                            }
                            if (ret.handled == true)
                            {
                                result.handled = true;
                                break;//cancel all other events
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Log(hook, ex.Message);
                        Log(ex.StackTrace);
                    }
                }

                if (TRASH != null)
                {
                    foreach (HookUID uid in TRASH)
                    {
                        try { unregister(uid); } catch (Exception ex) { Log(uid.hook, DebugHud.Format_Exception_Log(ex)); }
                    }
                }

                if (result == null)
                {
                    Log(hook, "Result became NULL somehow!");
                    return(new _hook_result());// we MUST return something other then NULL or the whole game can screw up!
                }

                if (args != null && args.Length != result.args.Length)
                {
                    Log(hook, "The size of Result.args does not match the number of arguments recieved from the function!");
                }

                return(result);
            }
            catch (Exception ex)
            {
                Log(hook, ex.Message);
                Log(ex.StackTrace);
                return(new _hook_result());
            }

            return(new _hook_result());//no abort
        }
 private static void Log(HOOK_ID hook, string format, params object[] args)
 {
     SLog.Info(String.Format("{0}<{1}> {2}", LOG_TAG, hook.ToString(), format), args);
 }
 /// <summary>
 /// Allows registering single-use hook with a void callback.
 /// </summary>
 /// <param name="evt"></param>
 /// <param name="cb"></param>
 /// <returns></returns>
 public static HookUID Once(HOOK_ID evt, Action cb)
 {
     return(Once(evt, (ref object sender, ref object[] args, ref object retVal) => { cb(); return null; }));
 }
Example #10
0
 /// <summary>
 /// Copies all of the relevant data from one instance into another.
 /// </summary>
 /// <param name="h"></param>
 public HookUID(HookUID h)
 {
     uid       = h.uid;
     hook      = h.hook;
     registrar = h.registrar;
 }
Example #11
0
 public bool Equals(HOOK_ID obj)
 {
     return (this.id == obj.id);
 }
Example #12
0
 private HOOK_ID(HOOK_ID i)
 {
     id = i.id;
     if (id >= _idx) _idx = (id + 1);
 }