Enumerator based coroutine yielding#281
Enumerator based coroutine yielding#281imerr wants to merge 2 commits intomoonsharp-devs:legacy/2.0from
Conversation
|
Oh, usecase The usecase for this would be nicer yielding in api functions while we wait for things to happen/be ready dialogue:say("Hello please give me your name")
local name = dialogue:input()
dialogue:clear()
dialogue:say("Hi ".. name)Currently |
| var enumerateYielder = script.DoString(@"return function (callable) | ||
| return function (...) | ||
| for y in callable(...) do | ||
| if coroutine.is_return_value(y) then | ||
| return coroutine.get_return_value(y) | ||
| else | ||
| coroutine.yield(y) | ||
| end | ||
| end | ||
| end | ||
| end", null, MethodInfo + "_yielder"); |
There was a problem hiding this comment.
Does it make sense to parse this lua code one for performance reasons? Could this lua function be pulled out and kept as a global function to be used when needed? I've done something similar in my own code, though all on the lua side without the C# interconnection work this PR does to make it nice and clean.
|
Yeah, in a final version you'd want to get rid of the lua code parsing and clean up the code all together
This is just a proof of concept, it also has issues of not yielding null values, since those aren't valid in lua "iterators"
I wouldn't recommend using this as is
… On 2 Sep 2020, at 22:04, Chris Smoak ***@***.***> wrote:
@cesmoak commented on this pull request.
In src/MoonSharp.Interpreter/Interop/StandardDescriptors/ReflectionMemberDescriptors/MethodMemberDescriptorCoroutine.cs:
> + var enumerateYielder = script.DoString(@"return function (callable)
+ return function (...)
+ for y in callable(...) do
+ if coroutine.is_return_value(y) then
+ return coroutine.get_return_value(y)
+ else
+ coroutine.yield(y)
+ end
+ end
+ end
+end", null, MethodInfo + "_yielder");
Does it make sense to parse this lua code one for performance reasons? Could this lua function be pulled out and kept as a global function to be used when needed? I've done something similar in my own code, though all on the lua side without the C# interconnection work this PR does to make it nice and clean.
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
|
Hey!
One of the features that's missing from moonsharp that'd make writing lua code a lot more elegant would be support for yielding a coroutine in clr functions
In unity this is usually done by just having an enumerator/generator function (not sure of the 100% correct terminology):
You can do something like this already, but you'll have to manually keep track of the iterator:
Conceptually it shouldn't be too hard to just add some "syntactical sugar" to implement something similar to the lua function above behind the scenes..
So I decided to give that a try and went digging
First I looked at the custom converters and figured it'd be as easy as checking for an attribute on the method info and just giving it a different DynValue with the "for loop yield" part, but turns out classes don't even use that and I had to go a lot deeper
This is obviously a giant hack at the moment and I'm mainly looking for feedback to get this to a decent state where merging it might be considered
The whole MethodMemberDescriptor part can be implemented better, but I didn't want to dig too deep into the scary parts for a proof of concept
I'm also curious what the best way would be to generate the iterator wrapper part? From what I gathered the yield does need to be run in bytecode currently