ModernUO icon indicating copy to clipboard operation
ModernUO copied to clipboard

Replace resources w/ generic commodity object

Open kamronbatman opened this issue 5 years ago • 4 comments

  • [ ] Replace all commodities (gold, logs, ore, ingots, etc) with a single Commodity type.
  • [ ] Use an object pool to rent/return these objects.
  • [ ] Replace Type arguments with Enum arguments for these commodities.
  • [ ] Replace Activator.CreateInstance with Rent from the object pool.
  • [ ] Replace getting items in a container by type with the enum.
  • [ ] Update hold and stack methods to be aware of the new commodity object.
  • [ ] Create a migration script from the old RunUO types.
  • [ ] Update mobiles/loot to allocate gold and other items through the object pool.

kamronbatman avatar Aug 12 '19 20:08 kamronbatman

Here could be an example implementation I made:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;

namespace Server.Collections
{
 public static class ObjectPool
 {
   private static class Pool<T>
   {
     private static readonly ConcurrentBag<T> pool = new ConcurrentBag<T>();

     /// <summary>
     /// Methode puts an object in pool. Furthermore methode does not need
     /// a lock to be thread safe because of internal handling of ConcurrentBag.
     /// </summary>
     /// <param name="obj"></param>
     public static void PutObject(T obj)
     {
       pool.Add(obj);
     }

     /// <summary>
     /// Methode gets an object of pool. Furthermore methode does not need
     /// a lock to be thread safe because of internal handling of ConcurrentBag.
     /// </summary>
     /// <param name="obj"></param>
     /// <returns></returns>
     public static bool TryGetObject(out T obj)
     {
       if (pool.Count > 0)
       {
         pool.TryTake(out obj);
         return true;

       }
       obj = default(T);
       return false;
     }
   }

   /// <summary>
   /// 
   /// </summary>
   /// <typeparam name="T"></typeparam>
   /// <param name="obj"></param>
   public static void Put<T>(T obj)
   {
     Pool<T>.PutObject(obj);
   }

   /// <summary>
   /// 
   /// </summary>
   /// <typeparam name="T"></typeparam>
   /// <param name="obj"></param>
   /// <returns></returns>
   private static bool TryGet<T>(out T obj)
   {
     return Pool<T>.TryGetObject(out obj);
   }

   /// <summary>
   /// 
   /// </summary>
   /// <typeparam name="T"></typeparam>
   /// <returns></returns>
   public static T GetOrDefault<T>()
   {
     T ret;
     TryGet(out ret);
     return ret;
   }

   /// <summary>
   /// 
   /// </summary>
   /// <typeparam name="T"></typeparam>
   /// <returns></returns>
   public static T Get<T>() where T : new()
   {
     T ret;
     return TryGet(out ret) ? ret : new T();
   }
 }
}

3HMonkey avatar Jan 07 '20 20:01 3HMonkey

That is a start but I think concurrent bags may not have great performance. We need to benchmark this.

Also needs to prefill it. Next needs a max size so you don't end up with 100mill objects lol. Next needs to be resizable (eventually will use ingame commands or a Gump to tweak)

kamronbatman avatar Jan 08 '20 16:01 kamronbatman

That is a start but I think concurrent bags may not have great performance. We need to benchmark this.

Also needs to prefill it. Next needs a max size so you don't end up with 100mill objects lol. Next needs to be resizable (eventually will use ingame commands or a Gump to tweak)

I already have an alternative approach using Stack instead of ConcurrentBags. Just chosen it because the bags are thread safe. I wrote it yesterday in about 5 minutes and were just playing around with it. I gonna check this out later on.

3HMonkey avatar Jan 08 '20 18:01 3HMonkey

Try using a ConcurrentQueue, it doesn't use locks, is thread-safe and it should be just as good as a Stack.

kamronbatman avatar Jan 09 '20 08:01 kamronbatman

Skip doing this for now. We can look into it if it becomes a bottle neck.

kamronbatman avatar Nov 26 '23 18:11 kamronbatman