0
Answered

Viewing source code for generated Units

Guavaman 4 years ago updated by PET 4 years ago 11

Is there any way to view the source code for generated Units? I know the units are stored in the SQLite database as serialized data. I can view these, but this doesn't show me the C# code which would be useful for duplicating established patterns for handling certain types of Units. I've reflected at runtime to find all the running assemblies and types, but I cannot see any types for the generated Units. Are these actually ever compiled to code anywhere? If not, is there a collection of example Units anywhere?

Bolt Version:
Unity Version:
Platform(s):
Scripting Backend:
.NET Version (API Compatibility Level):
GOOD, I'M SATISFIED
Satisfaction mark by Guavaman 4 years ago
+2
Answered

Hi Guavaman! (Guavaman as in Rewired? :) )

Bolt does not generate C# code. It all runs from memory, using delegates and JIT emitted MSIL to reach speeds closer to scripting performance. This allows it to avoid any compilation and keep graphs fully editable and debuggable even while in play mode. (Bolt 2 will include optional / hybrid script generation).

At the moment, the documentation to create custom (non-reflected) units from C# is not written. However, if you're comfortable, you can decompile the source using for example ILSpy and see how units are defined in Bolt.Flow.dll. Many users have started doing this, and you can chat with them on the #scripting-api channel on Discord.

Hi Lazlo,

Thanks for the quick reply! Yes, I'm the author of Rewired. I've been working with Bolt for a few days and I have to say it is very cool! :).

I'm currently working on a DLL of Units for Rewired since it currently requires extra steps for the users to add Rewired's types to Bolt. I've made an API exporter that exports the entire API to a DLL so the process can be automated when I make an update to Rewired. It's mostly working now, but I've got a few little things I'm trying to figure out how the best way to handle and a few more types to deal with (events, methods that take delegates as arguments, generic methods, etc.).

>> It all runs from memory, using delegates and JIT emitted MSIL to reach speeds closer to scripting 
>> performance.

I thought it was something like that. That explains it. Very nice.

I have been using ILSpy to view the code in Bolt.Flow.dll and the other libraries, but I haven't found any complete Units for certain types in there, mostly base classes and some operations.

I'd like to see the structure for:

A constructor Unit:
(Do I get the constructed class in the "enter" Port callback, store it in a temp variable, and then return it in the ValueOutput callback? This is my current approach.)

An "expose class" type Unit

An editor with a custom "property drawer" for a type (if that's possible):
Basically I'm trying to make a Unit that takes a Rewired.Player object for the ValueInput which is straightforward enough, but I want to optionally allow the user to select a Player Id if they haven't hooked one up and have it just get the Player object inline from Rewired. This is a bit like the GameObject "property drawer" that allows a drag-and-drop or uses "Self" if nothing is set.

Another thing I see that you do in the Unit list is to grey out certain methods like "ReferenceEquals", etc. I'm guessing this is for inherited members. I'd like to do the same for consistency.

One additional misc and not very important thing I ran into was dealing with setting properties/fields on structs. Since a struct member cannot be set directly when the struct is returned by a method (ValueInput.GetValue) because the method returns a copy of the struct, the only way to set it would be to replace the struct reference itself inside ValueInput. However that does not seem possible since ValueInput has no way to set a value from code. To get around this, I had to use reflection to set the property on the struct, which is fine, but generally I would prefer avoiding reflection if at all possible.

Thanks for the great asset and for the help!

+1

I see! I would strongly recommend not creating custom units for constructors, fields, properties and methods. Bolt can access all of these automatically, and they are guaranteed to be updated, documented, optimized and stabilized by my general implementation code. Moreover, when Bolt 2 arrives and supports compilation to scripts, all the reflected units will be automatically supported. If you duplicate units in your integration, none of that will be possible.

Basically, the only kind of unit it really makes sense to create manually for an integration are events. I suggest having a look at the input events in Bolt.Flow.dll, for example OnMouseInput or OnKeyboardInput, which I think will suit the Rewired way of doing things (polling).

If your only concern is the "additional step" that users have to take to add the Rewired types, rest assured that this will become even faster in version 1.3. A new "bulk" addition button will be included in the unit options wizard, allowing to add all types from a namespace, for example Rewired's.

Interesting. Thanks for the explanation and the advice. It sounds like my API exporter is a bad idea then. :/

I was going off of information I found here:
https://support.ludiq.io/forums/5-bolt/topics/210-new-input-system-integration/

"...Rewired can currently be supported by adding its custom types to the type options in the Ludiq project settings, but it is cumbersome for inexperienced users."

It sounds like I need to experiment more to see exactly what is and isn't supported and how difficult it is for someone to enable support for Rewired the built-in way, then create a documentation page for using Rewired with Bolt. Rewired has a ton of classes, structs, enums, etc., so a bulk importer would be very, very useful.

The planned features for 1.3 and 2.0 sound like great additions.

>> Basically, the only kind of unit it really makes sense to create manually for an integration are events
>> I suggest having a look at the input events in Bolt.Flow.dll, for example OnMouseInput or
>> OnKeyboardInput, which I think will suit the Rewired way of doing things (polling).

Okay, I will take a look at those. Thanks!

Rewired supports both polling for input and getting input via delegate callbacks (basically, an add listener method with some options and a callback). It also has a few .Net events for things like when a controller is connected.

+3

Hey, you should have messaged me.  Your events already have been all added in (except brand new ones). I recently separated my extra code away from the events system, if you need anything, perhaps my source for the events already done, it's yours to use or peak at.  I'd absolutely love to start working on other things more if your able to better maintain this.  Email me or give me message on Discord/Twiiter with the same name and I'll help you out with whatever you need. 

+1

Ahh, I see you have updated the page here: https://support.ludiq.io/forums/5-bolt/topics/736-rewired-full-integration-native-units-events/#comment-3031

This wasn't up when I started working on the exporter several days ago. I was a little bit confused why you had started adding all the individual methods like GetButton, etc. Separating it into just the events is great.

I just tested and am able to use all the Rewired methods without using separate Units, although there are just too many classes, enums, etc. in Rewired for anyone to import the whole API manually.

Since I've already got my exporter written, I just need to adapt it to export the events instead of all the other classes and members and it should be good. I'll send you an email and continue this conversation there.

+1

Feel free to PM me on Discord if you need help guys! :)

+1

Well, Jason will be delighted you are doing this.

I hope so. I've seen what he's done and I like it, but the Rewired API is enormous and would take forever to manually create Units for everything. Having an exporter will make things much less painful and will eliminate the hassle of having to manually add new Units every time the API is updated.

+1

I love it when developers talk and try to integrate their products :D Yay developers!