Skip to main content

News

Topic: Sphere v2 API discussion (Read 34828 times) previous topic - next topic

0 Members and 4 Guests are viewing this topic.
  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Sphere v2 API discussion
Reply #15
I guess it would still be possible to build an "assert" module as part of the standard library though:
http://wiki.commonjs.org/wiki/Unit_Testing/1.0#Assert

One thing that could be done is to do the actual comparison in JS and just expand the SSJ API a bit to accommodate.  For example that "show error and break" could be its own function, `ssj.alert()` which would be a no-op if not debugging.

One thing I don't like about having an external library for assertions is that it increases the barrier to entry.  We want to encourage people to pepper their code with assertions, but if you have to import the assert module in every file that uses them, people might just get lazy and avoid doing it.  So it's not clear what the best setup would be.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere v2 API discussion
Reply #16

One thing I don't like about having an external library for assertions is that it increases the barrier to entry.  We want to encourage people to pepper their code with assertions, but if you have to import the assert module in every file that uses them, people might just get lazy and avoid doing it.  So it's not clear what the best setup would be.


I'm not sure. I for one never pepper my code with assertions. If there are to be assertions, in unit tests they go, not in actual game logic. But I guess it depends if you like a more contractual style or not. I'd rather add an assertion library to my unit test scripts instead.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Sphere v2 API discussion
Reply #17
Unit tests test external behavior ("external" relative to the component under test, I mean).  It's my understanding that the other purpose of assertions is to verify assumptions made internally.  For example, maybe you wrote some code assuming a pointer (which is not visible to unit tests) won't be null because, if the program is well-behaved, it can't possibly be null.  If there's _any_ chance at all that the pointer could become null due to a regression elsewhere, you assert for it so that in a debug build, you crash as early as possible.  Duktape is actually loaded with asserts like that.

That's the reason why, in most programming languages, asserts don't actually do anything at all in a release build (they are usually compiled out completely) - because the scenarios they are designed for would cause massive slowdowns if they all had to be tested in the final build.  Unfortunately, JS doesn't have any kind of conditional compilation so we lose that benefit. :(

In any case, I'll implement that CommonJS Assert interface because it seems common enough in the wild (Firefox supports it, e.g.) that Sphere should have it too.
  • Last Edit: August 14, 2016, 12:45:25 am by Lord English
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Radnen
  • [*][*][*][*][*]
  • Senior Staff
  • Wise Warrior
Re: Sphere v2 API discussion
Reply #18
Yeah I was thinking it would be slower to pepper code with assertions, but then again in languages like C they can be compiled away.
If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

Sphere-sfml here
Sphere Studio editor here

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Sphere v2 API discussion
Reply #19
The one benefit to the Node.js-style assert library is that it actually throws an exception if the condition isn't met, making it useful for actual validation at runtime.  ssj.assert() never throws - it displays a warning and optionally triggers a breakpoint if the debugger is in use, but otherwise has no effect on the program flow.  Both have their uses.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Sphere v2 API discussion
Reply #20
I'm wondering what the best setup for font.getTextWidth/Height() is.  Right now I implemented it like Sphere 1.x, with the separate methods, but I wonder if it would be better to have a unified .getTextSize() function.  The function would look like

Code: [Select]
Font#getTextSize(text[, width]);


If you don't pass a width, it would just measures the width and height with no wrapping.  Otherwise it wraps the text to the specified with and gets the height of the block.

Do you think this would be more or less intuitive than the separate width/height functions we have now?
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Sphere v2 API discussion
Reply #21
I'm still trying to hash out a good setup for the Sphere v2 joystick API.  Right now I'm thinking of a system where you access connected devices like this:

Code: (javascript) [Select]

var joy = Joystick.devices[0];
if (joy.isPressed(0)) { /* talk */ }
if (joy.getPosition(0) > 0.5) { /* move right */ }
// etc.


The important part is that:

  • Joystick.devices is an array, or at least acts like one, so that you can use Link to iterate on it.  For example to find Xbox controllers you'd use Link to narrow down to only joysticks with 6 axes (2 axes per stick + 2 analog triggers) and <however many buttons are on an Xbox controller, I haven't bothered to count :P)

  • Accessing a nonexistent device would return a null joystick that always returns neutral values (0.0 for axes, false for buttons), and never throws an error.  The same goes for accessing nonexistent buttons or axes on a valid device.  This greatly simplifies joystick input code as it doesn't have to ensure the device exists before polling it.



Of course, this is just an idea and I'm free to change my mind.  Any opinions/ideas/suggestions?
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Sphere v2 API discussion
Reply #22
I've decided to drop the typed I/O (readInt, readString, writeFloat, etc.) from FileStream in favor of implementing the W3C Encoding API:
https://www.w3.org/TR/encoding/

This is more flexible, since it allows processing text in any ArrayBuffer or view, thus it'll be possible to encode and decode text from other sources such as sockets, which is currently not possible.  The API is a bit more convoluted than I'd prefer, but better to implement a standard rather than rolling my own API if there's no functionality to be gained by doing so.

Note: Reading ints and floats from an ArrayBuffer is already possible by using a DataView.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Sphere v2 API discussion
Reply #23
Here's the new way to do update and render scripts coming in minisphere 4.3:
Code: (javascript) [Select]

var updateJob = system.recur(Dispatch.Update, myUpdateFunc);
var renderJob = system.recur(Dispatch.Render, myRenderFunc);


You can call recur() as many times as you want and it will keep adding jobs.  To remove them, just do:
Code: (javascript) [Select]

updateJob.cancel();
renderJob.cancel();


Best of all, this works engine-wide, not only in the map engine.
  • Last Edit: October 31, 2016, 01:21:12 pm by Lord English
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • DaVince
  • [*][*][*][*][*]
  • Administrator
  • Used Sphere for, like, half my life
Re: Sphere v2 API discussion
Reply #24
That's kinda difficult to understand from a glance, but perhaps that's because I haven't given the new API stuff much of a look at all. (The original links 404 now too.) What is this about jobs again? How do you recur multiple things into a renderscript? Do you create separate jobs for that, like so?

Code: (javascript) [Select]

var updateJob = system.recur(Dispatch.Update, myUpdateFunc);
var anotherUpdateJob = system.recur(Dispatch.Update, someOtherFunc);

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Sphere v2 API discussion
Reply #25
Right, multiple calls to recur() create new hooks each time.  To cancel the job later, you just do updateJob.cancel().

It's like how setTimeout() works in web JS.  The first parameter to recur() specifies when to run it (update, render, on next tick) and the second is the function to call.
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Sphere v2 API discussion
Reply #26
By the way the reason I called them "jobs" is because that's how the ECMAScript specification refers to asynchronous calls performed from the event loop, as opposed to immediately.

Async is a bit hard to fully wrap your head around until you get used to it, so the confusion is understandable.
  • Last Edit: October 31, 2016, 03:54:48 pm by Lord English
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Sphere v2 API discussion
Reply #27
@DaVince: Would it make the API any easier to understand if I namespaced things a bit?  For example, something like this:

Code: (javascript) [Select]

// these are all recurring:
Dispatch.onUpdate(updateThis);
Dispatch.onUpdate(updateThat);
Dispatch.onUpdate(updateSomeOtherThing);
Dispatch.onFlip(renderItAll);

// these are one-shots:
Dispatch.now(resolvePromise);
Dispatch.later(2.0, getEatenBy.bind(you, maggie));


At first I thought "onUpdate" etc. might imply the job only runs once on the next update, but since Node.js uses a similar scheme (object.on('event', fn)), I don't think that should be a source of confusion in reality.

edit: Just saw you said the documentation links were 404s now.  I probably did some housekeeping and renamed them or something, here's the up-to-date links:
https://github.com/fatcerberus/minisphere/blob/master/docs/sphere2-api.txt
https://github.com/fatcerberus/minisphere/blob/master/docs/miniRT-api.txt

edit 2: Also added Dispatch.later() for making delayed calls.
  • Last Edit: November 02, 2016, 03:29:11 am by Lord English
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub

  • DaVince
  • [*][*][*][*][*]
  • Administrator
  • Used Sphere for, like, half my life
Re: Sphere v2 API discussion
Reply #28
Hmm, that would certainly make them less obtuse to people reading the code. The code you posted before introduced a bunch of new things that would confuse people who are just getting into it. What you suggested does look a lot clearer!

I assume that even with the namespacing suggestion, you could still do job = Dispatch.onUpdate(updateThis); job.cancel()? :)

  • Fat Cerberus
  • [*][*][*][*][*]
  • Global Moderator
  • Sphere Developer
Re: Sphere v2 API discussion
Reply #29
Yep, that would still work. :D
neoSphere 5.9.2 - neoSphere engine - Cell compiler - SSj debugger
forum thread | on GitHub