3

I'm trying to create an object pooling framework. Every time a client requests an objects of some type, I return an object from a cache (a queue) or create a new object if there isn't any in the cache.

Now when the client code is done with the object, passes it to the framework to be cached again. But for this pattern to work, the object needs to be reset to initial state. every field has to be set to its default(T). Doing this manually for every class would be error prone and tedious work.

public void Reset(){
  x=0;
  y=0;
  ...
}

And of course performance is a primary concern. I'm looking for the most efficient solution.

EDIT:

As for motivation, this is a unity3d game project and garbage collection is a huge issue in unity. Every byte you save from garbage collection matters. So it is desirable to cache objects in contrast to the fastest, easiest, more reasonable way of just creating new objects.

morteza khosravi
  • 1,599
  • 1
  • 20
  • 36
  • 2
    Just wondering, what is the point of passing it back to the pool, if you are just going to reset its properties? Isn't it easier to drop the object, and create a new one, which is already in initial state? Perhaps you can clarify the purpose of the framework. – pkm Dec 26 '15 at 02:12
  • 1
    @pkm Yes that would be easier. This is a unity3d game project. And garbage collection is a huge issue in unity. Every byte you save from garbage collection matters. So it is desirable to cache objects in contrast to the fastest, easiest, more reasonable way of just creating new objects. – morteza khosravi Dec 26 '15 at 02:20
  • 1
    thank you for the clarification. – pkm Dec 26 '15 at 02:23
  • @pkm And thank you for asking. I edited the post to mention the reason. – morteza khosravi Dec 26 '15 at 02:30
  • 1
    Since default values can be of any type (and can be many). I guess there isn't really shortcut apart from the pattern that you can find in the default values itself. For instance, you can use Array.Clear for variables which you can set in an array and having initial values of zero. But if all array elements are of different values (or rather: patternless), then you should set it one by one. It boils down to whether there is pattern in the default values of the variables or not. – Ian Dec 26 '15 at 02:46

2 Answers2

1

The idea would be to have your pool to require all pooled object to be IPoolObject. This interface would contain Reset method.

Then any time a call to pop out an item is made, this Reset method is called from the pool framework. If nothing shout be done, the method remains empty.

This way, any given pool object gets to reset in its own way and can also reset other components attached to the object.

You can find my version of pool object there: https://github.com/fafase/unity-utilities/blob/master/Scripts/ObjectPool.cs

Everts
  • 10,408
  • 2
  • 34
  • 45
  • Actually that's exactly what I'm doing. The main concern here is the body of Reset method. Doing manually is one way to go as we both are doing. It would be interesting if there is a way to automate this method because the possiblity of making mistake is high in manually resetting every field. – morteza khosravi Dec 26 '15 at 13:20
  • 1
    MonoBehaviour components have a Reset method. You cannot just reset a class without calling a method or creating a new instance. – Everts Dec 26 '15 at 15:50
  • The objects are not MonoBehaviours. Just plain old objects. – morteza khosravi Dec 26 '15 at 15:52
  • Then it is Reset method with implementation or new object. One reason is inheritance. A sub class cannot see a private field from base class, so it cannot reset it as it does not know about it. It would have to call for base.Reset() within its own Reset. – Everts Dec 26 '15 at 16:05
0

What about something like this?

public void Reset()
{
    foreach(FieldInfo fieldInfo in this.GetType().GetFields())
        fieldInfo.SetValue(default(fieldInfo.GetType());
}
AustinWBryan
  • 3,249
  • 3
  • 24
  • 42
  • 1
    Definitely... You do have an extra parenthesis at `GetType()));` You put three closing parens, but there should only be two. – AustinWBryan Dec 26 '15 at 05:05
  • It's not that. There are 3 opening and 3 closing parenthesis – morteza khosravi Dec 26 '15 at 07:32
  • If your concern is memory, this is not going to help. Each Getxxx method creates a new object containing info. And SetValue uses some boxing for value type which adds up. – Everts Dec 26 '15 at 16:07
  • This answer is wrong in two ways. Firstly, it cannot compile because `default()` expects a type expression, not an instance of `System.Type`. For example, `default(int)` compiles, but not `default(typeof(int))` or `default(1.GetType())`. Secondly, `fieldInfo.GetType()` returns the type of the `FieldInfo` instance, which will always be `System.Reflection.RuntimeFieldInfo`. To get the field type, one must use `fieldInfo.FieldType`. – Mr Anderson Nov 21 '17 at 08:29