playMaker

Author Topic: Storing non mono-behaviour object as variables[SOLVED]  (Read 8635 times)

mochatony

  • Playmaker Newbie
  • *
  • Posts: 7
Storing non mono-behaviour object as variables[SOLVED]
« on: November 08, 2013, 11:27:14 AM »
Hello

I am new to playmaker and learning how it fits to my workflow. One thing I found out is if I create any class that is not extend from monobehaviour, it will not be found at variables->object->object type.

I am not sure I got it right, but I do need to store custom class from myself or 3rd party plugins. Anyway to resolve this?
« Last Edit: November 18, 2013, 01:47:57 AM by jeanfabre »

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Storing non mono-behaviour object as variables
« Reply #1 on: November 11, 2013, 01:30:43 AM »
Hi,

 Indeed, there is this restriction in place. I am not sure myself how to work around this. When I need to store references to my own classes, I use a hashtable, then I am free to do what I want and only need to store a string reference.

 the other solution, depending on your context is to have you classes with a monobehavior equivalent in the scene, then you work with the monobehavior that in turn compose your class.

 Could you give more info about the context and usage of your custom classes?

bye,

 Jean

mochatony

  • Playmaker Newbie
  • *
  • Posts: 7
Re: Storing non mono-behaviour object as variables
« Reply #2 on: November 12, 2013, 10:01:47 AM »
Hello Jean

Thanks for reply. For my case I am trying to build custom playmaker action for hotween that batch the tweens.

Example:

      Tweener tween;
      Sequence seq = new Sequence(new SequenceParms());
      tween = HOTween.To(selectPanel, fadeInterval, new TweenParms().Prop("alpha",0f));
      seq.Insert(0,tween);
      tween = HOTween.To( homePanel, fadeInterval, new TweenParms().Prop("alpha",1f));
      seq.Insert(0,tween);         
      seq.Play();      


What I tends to do is store each of the tween in variables and then batch it in custom playmaker action (by selecting the variables into the array).

What do you suggest to overcome this limitation, could give some example on how do you do it with hashtable?

Thank you


jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Storing non mono-behaviour object as variables
« Reply #3 on: November 14, 2013, 02:06:49 AM »
Hi,

 For this I would explore the following:

-- make use of a static singleton class that manage the references to these tweens you create, and you keep a unique id reference for each one of them.

 so, when one action creates one of these tween, you store it in a hashtable against a unique id you generate for the occasion, then in your final action that compose all these tweens in into a sequence, you use these unique id references, so in PlayMaker you only saves these references.

You should also create management actions such as deleting a reference for a tween in this static class so that you don't start crowding the memory, so everytime you have finished with a sequence, you simply cleanup all references to the tweens you don't need anymore.

 Are you ok with creating such static classes? I would not go for a hashtable sotred for each sequence, I think it will create more problems than it will solve.

bye,

 Jean

mochatony

  • Playmaker Newbie
  • *
  • Posts: 7
Re: Storing non mono-behaviour object as variables
« Reply #4 on: November 17, 2013, 07:27:10 AM »
Hello JeanFabre

Thanks for reply. At the end I go with static class that keep reference of the sequence. Seems working.  :)

Thank you so much

tinjaw

  • Playmaker Newbie
  • *
  • Posts: 24
Re: Storing non mono-behaviour object as variables[SOLVED]
« Reply #5 on: February 14, 2014, 01:09:08 PM »
I am new to C# scripting and I do not know how to create a static class that keeps references.

I have a vendor asset that I wish to make custom Playmaker actions for. However, the vendor's class is derived from object. I don't know how to get it to work as something that is compatible with FsmObject.

Can somebody provide an example of what is talked about in this thread?

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Storing non mono-behaviour object as variables[SOLVED]
« Reply #6 on: February 17, 2014, 10:57:02 AM »
Hi,

 you will need to create a bridge class, one that is compatible with FsmObject, and in that class, you can then reference your vendor static class.

but this sounds ood to me, are you sure you want static classes? what kind of content is there in your vendor class?

Bye,

 Jean

tinjaw

  • Playmaker Newbie
  • *
  • Posts: 24
Re: Storing non mono-behaviour object as variables[SOLVED]
« Reply #7 on: February 18, 2014, 08:43:00 AM »
Hi,

 you will need to create a bridge class, one that is compatible with FsmObject, and in that class, you can then reference your vendor static class.

but this sounds ood to me, are you sure you want static classes? what kind of content is there in your vendor class?

Bye,

 Jean

Jean,
I only said that because that is what was mentioned in this thread.

Simply put, I have no idea how to wrap an object as to be usable in Playmaker. I was hoping somebody could provide a simple example. I don't mind RTFM, but I don't know where to look to find out how to do this.

Any help getting me started would be appreciated.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Storing non mono-behaviour object as variables[SOLVED]
« Reply #8 on: February 24, 2014, 06:22:55 AM »
Hi,

 Can you share the class you want to wrap? or at least the kind of data and why it needs to be static? saving data in variables doesn't make sense if in the end you access a static variable... this is true even outside PlayMaker.


bye,

 Jean

tinjaw

  • Playmaker Newbie
  • *
  • Posts: 24
Re: Storing non mono-behaviour object as variables[SOLVED]
« Reply #9 on: February 26, 2014, 11:22:41 AM »
Hi,

 Can you share the class you want to wrap? or at least the kind of data and why it needs to be static? saving data in variables doesn't make sense if in the end you access a static variable... this is true even outside PlayMaker.


bye,

 Jean

I'm sorry. I seem to have confused you. I don't need a static class.

What I am trying to do is wrap a third-party asset, OOForm. The class I am trying to use with PlayMaker descends from object, not MonoBehavior. Thus I cannot use fsmObject. I believe that I need to make a wrapper class for OOFormArray that I can then use as a fsmObject.

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Storing non mono-behaviour object as variables[SOLVED]
« Reply #10 on: February 26, 2014, 01:43:35 PM »
Hi,

 I am currently going for a totally different approach lately ( I face your problem daily :) )

 I am maintain an hashtable or dictionnary using a string as key and OOFormArray as value, this list is static public so accessible from anywhere ( and even persist when editing actually), then my fsm only need to reference a string to get to a OOFormArray, which is much easier to manage AND prevent garbage collection issues, Unity object do not obey to garbage collection like regular class do so I always fear using them and end up with memory warnings and crashes on mobile.

So here , simply create a singleton or actually in an action a static public hashtable to store, retrieve a delete entries for OOFormArray based on string keys.

 Hope that make sense. I am working on XmlMaker and I am using this to save xml nodes as you query create and edit xml nodes, it works very well so far. If you are interested, I'll send you the current package for you to see how it's implemented.


bye,

 Jean

Guavaman

  • Playmaker Newbie
  • *
  • Posts: 38
Re: Storing non mono-behaviour object as variables[SOLVED]
« Reply #11 on: September 26, 2016, 03:51:35 AM »
Have there been any changes to this limitation since this post? I can't find any recent information on this issue.

I've tried both object wrappers that inherit from SerializedObject and creating an object manager that stores a Dictionary of unique ids. Both of these approaches have the same issue -- created objects or object references must be freed manually by the user or memory will expand indefinitely. The wrapper approach using SerializedObject requires that Object.Destroy be called when the object is no longer required. The object manager approach requires that the object be deleted from the object manager when it's no longer required. Both approaches require that the user learn about and perform data management which is not something I think most users would be happy about.

For my purposes, the objects in question do not need to be serialized and do not need to persist between sessions. They are runtime-only objects which must be able to be passed around to various parts of an API. They need to be able to be stored in an array, the array iterated, and various tasks performed with the objects.

I haven't been able to come up with an acceptable general-purpose solution to this issue. Does anyone have any ideas?

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Storing non mono-behaviour object as variables[SOLVED]
« Reply #12 on: September 26, 2016, 03:56:56 AM »
Hi,

 I would propose a solution that I use for XmlMaker ( same problem).

create a wrapper that reference your object using a string as key, just like variables do, only that you write the system yourself.

so create a static hashtable or dictionnary of string-> object and get set your object using the string key as a reference.

Does that make sense?

else, like ngui and Unity UI do, you could create a GameObject per Object and a monobehaviour on that object would be the interface for you to communicate with it.

Bye,

 Jean

Guavaman

  • Playmaker Newbie
  • *
  • Posts: 38
Re: Storing non mono-behaviour object as variables[SOLVED]
« Reply #13 on: September 26, 2016, 02:23:48 PM »
Hi,

 I would propose a solution that I use for XmlMaker ( same problem).

create a wrapper that reference your object using a string as key, just like variables do, only that you write the system yourself.

so create a static hashtable or dictionnary of string-> object and get set your object using the string key as a reference.

Does that make sense?

else, like ngui and Unity UI do, you could create a GameObject per Object and a monobehaviour on that object would be the interface for you to communicate with it.

Bye,

 Jean

Hi,

Thanks for the reply!

I've tried both the wrapper approach using a class that inherits from ScriptableObject as a wrapper, and the hashtable/dictionary approach using a Dictionary<int, object> that stores the object reference and assigns it a unique id. The problem with both approaches is that these objects stay in memory forever unless the user manually clears them with some Action such as FreeObject.

If the user stores an arbitrary object in a variable, and this variable is a hash or unique id that points to the static object manager, the static object manager retains an object reference to this object forever unless manually removed when the user is finished with the object. It cannot be automatically deleted as far as I know because the user may store this value in a variable anywhere in any or multiple FSMs.

The wrapper approach has the same problem -- the SerializedObject must be cleared with Object.Destroy when the user is finished or it will stay in memory forever.

The more objects that are added to the object manager or the more SerializedObject wrappers that are created, the more memory will expand.

How do you deal with this issue with your XML Maker Actions? Do you ever clear the objects in your static class or are the left there forever?

The only way I can think of to automatically garbage collect these objects would be to check all variables in all globals and all FSMs and check if a unique id is no longer in use before clearing it. (I imagine that process could take a very long time.) Edit: No, this approach won't work either because there would be no way to detect which variables are just normal ints and which ones are ints that store a uid key for an object.

For non-serialized objects, it seems it would be easy enough to have an FSMNonSerializedObject or another field in FSMVar to handle System.Object classes that do not need to be serialized along with an associated VariableType.NonSerializedObject to store these references during runtime as a System.Object field. These obviously could not be set by drag-and-drop and would not be editable by the user in the editor (that's not their purpose), but it could be used by Actions for runtime APIs that need the ability to pass around arbitrary objects to an API.
« Last Edit: September 26, 2016, 10:45:35 PM by Guavaman »

jeanfabre

  • Administrator
  • Hero Member
  • *****
  • Posts: 15500
  • Official Playmaker Support
Re: Storing non mono-behaviour object as variables[SOLVED]
« Reply #14 on: October 14, 2016, 02:55:51 AM »
Hi,

 I think you are confusing the developer and the end user.

 In your logic you'll have to cleanup a reference you estimate not being used anymore, and that will have no penalty like garbagecollection for Unity Objects. So this is fine, it's like many many aspects of pur c# coding, if you are not clean, it will get dirty... :) delegates not being removed, leaked objects here and there, etc etc.

I have extensive experience with XmMaker on many projects which uses soft references in static hashtables, and the problem of memory isn't there, it's not like you are going to constantly create new references, once you have your set, you'll reuse them, assign new values to it.

I never had the following for example: dozens of ennemies each requiring an xml ref that would lead to a memoryleak as they get destroyed if reference not cleaned up. But still within XmlMaker it would not make sense, your enemies could be categorized and you would only need common xml data for certain ennemies, I don't see any use case for a unique xml set of data per instance, it doesn't make sense, xml is for easily storing data for configuration and saving data. not for live data as the game is being executed.

in the best scenario for the worse case mentionned above, you should simply have a "ClearReference" and "ClearAllReferences" action for your framework and use that when the user is going back to the main menu, or switching from one level to another, if indeed you create uniquely references per level ( which I doubt is making sense, you should try organize your data so that it's generic for all levels).

Bye,

 Jean