Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[Open Source] VFW (135): Drawers. Save System and full exposure

Discussion in 'Assets and Asset Store' started by vexe, Sep 2, 2014.

  1. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    Okay, this sounds great! I'll get the newest version!
     
  2. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    I got some errors here:

    Assets/Plugins/Vexe/Runtime/Types/Attributes/API/SerializationAttributes.cs(9,22): error CS0101: The namespace `Vexe.Runtime.Types' already contains a definition for `SerializeAttribute'
    Assets/Plugins/Vexe/Runtime/Types/Attributes/API/SerializationAttributes.cs(17,22): error CS0101: The namespace `Vexe.Runtime.Types' already contains a definition for `DontSerializeAttribute'
    Assets/Plugins/Vexe/Runtime/Types/Attributes/API/VisibilityAttributes.cs(10,22): error CS0101: The namespace `Vexe.Runtime.Types' already contains a definition for `ShowAttribute'
    Assets/Plugins/Vexe/Runtime/Types/Attributes/API/VisibilityAttributes.cs(18,22): error CS0101: The namespace `Vexe.Runtime.Types' already contains a definition for `HideAttribute'
    Assets/Plugins/Vexe/Runtime/Types/Categories/CategoryAttribute.cs(10,22): error CS0101: The namespace `Vexe.Runtime.Types' already contains a definition for `CategoryAttribute'
    Assets/Plugins/Vexe/Runtime/Types/Categories/DefineCategoriesAttribute.cs(9,22): error CS0101: The namespace `Vexe.Runtime.Types' already contains a definition for `DefineCategoriesAttribute'
    Assets/Plugins/Vexe/Runtime/Types/Categories/DefineCategoryAttribute.cs(9,22): error CS0101: The namespace `Vexe.Runtime.Types' already contains a definition for `DefineCategoryAttribute'
     
  3. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Looks like an import problem to me. I just downloaded the recent version into an empty project and it went fine. Maybe remove the previous version and try again?
     
  4. Xelnath

    Xelnath

    Joined:
    Jan 31, 2015
    Posts:
    402
    I deleted *all* of the Vexe folders (Both Plugin and Editor) in my project - grabbed the repository off git hub, then copied it into my project.

    Is that the wrong process?
     
  5. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    How did you 'grab' it? - cause I downloaded the zip, although I didn't get the errors you mentioned, but it seems that all scripts on all test gameObjects are not loaded. Could be due to the fact that I'm not tracking metafiles anymore? what if you did a git clone and pull every time there's a new update?
     
  6. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    It seems that for some reason that a .unitypackage is the only way to import Vfw without problems. Downloading/cloning the repository from github will yield errors. I'm not sure what's wrong, I set the asset serialization method to Force Text, added back the meta data files and set them to "Visible metadat" in the editor settings. I've added a .unitypackage in the repository as well. If anyone has any idea why this is happening please do let me know.

    Edit: made a thread about it here
     
    Last edited: Apr 29, 2015
  7. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    Hey vexe, I got these error today out of nowhere:
    Updated to 1.3.1, didn't help.

    I'm on Unity 5.0.1f1.

    Errors just popped up, worked 2 hours with the script, everything was fine and all of a sudden they occured.
     
  8. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @BTStone I've been seeing these errors randomly occurring since updating FullSerializer in Vfw 1.3 - I've asked the author about them but he himself wasn't sure. The problem seems to be related to the fact that things are being serialized/deserialized in a different order, so say you serialized a float, an interface and a list. somehow they get deserialized as interface, float then list. It yells at you "can't convert float to object" or whatever. But this really doesn't make sense, I use the same function to grab members when serializing/deserializing, the order should be the same. I've never had this issue in Vfw versions prior to 1.3 which tells me that the member fetching logic is working fine.

    Do the error occur constantly or randomly? If you can send a project that has a pattern I can follow to replicate the errors I can debug and see what's wrong. Otherwise you just have to wait till I finish Fast.Serializer and integrate it.
     
  9. Deleted User

    Deleted User

    Guest

    If I already use another serialization tool (Full Inspector), will this clash with it?
     
  10. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @supremegrandruler give it a try and let me know what happens. Both Vfw and FI use FullSerializer so there might be some naming conflicts. If I were you, I'd try to figure what exactly my requirements are and stick with one package. Using both could be an overkill, unless you have specific needs that are only met having both packages.
     
  11. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    Hello,

    I've made a drawer for an object. How can use that drawer for a list of that object?
    I alway have this error :

    Drawer `MyDrawer` can't seem to handle type `List<MyObject>`. Make sure you're not applying attributes on the wrong members

    Thanks,

    By the way, It would be great if upgrades of VFW were less painful... I know lately you made great changes, but I always get "Error deserializing member X (type Y) in Z" and It always take me some days to repair the glitches.
     
  12. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @sGlorz if that drawer is an ObjectDrawer<X>, it should be applied automatically in elements of List<X> or X[] *if* you mapped your drawer via the TypeDrawerMapper (see RegisterCustomDrawerExample.cs). If you have an attribute/composite drawer, in that case you have to add the [PerItem] attribute on your list to tell it to apply the drawer on each element (you still have to register it)

    I'm sorry to hear that. Yeah It's kind of painful at the moment, part of it is git and another are those FullSerializer errors. If you have a clear way to replicate that error please let me know. I'm working on my binary serializer when it's finished we should be able to integrate and and those errors will go away eventually.
     
    Last edited: May 2, 2015
  13. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    Of course PerItem !

    Thanks a lot and I'll wait for your binary serializer. BTW, why binary?
     
  14. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Well I was using FullSerializer for my saving system but wasn't happy with the performance. So I set out to write a serializer with performance in mind, binary is fastest since you don't have to parse anything you could just write immediately to stream, no temp buffers etc.
     
  15. sGlorz

    sGlorz

    Joined:
    Dec 4, 2013
    Posts:
    20
    That's smart thinking.
     
  16. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    That's the problem. It seems to happen absolutely randomly, that's why I cant send you a project to reproduce it, I'm afraid :/

    Another thing occured right now.

    Tried to Build&Run the Game (on our PS Vita DevKit):


    Weird thing, we used some scripts which are BetterBehaviours all the time and everything worked fine,
    Yesterday I created another one and tried to built it right now and the process breaks.
     
  17. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @BTStone are you sure you have the latest version? I'm pretty sure that's fixed here.
     
  18. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    As said before, it came out of nowhere. But I updated. Error is gone. For now :p
    (Thanks, though!)
     
  19. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    Hey @vexe

    I'm using the latest VFW with Unity 5 and I can't locate your EventSystem. Did you exclude it in an earlier Version?
     
  20. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @BTStone no I just refactored it. See this. You can now extend it (via inheritance or Extension methods) to add whatever extra features you like.
     
    BTStone likes this.
  21. BTStone

    BTStone

    Joined:
    Mar 10, 2012
    Posts:
    1,422
    Ah, yes, great! :D
     
  22. KhaledM

    KhaledM

    Joined:
    Sep 29, 2013
    Posts:
    41
    Hi,
    I am having these errors, 131-delegates.png
    I imported vfw131.unitypackage into new project
    Opened Delegates scene
    tried to assign variables to selected delegate 131-delegates 2.png

    Unity 5.0.1p3
     
  23. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @KhaledM this should fix it. For future bugs please raise an issue on github so others can see that it's fixed.
     
    KhaledM likes this.
  24. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Added the ability to draw things by Unity's layout. As you all know, I use a different layout system that's not compatible with Unity's. So things such as UnityEvents will be drawn inappropriately. One solution is to decompile and adapt Unity's UnityEventDrawer to VFW or find a way to use Unity's layout in Vfw's... The trick is to do Unity layout 'after' Vfw layout, so there will be no conflict. As a result of this members drawn by Unity's layout will always appear last.

    Here's an example showing a struct Index2D drawn by both Unity and VFW (which has a custom drawer mapped to it) - Notice how 'J' is not drawn by Unity cause it's readonly, but it is in our layout :)

     
  25. ThatGuyFromTheWeb

    ThatGuyFromTheWeb

    Joined:
    Jan 23, 2014
    Posts:
    29
    Hi guys.

    After struggling with Unity serialization for a while, I'm tempted to try this framework. I'm pretty new to Unity, so i may ask stupid stuff. If so - please forgive. :)

    Currently i'm working on a spare time project for module based procedural generation. Basically i'm ripping things from some other libraries, refactor them and put them in an assembly that is developed outside of unity. Currently i use something like this:
    • Some managers, threadpools and lots helper classes (and some structs)
    • An abstract base class Module : System.Object
    • Lots of classes derived from Module
      • Containing filter lists
      • Connections to other modules that work as consumers
      • Lots of module specific options
    All of this inherits from System.Object since it simply operates on float data and doesn't need any of unity's functionality - so my library doesn't contain any references to Unity assemblies.

    Apart from this, there is a separate unity project that (is going to be) a wrapper around that library to provide access to the most important unity types, convert textures to data arrays to calculate on and some editors for my custom classes.

    After reading through the thread and watching some of the tutorial vids, i have some questions.

    1. Can i serialize those custom types with VFW so they can live within the unity environment? I realize there are a lot of references to unity assemblies in the source, but maybe i can just go with [Serializable] for my objects and implement the necessary drawers and such in my wrapper library. Maybe if i wrap them in a Unity.object as container? I hope someone can point me in the general direction of how to approach this.

    2. I use auto-properties with https://github.com/Fody/Fody/wiki This is injecting backing fields, value testing and calls to PropertyChanged after compilation of the assembly. Mostly since i'm too lazy to type all that stuff. Is there an attribute to serialize them, event if they have side-effects?

    3. Could somebody confirm, that i can use the standard unity editor while using some of the features of VFW? To be honest, I'm not sure i want to introduce a new editor gui system ... especially if i'm still struggling with the buildt-in editors.

    Well ... Beertime!

    Lerzpftz
     
  26. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @Lerzpftz Hello there, and welcome to my humble little corner in the interwebs!

    What are those types? Vfw can serialize and view almost any type except for delegates (which are supported indirectly via uDelegate, uAction and uFunc). You don't need to mark your types with [Serializable] for them to be serialized by Vfw, in fact, it's recommended that you shouldn't! (read the FAQ regarding [Serialize] vs [SerializeField] and minimizing friction with Unity's serialization system) - You don't 'have' to write drawers for your types, unless there's a specific style/manner you want a certain type to be inspected as.

    I currently only support serializing auto-properties. If you had a property that has bodies for its get/set you could serialize its backing field instead. (Note: serialization is independent of exposure in Vfw. Meaning you could still expose something even if it wasn't serializable; via [Show])

    What are you looking for exactly? What features do you want to use from Vfw? All Vfw features are enabled for BetterBehaviour/BetterScriptableObject, not MonoBehaviour/ScriptableObject. The gui stuff is meant to make your life easier, you don't have to think they exist if you don't want to. They won't affect your development, but they're always there if you wanted to write editor scripts/windows.

    I suggest you give the fw a try and see if it suits your needs.

    Cheers!
     
  27. ThatGuyFromTheWeb

    ThatGuyFromTheWeb

    Joined:
    Jan 23, 2014
    Posts:
    29
    Good morning and thanks for the immediate answer.

    Well ... mostly pretty simple ones. The base class for the other types looks like this.

    Code (CSharp):
    1. using System;
    2. // ... no unity references here
    3. using APE.Base;
    4.  
    5. namespace APE.Modules {
    6.  
    7.     [ImplementPropertyChanged] // Base class, living in APE.dll
    8.     public abstract class ModuleBase : Object {
    9.      
    10.         public string ID { get; set; }               // Unique ID              
    11.  
    12.         public Tile DataTile { get; set; }         // Struct
    13.  
    14.         [DataReset]
    15.         public EOutputMode DataMode { get; set; }  // Enumeration
    16.        
    17.         [DataReset]
    18.         public Stack<Module> Inputs { get; set; }  
    19.  
    20.         [DataReset]
    21.         public List<FilterBase> Filter { get; set; }
    22.  
    23.         public SingleData Data { get; set; }  // I do NOT want to serialize this
    24.  
    25.         protected void OnPropertyChanged( string propertyName, object before, object after ) {  /* ... */ }  
    26.     }
    27. }
    28.  
    What i want to achieve is this:

    1. Keep unity references out of my APE.dll
    2. Use a unity project (or second assembly) to write editors for modulebase descendants
    3. Be able to save a bunch of modules, there settings and some other stuff in a prefab

    The problem with those properties is, that i define them like this ...
    Code (CSharp):
    1.  
    2. public string ID { get; set; }
    3.  
    ... and that fody framework injects additional code so it compiles something like this into my library
    Code (CSharp):
    1.  
    2.     string id;
    3.     public string ID
    4.     {
    5.         get { return id; }
    6.         set
    7.         {
    8.             if (value != id)
    9.             {
    10.                 string oldValue = id;
    11.                 id = value;
    12.                 OnPropertyChanged("ID, oldValue, id);
    13.            }
    14.        }
    15.    }
    This means i don't have a backing field to annotate in my code ... but yet it's still there in the compiled library.

    Hm ... i suppose you are right. It's probably more usefull to toy around with VFW a little and come back with more specific questions.

    Thanks anyway. :)
     
  28. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @Lerzpftz what if you had the ability to explicitly specify what members you want to serialize in a given type, regardless of what they're annotated with, or whether they're auto or non-auto properties? will that solve your problem?
     
  29. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    A small taste of what's commin' in 1.3.2:

    - You can now explicitly define what attributes to apply per item, key or value (*)
    - Implemented TextFieldDropDown (applied on the dictionary keys)
    - Dynamic display text formatting (applied on the dictionary, including its count in the label)

    * Still not perfect, what if there were two comments, I want to apply the first on the dictionary keys, the other on values. Right now that's not possible. This is good for most common use cases where, you want to draw your collection elements in a certain way, but still apply formatting attributes or whatever on the main collection.

     
  30. ThatGuyFromTheWeb

    ThatGuyFromTheWeb

    Joined:
    Jan 23, 2014
    Posts:
    29
    Probably it would be sufficient, if i have the possibility to force serialization of a property instead of the backing field, even if it may have side-effects. But since i didn't have much time to learn about VFW, i'm not very sure about that. I plan to use a simplified version of my class structures to test some things and learn a bit more over the weekend. I'll report back when i know a bit more. Thanks for your efforts!
     
  31. ThatGuyFromTheWeb

    ThatGuyFromTheWeb

    Joined:
    Jan 23, 2014
    Posts:
    29
    Well then.

    There is a small loophole allowing serialization of properties with side effects under certain circumstances.
    Code (CSharp):
    1.         public static bool IsAutoProperty(this PropertyInfo pinfo)
    2.         { ...
    3.             // then, check to make sure there's a complier generated backing field for the property
    4.             // the backing field would be something like: "<PropName>k__BackingField;
    5.             // and would have a [CompilerGenerated] attribute on it. but checking for the name is enough
    6.         ... }

    The backing fields injected in my library by Fody can be named like standard auto-prop backing fields, but are missing the [CompilerGenerated] attribute. So VFW regards them as serializable fields. This kind of works and gives me a way to decorate my properties instead of the backing fields with serialization attributes.

    Problem 2, controlling from another library, which properties should be serialized or shown can be solved by defining some new attributes like [ShowUnityEditor] or [SerializeThis] and adding them in VisibilityAttributes Default and SerializationAttributes DefaultAttributes. Those are readonly. Is there a way to register my custom attributes later to avoid breaking it, when i update VFW?

    Problem 3, using your editor attributes on the types of an external library can be solved by a thin wrapper class that re-publishes the properties i want to decorate.

    Also: Your framework looks pretty well structured and mature to me. Well done!
     
  32. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    1.3.2 is finally here!

    Massive release, tons of fixes/improvements and new features! - See the first page in this thread for details.

    You can now use your own serialization logic or explicitly specify what members to serialize (by name) (@Lerzpftz):








    More drawing power and control with the new PerItem/PerValue/PerKey letting you determine exactly what attributes to apply per element (see my previous post), you can inject attributes to members in situations where you don't want to annotate your member with any attributes but still want to draw it in a custom way, sequence/dictionary/popup drawing has been improved with new options, such as Filters and HorizontalPairs. See the example files mentioned at the end of the release notes.





    Saving (or should I say serializing lol) the best for last, Fast.Serializer is here (ALPHA BUILD) - again read the notes regarding it at the end of the first thread. Here's some benchmark/profiles (albeit not fair Binary VS JSON - Serializing a complex array of dictionaries (Item) - you can trigger serialization by resizing the inspector window) but just to give you an idea that using a faster serializer could improve even your editor workflow. Here's an older one. Eventually I'll add some FastSerializer VS protobuf-net benchmarks, but I'm too lazy and busy for that now. Feel free to do so yourself if you want, I don't expect to be faster cause this is an alpha, not fully optimized build.

    Hope you read the notes, I really hope you don't use FastSerializer for production, this is just a test drive. Mess around with it, test it, let me know how it goes! :)
     
    Last edited: May 25, 2015
  33. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    The idea of dynamically formatting things is still fresh, I haven't yet discovered if it's something of useful practical value, it 'sounds' cool but is it really useful? - I ended up with duplicate annotations and format methods, I don't particularly like this, I don't want to encourage clutter. https://github.com/vexe/VFW/issues/18 - Thinking outside the box for solutions...
     
    Last edited: May 25, 2015
  34. baj00

    baj00

    Joined:
    Nov 1, 2010
    Posts:
    25
    Hey Vexe, great update! PerItem Attributes are awesome!

    1. I think [RequiredFromThis(true)] is not creating the component. I've tried the inline example with the "combo" also. I don't know if it was working before.
    Code (csharp):
    1.  
    2.   // This is a very common combination to use
    3.      // We require the component (in this case from this gameObject),
    4.      // if it doesn't exist it gets added
    5.      // And then we inline it, and hide it from the gameObject
    6.      // NOTE: Both of these are composite attributes,
    7.      // meaning they have an order in which they are drawn
    8.      // RequiredFromThis should be drawn before Inline
    9.      // Otherwise Inline will try to hide a target that's not there yet!
    10.      // So we use an id of 0 to the first attribute, and 1 to the second.
    11.      // 0 comes before 1 :)
    12.      [RequiredFromThis(0, true), Inline(1, HideButton = true)]
    13.      public BoxCollider2D col;
    14.  
    15.  
    2. On the other hand, here is an idea: it would be killer if we could use the new PerItem and insert custom buttons which would trigger a custom method and carry the element index (or the object itself).
    I don't know how doable it is and maybe there is actually a way to achive this in this version.

    Code (csharp):
    1.  
    2.   [PerItem(Button("ShowIndex"))]
    3.    public List<GameObject> list;
    4.  
    5.    void ShowIndex(int index) {
    6.     list[index].DoSomething();
    7.    }
    8.  


     
    vexe likes this.
  35. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @peladovii Sure that's a nice idea I'll look in to it. About the InlineExample.cs, I seem to have forgotten to mark the class with [HasRequirements], fixed in next push. - See RequirementsExample.cs
     
  36. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Pushed 1.3.2p1, there was a serious mistake preventing members from appearing in System.Objects!

    Added two new attributes, Using and Button.

    Using solves the issue I raised here. Now we get to reuse annotations!



    And Button is a nice idea suggested by Mr @peladovii - Here you go:



    You don't get the index of an element, but instead the value of it, cause I figured that's more generic (works on any member, PerItem, PerKey, PerValue etc)
     
    Last edited: May 26, 2015
    baj00 likes this.
  37. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @Lerzpftz how did it go? - I noticed an issue that while true you can override logic/explicitly define what members to serialize in a behaviour, you can't do that on arbitrary System.Object, it would require me to let FullSerializer know of those members for that object, I'm not sure if I need to modify it or if there's already a way to do it. Should be easier to do in FastSerializer since it takes a predicates object (essentially like a serialization logic object). Let me know if the current setup works for you or not.
     
    Last edited: May 26, 2015
  38. ThatGuyFromTheWeb

    ThatGuyFromTheWeb

    Joined:
    Jan 23, 2014
    Posts:
    29
    Hi vexe! I've only had a couple of minutes to test things with the new version, since currently my (non-unity) day job is trying to eat me alive.

    If i understood what you wrote and what the code looks like, this is because all the serialization stuff is centered around your Better-Behaviour and Better-SO being implementers of IVFWObject - so they point to the serializer backend and the serialization logic. That would mean, in a nested object structure, i can easily control details of serialization on the root level(s), which currently are Better-SO objects - but not on deeper nesting levels, since FullSerializer takes control of how to serialize these nested subobjects? Is that what you were saying?

    If so it's basically the same problem as before - i'm trying to force VFW to do things with objects, that are decoupled from unity itself as much as possible, while VFW works mostly on MB and SO descendants. This and the fact, that VFW is heavily based on attribute decoration - while at the same time there is no easy way to late-decorate my external objects or use VFWs attributes in another dll (without referencing back to unity). The more i think about that, the more wrong the thing i'm trying to do here feels. Maybe i'm trying to abuse it a bit too much ... i'll have to think about it a bit more.
     
  39. baj00

    baj00

    Joined:
    Nov 1, 2010
    Posts:
    25
    @vexe, thanks for the (almost inmediatly) reply and addition!!

    This button is incredible useful for deleting components linked to that list element. (with the default "-" we can remove the element but the script would still exist).
    The only problem im facing is trying to use the button to attach a script on that position of the list. As the value is null, I cant find an index from it. thus I cant know where to work on.

    Sorry if that makes no sense (Not native english) and thanks again for this incredible Framework!
     
  40. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @peladovii If I understood you correctly, you want to click the button and have it attach a script to that element in the array? If so, then you can definitely do this in the current setup:

    Code (csharp):
    1.  
    2. [PerItem, Button("AttachScript", "Attach")]
    3. public GameObject[] array;
    4.  
    5. void AttachScript(GameObject go)
    6. {
    7.       if (go != null)
    8.           go.AddComponent<MyScript>();
    9. }
    10.  
    Clicking the button on the first array element, 'AttachScript' will get passed the value of that element, same for the rest. From the task your described to me, I don't understand why you need the index cause you're just clicking a button from the inspector, and stuff happens at the element you clicked on.

    Sorry if I misunderstood, If that setup really doesn't help, I could easily add a callback option to sequences giving you the index and value
     
  41. baj00

    baj00

    Joined:
    Nov 1, 2010
    Posts:
    25
    @vexe What im trying to achieve is:
    1. You click the button and the "AttachScript" method is called.
    2. The newly created script is referenced in the array position of the clicked button.(like if you drag and drop it on the slot).
    The problem is that the array element will be null so I can work (i think) without an index or an object.



    Anyway, thanks again for the response! And please dont waste your time with this, you already did a lot!!

    BTW: sequences and Inline are a really powerful combination! a real time saver! (im "inlining" list with inlined lists with inlined lists with almost 0 effort !)
     
  42. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @peladovii ~Done! - See the ButtonExample.cs again. I did not think it would be that easy to implement, I thought I'd have to add another Seq option, or come up with a new attribute, but we can actually still do it via Button. One feature I didn't think I would use in public is the fact that EditorMembers store information about whether or not they're elements inside a list/array/dictionary! - So what I did in ButtonDrawer, is check for 'member.ElementIndex' - if it's equal to -1, it means that this member is not a list/array/dictionary member (but just a regular member inside a behaviour or System.Object), otherwise it is, then I'd pass in that index as the second parameter. Note that it's optional to include the index in your callback, in that case you only get the element value.
     
    Last edited: May 27, 2015
    baj00 likes this.
  43. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    @Lerzpftz I'd like to help, but I can't if you don't give me anything concrete to work with :D - If you could post some sample code/project demonstrating what you want to do, I'd be able to give you more helpful answers.

    That's not accurate. On the editor side of things: if you look at the 'Using' attribute, you'll notice that it's dynamically pulling attributes from a remote location. This also means that you could actually 'simulate' annotations from an external source! This was a crazy idea I had before attempting 'Using', the idea is that you get a 'Type' browser (EditorWindow), from which you browse and expand a certain type viewing all the visible members in it, you'd get a text field above each member that you could use to add and annotate that member with attributes, then save those settings. I'd then see if you have any external attributes assigned for that type, if so I parse your settings and load the attributes you had defined. The end result would be that the actual member in the class doesn't have any physical attributes on it at compile time, but it is still drawn in custom ways because of the external attributes injected to it! I don't know if that made any sense. I didn't want to go with that path since I saw that 'Using' is enough for now.

    On the runtime/serialization side of things: You could write a custom logic that totally ignores attributes and does whatever custom checks and accept members under very special circumstances.

    But like I said before, FullSerializer doesn't take a 'logic' argument atm, (FastSerializer does) which means when dealing with System.Objects the logic defined in your BetterBehaviour is ignored. It can of course be implemented but I'd rather wait and see some concrete samples from you on what is it exactly that you're trying to do.
     
  44. ThatGuyFromTheWeb

    ThatGuyFromTheWeb

    Joined:
    Jan 23, 2014
    Posts:
    29
    That does make a lot of sense and sounds like the thing i searched for. I'll have a look at 'Using', as soon as i've time. Thanks!
     
  45. baj00

    baj00

    Joined:
    Nov 1, 2010
    Posts:
    25
    You are a Hero!! I'll test it at home and give you feedback. Thanks again!!!

    Its working great! Great addition, thanks again!
     
    Last edited: May 28, 2015
  46. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Added a small temp area to quickly add dictionary pairs (see):




    Also added a feature to reduce serialization calls, handy if you're using FullSerializer and inspecting a complex data structure. More details here.

    One portion I did not mean to include in that commit: [Display] values are now combined together, so if you had:

    Code (csharp):
    1.  
    2.   [AttributeContainer]
    3.   public static class SharedAttributes
    4.   {
    5.         public static Attribute[] ContainerDisplay = new Attribute[]
    6.         {
    7.               new DisplayAttribute(Dict.HorizontalPairs | Dict.Filter),
    8.         };
    9.   }
    10.  
    11.   [Using("ContainerDisplay"), Display(Dict.AddToLast | Dict.TempKey)]
    12.   public PropertyContainer Messages;
    13.  
    The Dict values will be combined - However if you specify any Formatting in [Display] on 'Messages' it will override the ones in ContainerDisplay
     
  47. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    I'm having (in-editor performance) problems regarding when to invoke serialization. Please see this issue I raised. I'd appreciate any help/ideas.
     
  48. ThatGuyFromTheWeb

    ThatGuyFromTheWeb

    Joined:
    Jan 23, 2014
    Posts:
    29
    Hi vexe,
    since i've got no account over there i'll answer here. I suppose it's pretty hard to go with option one and track the members yourself. Especially if you are talking about nested object structures. To track that information you would either have to a) compare data member by member or b) have the objects inform you about changes to their values.

    If you pick option a) and do it by comparison, it will get pretty slow anyway. Assuming, another serializer or deep-cloning mechanism is X times faster than FullSerializer, you've got the same problem again, as soon as you put X times more objects in a list. Maybe this mitigates the problem enough to be usable, but somehow i doubt that. Sadly you also can't go with option b) since arbitrary System.Object-Types have nothing in common that you could use to hook into, to get informed about changes.

    I suppose that is one of the reasons, that every single gui framework i worked with, demanded displayable and editable object, to inherit from certain base classes or implement special interfaces. (IBindingList or IPropertyChangedNotification anyone?)
     
  49. vexe

    vexe

    Joined:
    May 18, 2013
    Posts:
    644
    Hey @Lerzpftz thanks for the input.

    I have no problems tracking member changes if you make the change from the inspector, EditorMember has a convenient place to give a change callback if needed. But that's not enough, I have to track changes made from code. The only way I found is to do member-by-member data comparison like you said.

    I deal with large amounts of data and complex structures (array of dictionaries etc), serializing that with FullSerializer yield a non-usable inspector. I've been working around that by having a flag to turn off serialization temporarily. Another idea is to fallback to Unity's serialization by making OnBeforeSerialize/OnAfterDeserialize virtual, overriding them and leaving their body empty. So you can still use Vfw inspectors etc but not its custom serialization. That is just a pity.

    FastSerializer performs much better in comparison but it falls short in terms of debug-ability and flexibility. It's a pure pain in the back to debug IL generated code. You'd have to emit to a DLL, decompile it, copy-paste the code somewhere else and then bind to that code. Every time there's a but I'm like omg not again... That, combined with the fact that you must provide it the types it's working with in advanced, makes it practically not easy to use. Recently I worked on a feature where it would dynamically generate code for types so you don't have to give it the types in advance, it worked pretty well but when integrating it to Unity/Vfw it felt short, there was a deal-breaking issue that rendered the whole feature practically useless, made me feel pretty bad. So I decided to move on, learn from my experience (learned a ton from dealing with IL) and ditch FastSerializer and come up with a new one that combines speed with flexibility. In fact with my new design flexibility and debugability comes before speed. No more IL emission, still a binary serializer, this time I will use reflection to serialize objects, which means I could use my Fast.Reflection library (standalone only) and leave standard reflection to AOT platforms. I will do my best to kee things simple and straight forward but fast at the same time (no boxing/unboxing when serializing collections of value-types for ex) - Sometimes the wind goes against you, you just have to consume it, make you stronger instead of pushing you down! You can never write something truly good from first try, unless you're a true genius. But if you're persistent and give it more than one try you can make it happen! - Failure is just a prerequisite to success.

    Whether you think you can do it or not, you're right in both cases! Wish me luck!
     
    Last edited: Jun 4, 2015
  50. ThatGuyFromTheWeb

    ThatGuyFromTheWeb

    Joined:
    Jan 23, 2014
    Posts:
    29
    Hi @vexe, i'm at work, so i've only limited time. And i also ran into that problem, when i forgot to hide a member in a treestructure and that were float[] with a million values. :D

    If i understood you correctly
    * Member changes done through the editor are ok, since you get notified about them
    * Member changes by code are ok, for smaller amounts of data
    * Member changes on complex (and large) data structures are difficult since you have to clone them to track changes

    Is that correct so far?

    If so, you may consider to use a mixed approach and utilize .nets build-in interfaces:
    https://msdn.microsoft.com/en-us/li...alized.inotifycollectionchanged(v=vs.85).aspx
    https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.80).aspx

    If the member or member collection implements those interfaces, you could grab the change events from there and track changes that way. If it doesn't you could fallback and use the copy-and-compare method. This would allow users to work around restrictions when they actually hit them. At the same time you could try to move the threshold, when they hit them a bit away with faster serialization.

    Well: Good luck! ;-)