• Content count

  • Joined

  • Last visited

Community Reputation

468 Neutral

About gjl

  • Rank

Personal Information

  • Interests
  1. Looks good, thanks! Is there any impact for the JIT?
  2. Remote visual debugger: asdbg

    This looks very nice! Have you made any progress since the original post?
  3. Still working on it anyway :-)
  4. An update has been posted. Generators will now pass the exception to the parent execution context. https://github.com/bluecataudio/angelscript-addons/tree/master/cpp Also, if you are using the JIT by BlindMind studios, you will need the following fix to avoid crashes when destroying a generator while its execution is not finished: https://github.com/BlindMindStudios/AngelScript-JIT-Compiler/pull/24
  5. By the way here some more information about the javascript generators (no need to be a javascript guru): https://blog.ragnarson.com/2016/12/15/javascript-generators.html I am actually thinking about using the generators as is, and why not build specific coroutine class on top of is, in plain angelscript - the only difference would be naming, and the fact that you can launch a coroutine until the first yield, without having to call next() once. Also, with coroutines, you may actually want to include a scheduler (dispatcher) to manage them, whereas a generator is just a lower level building block for coroutines, managing pause/resume and basic communication (managing return value and argument). You could also imagine that the scheduler class would actually be used as a coroutine factory, and you may want to assign them a priority etc.
  6. I definitely agree about naming. But I hate reinventing the wheel, so I copied this one from Javascript. The main difference with javascript though is that the iterator interface has a special meaning in the language, so you can do foreach() etc. on generators, which is something that does not exist (yet) in Angelscript. On the other hand, generators are more generic than coroutines: it CAN be used as coroutines (especially this angelscript version, that does not have the limitations of javascript generators, such as calling yield in a subroutine). but it can also be used to create generic iterators that return a value for each step (see my example above). So I am still thinking about it - any input is welcome! Even if I don't like the generator keyword, the fact that it already exists in a widespread language tells me not to reinvent another one. Also, when used as an iterator, resume() does not mean much (whereas next() in the context of a coroutine actually means nextStep()).
  7. I have finally added support for values exchange between the caller and callee using any objects: https://github.com/bluecataudio/angelscript-addons/tree/master/cpp It was not as simple as I expected, because the VM is actually suspended AFTER the call to yield returns. But it now works. No change for the simple example (yield() and next() without arguments are still supported). But you can also write the following: void main() { int count = 10; generator@ genB = createGenerator(threadB, dictionary = { {"count", 3}, {"str", " B"} }); generator@ genC = createGenerator(threadC, dictionary = { {"count", 5}, {"str", " C"} }); while (count-- > 0) { print("A :" + count + "\n"); if (genB.next(count)) { int bValue = -1; if (genB.value.retrieve(bValue)) { print("A knows B is:" + bValue + "\n"); } } if (genC.next(count)) { int cValue = -1; if (genC.value.retrieve(cValue)) { print("A knows C is:" + cValue + "\n"); } } } } void threadB(dictionary @args) { int count = int(args["count"]); string str = string(args["str"]); any valueSent; while (count-- > 0) { int fromA = -1; if (valueSent.retrieve(fromA)!=false) print(str + ":" + count + " - knows A is:" + fromA + "\n"); else print(str + ":" + count + " - knows A is: ?\n"); valueSent = yield(count); } } void threadC(dictionary @args) { int count = int(args["count"]); string str = string(args["str"]); while (count-- > 0) { print(str + ":" + count + "\n"); yield(count); } } Which outputs: A :9 B:2 - knows A is: ? A knows B is:2 C:4 A knows C is:4 A :8 B:1 - knows A is:8 A knows B is:1 C:3 A knows C is:3 A :7 B:0 - knows A is:7 A knows B is:0 C:2 A knows C is:2 A :6 C:1 A knows C is:1 A :5 C:0 A knows C is:0 A :4 A :3 A :2 A :1 A :0
  8. It is actually extremely simple for the moment. I reused the basic ideas from the coroutines add-on (actually copy/pasted the code). You can find the current prototype here (generator.h and cpp): https://github.com/bluecataudio/angelscript-addons/tree/master/cpp I am however still wondering a couple of things, so it may change quite a bit in the future. Your opinion is of course welcome! ?- should I keep the javascript-like syntax with next(), or do something like LUA (resume() etc.)? Since coroutines already exist with the coroutines add-on, I have chosen the javascript style so far, and it is also a bit more modern. ?- Does it make sense to implement values passing (back and forth) with yield like in javascript? Like: // dummy example - incomplete syntax coroutineProc(dictionary@ args) { string x=""; while(count-->0) { print("Hello" + x); x=yield(count); } } main() { // create generator generator@ gen=... gen.next("A"); print(gen.value); gen.next("B"); print(gen.value); } To make the above example work nicely, the generator object should be a template with two arguments, so it makes the whole thing a bit heavier, since template functions are not supported in Angelcript. An alternative would be to use dictionaries or "any" for argument types, but it is not very elegant - I like Angelscript's type safety :-).
  9. Hi, I am working on adding coroutines support to an application framework that uses anglescript for GUI scripting. After giving a try to the coroutines sample, it appears that it won't work for me: you cannot manage the coroutines from the scripts, as it requires that the ExecuteScripts function to be called on a regular basis by the C++ side. Also, calling yield from a context that was not registered will just do nothing. So I have written a very simple Generator add-on that makes it easier to manage coroutines from scripts, using a very similar syntax as Javascript (not returning values for the moment). So the coroutines sample script becomes: void main() { int count = 10; generator@ genB=createGenerator(thread, dictionary = {{"count", 3}, {"str", " B"}}); while( count-- > 0 ) { print("A :" + count + "\n"); genB.next(); } } void thread(dictionary @args) { int count = int(args["count"]); string str = string(args["str"]); while( count-- > 0 ) { print(str + ":" + count + "\n"); yield(); } } The major difference is that "main()" can be called from any context (no need to add it to the context manager). And you can then write your own coroutines dispatcher in Angelscript, like this very simplistic one: class GenDispatcher { bool next() { if(nextIndex>=tasks.length) nextIndex=0; if (nextIndex<tasks.length) { bool hasNext=tasks[nextIndex].next(); if (!hasNext) { tasks.removeAt(nextIndex); } else nextIndex++; } return tasks.length!=0; } array<generator@> tasks; private int nextIndex=0; }; Would you be interested in incorporating this add-on into angelscript? It is already running and I'll share the code anyways, but if it has to become an official add-on, some extra work is required, such as implementing the generic calling convention (which I do not use for the moment).
  10. AngelScript execution speed?

    With the JIT enabled, Angelscript is really fast. I could even use it for real time audio processing. It is about 5 times slower than C++ in such a scenario, which is impressive for a scripting language! As for LUA, if you can cope with its syntax, just use it. But IMHO Angelscript is much easier to use - be it for its syntax, C++ integration or features.
  11. Thanks for taking the time to check it out. My initial idea was indeed to preprocess with the callback before actually processing the files, but I tried to stick to the same semantics as the include callback, that actually replaces the include logic. So it's the same here, it replaces the processing logic, so that you can do your preprocessing and then call the compiler from there (it can be interesting to proceed this way if pre-processing is rather complex and requires that you compile several sections for example).
  12. Hi,   I needed a way to preprocess the script files before they were compiled, but after all the preprocessor directives have been processed in the script builder addon, so I have added a new callback for this purpose. I also use it to produce a preprocessed version of a script that includes many files, so that it can be distributed as a single file.   Please find attached the patch for the add-on. It would be nice if the modification could be added to the main branch - if you find it useful. I have tried to keep the semantics of the include callback (that replaces the default behavior). 
  13. Woops, my bad: I forgot that native objects are not wrapped but used "as is" by the script engine... You can forget this feature request! :-)   Anyway, I ended up writing wrapper classes, which is not a big deal (not so many methods to wrap)