This topic is for discussion of the Arduboy2 Development Library
ArduboyToo is the better name of course!
Is there some reason we didn’t just push the work on a branch and do a beta release to let people try it out with same library path?
The pause in development is really to create a stable API and let people get their bearing before shifting the API. Getting patches pushed at the
v1-1 tag would be neat, or just releasing the fixes in as
v1-2. That’s kind of been the most important thing.
It would be great to look at some of the other drawing APIs out there before putting work into defining a new set of functions for our own library. Projects like pico8 and u8glib or u8g2 can offer some clean paths to creating a fairly ubiquitous API across a few platforms. That’s really the goal for a next major version like
2.0.0. The current
v1-2, the build on the
master branch, currently breaks
v1-1's API, so it wasn’t something we could push as a release. I made some general attempts at bringing that issue up to push it, but I haven’t had a chance to fork and work a solution.
It would be cool to do a
v1-2 release that is the fixes for the library, but does not change the way people are currently programming.
Any number of branches can be created, the @Developers group is pretty good for creating a topic about that. I may have missed a private message about it though
Nice work Scott, the
README.md is legit I can tell.
If we make all these changes to the Arduboy library as a beta, I assume you plan to release them as a new version at some point. At that point are you willing to break a good percentage of the existing sketches using the Arduboy V1.1 API?
That’s the reason for having a separate Arduboy2 library. Arduboy stays at V1.1 so existing sketches continue to work with it, while new development is done with Arduboy2. And, if someone wants to migrate an Arduboy V1.1 based sketch to Arduboy2, they can do so at their leasure.
If you want to substantially change the API over what the exiting one is, just go ahead and create a new separate library under a different name.
That’s why I moved the ArduboyCore class back to src directory. You can now inherit it to get basic hardware control and then write your own higher level functions on top of it in your derived class.
There won’t be a complete solution. In order to free up the timer ISRs so that other sound libraries can be used (such as ArduboyTones), and also free up some code space for sketches that don’t use sound, you have to move the tunes functions to a separate library, which can’t exist in the same directory as the Arduboy class. This will break the V1.1 API with respect to the tunes functions.
For any major release, it would be great to really look at what options are out there for extending the embedded platform we have going now, while keeping what is established well supported and make it even easier. People sometimes just want things to work for a while before they dig into the moderate frustration that can be setting up and working in development environments that can have many approaches, or where an API may change each month. It’s nice to keep the support going for what we know works, and we know people have spent time learning.
It would be fantastic to have all the documentation up for
v1-1 and a clear path for very brand new users, and a system for the documentation before moving forward too far.
It would be fantastic to keep making only quality releases on major versions. Ideally we would provide fixes to any problems for a major release, or an optimization, through minor versions, but not alter the API we have published to do so.
One thing I think would be helpful going into a major version would be to generate a short report on similar APIs out there so we can say that we are making a good choice going forward when approaching changing our API.
These sort of test builds are well suited for branches, something like
1-1-optimized is easy to understand, and a practical approach to providing consistently developed libraries that try new features, and are accessible to developers moving outside of the straight forward approach to producing content, and of course brave new-comers through the package manager or similar.
I’m not sure you get it. I’m not trying to shift to a new API. Quite the opposite; I’m trying to keep the API as close to the existing one as possible, while making it possible to free up more code space, and allow alternative sound generation libraries, and fix things like the RGB LED conflicting with tunes. This is what sketch developers have been asking for. My efforts were to make it as easy as possible to migrate a sketch from Arduboy to Arduboy2. I you want a library that shifts substantially from the existing API then that’s a whole different story.
Agreed. That’s my goal; make getting more code space and alternative sound options as painless as possible, by changing the API as little as possible. I’ve added a few new functions, but they don’t break any of the old ones.
Can we call after
arduboy.print() after declaring a class of
Arduboy when using the
master branch? I can tag it and release it for
v1-2 if that was done, getting the other fixes into a published release. I think that was about it. I can take a look at the issues again to catch up.
I’ll read through your repo and docs, there’s a lot of work there, so we should make sure it gets to as many people as it can ya know? It could just go straight in.
Can you state exactly what you expect to be different between V1.1 and V1.2, and what you intend it to accomplish?
Finish the removal of Print by maintaining the API. Let the programmer create the base Arduboy class without worrying about the compilation failing if print() is called as a function of an Arduboy class where Print is not inherited. You don’t have to load the
printf libraries, but just offer an implementation that does nothing. A separate class that implements print can be included at the very least. That’s what I was going to try when I took a stab at it.
And then what happens when people want to use a different sound library, like ArduobyTones or a future one based on the 4 channel Music Tracker that Team A.R.G. is working on? What if we want to free up the code space that the ISRs take up for tunes, even when a sketch doesn’t use any tunes functions?
To do this you must move the tunes functions to a separate library, which breaks the API. So at that point you either break all the sketches that use tunes or create a new library, as I’ve done. By just allowing the removal of the text code to free up some code space, you’re only delaying the inevitable.
There’s also the issue of the bug in nextFrame(). Are you going to fix the bug and force all existing sketches to make changes because they now run too fast, or are you going to leave the bug in nextFrame() and cripple all new sketches that use it?
By leaving Arduboy at V1.1 and carrying on with future fixes and enhancements to Arduboy2, you don’t have to deal with the issues above. Arduboy2 exists in the Arduino IDE alongside Arduboy V1.1 without any issues. Existing sketches can continue to use Arduoby V1.1 and not break, while new sketches can use Arduboy2 to take advantage of its benefits.
My Arduboy2 library already does this, along with everything described above. The text functions in the API remain unchanged. If you use class Arduboy2 you get the text functions as they are now. If you use class Arduboy2Base, the text functions are removed and the code space that was used by the font table and other print functions is freed up for use by the sketch.
It’s an iterative process, we can knock each problem along the minor versions. It would be nice to press on and get the print thing taken care of, and push a release, as that is a problem users run in to. The sound I hadn’t looked too much and it may warrant a separate repository, or another library. I wanted to get the print done then look at that issue. There are probably more than enough unresolved issues targeted and one release without resolution that we could pop one from the stack.
Keep in mind, as said a few posts back, your code could replace the existing code base no problem. Test and build reports can make it easier to assess code without reading through it. Maybe some users want to try loading it up give some status reports. I’d have to build the read repo and read through it before knowing anything, ya know?
Are there even comments?!?!
haha I kid we both know you comment.
Again, you’re going to run into a road block when you get to sound. You’re only delaying things.
My code is a fork Arduboy V1.2 development code as of the Apr 2, 2016 commit. The existing functions were basically left as is, or at least are backwards compatible. The comments are the same, other than a few that I added or changed for clarity. Just review the commit logs starting at May 27, for a quick summary of what I’ve changed from V1.2
Cool, sleep is for the weak anyway. This is a nice repo, and so just looking through it quickly: yeah man looks cool, this is great, good solution to handling print setup, but need the dummy api call, and maybe some refactoring for the class names. I’ll look at the tone stuff tomorrow, maybe push a PR at this fork.
I’m sure some others will take a look, so there should be some feedback generated in a bit.
The concept is really quite simple:
- Freeze the Arduboy library at V1.1
- Existing sketches can continue to use the frozen Arduboy V1.1 without any changes (some of these may be perfectly good games but have been abandoned by the developer and would require someone else to step in and spend the time to fix them, if the Arduboy API changed).
- Continue on with the, mostly compatible, Arduboy2 library, which unfortunately changes the API slightly but in such a way that many existing sketches will break if they use it and aren’t modified.
- New sketches could still use Arduboy (at V1.1) but since new development is now (only) being carried on in Arduboy2 they would be much wiser to use Arduboy2.
Result: Existing sketches don’t break, and if desired, could be migrated to Arduboy2 at any point in time, at their leisure, to take advantage of any new features or benefits. New sketches would naturally use Arduboy2.
Note, in continuing with this concept:
If, at some point in the future, it was decided that the API should again change in such a way as to not be backwards compatible, then the Arduboy2 library would be frozen (at least its API) and a new Arduboy3 library would be created for continued development with this new incompatible API, so as not to break sketches using Arduboy2.
I don’t know what you mean by the dummy api call.
Library and class names have been discussed extensively in the topic that you started (sorry to others who can’t view this restricted topic). It would have been nice if you’d voiced your opinion back then.
Kind of sad to see this but maybe I should have just forked it myself long ago. Sad that so much effort went into 1.2 and it can’t be made official.
So thanks for finally forking it I guess.
As I said, I’m hoping it will be accepted and made an official Arduboy repository and library for further development.
Well, hang on…
I get that in general APIs can change between major (ish) versions and while this isn’t bad per se, people may not like it. However I think it might be nice if we can find some middle ground between that (by forking or otherwise), and never changing from the 1.1 API.
If you forked the core library, someone who doesn’t notice this thread (or Community space) might think development stopped at 1.1 unless you released a 1.1.1 that deprecated it all with a note of where to find the latest library. (Uuuug-leey.)
Therefore would it be possible, at risk of slight confusion in generated documentation, to add a new class to the original repository called ArduboyBase (or something more elegant, that’s not Arduboy2) and keep the original the same? Then if people upgrade to 1.2 their sketch still works and they can try the newer things without switching libraries.
In this scenario, one thing that might be useful in making it so you don’t end up with an Arduboy2 and Arduboy3, etc. as separate libraries or even classes in the same library would be to spin out features like printing, drawing, etc. into their own decorator-pattern-like classes (the same as 1.2-alpha’s AbPrinter). I think this would have a few advantages:
- The need for breaking changes would hopefully be reduced.
- These smaller classes can be, if needed, deprecated without impacting the others.
- New / replacement “decorator” classes can be added without impact if you need to make backwards incompatible breaking changes or add new APIs.
- It would be easier, in theory, to name successors other than tacking on a number to the end (AbPrinter -> AbWriter) due to the reduced scope of the “decorator” class.
- Compiled code size could be reduced even further by lack of references to the wrapping classes you don’t use, as already stated for the reason to split out AbPrinter.
The core class would effectively become a host for the buffer (unless that moved entirely to a drawing class), begin(), and a few other core methods that are very unlikely to have arguments changed or functions removed. This would give it a reduced surface for backwards incompatible changes. Everything else would just wrap it to do their stuff and to interact with it. (like AbPrinter)
Grain of salt moment here: This is the first time in quite a while I’ve done anything in C/++ so aside my thoughts on design patterns and such as they apply to such a language may not be great. However I’ve done a good bit of development otherwise. In other words, this is just a proposal like anyone else’s. Give feedback, comments, tear it apart, whatever.
Edit: Argh. I didn’t want it to be a reply to that one… just an addition to the thread. Discourse-- for a confuzzling UI.
The problem is: No matter how many new classes you add or names you choose, somewhere in the library the tunes code for V1.1 exists. Within that code are interrupt service routines (ISR)s for the timers.
The way the IDE compile process works is that it compiles each and every .h and .c and .ccp file found in a library’s source directory, for which a sketch has included any .h file in that library. During this compile, it says “Hey, there’s an ISR here. I’m going to compile and link it in because I don’t know when or how it’s going to be used”.
Now, that ISR has been grabbed, even if the sketch that included the library never uses it. It makes it impossible for any other library to be used that needs to use the same ISR(s).
In order to not take over any ISRs, so other sound libraries have the opportunity to use them, the tunes class must be removed from the library and moved to a separate library. This breaks the V1.1 API no matter what you do for a V1.2 or later API in the same library.
I think everyone must look at having this separate Arduboy2 library from a sketch developers point of view:
First, note that in order for a library to be included in the Arduino IDE Library Manager it must use the Semantic Versioning specification for version numbers. This specification states that when you make incompatibe API changes, then you change the MAJOR version number. Since we’re talking about making API changes that can break sketches, the new version should be number 2.x.x not 1.2.x. Also note that the current API has never changed in a way that breaks things, so we can just call it API V1, instead of V1.1
A sketch should be able to use a single library and then specify which version of the API it would like to use. As is currently the case, for API V1 it would start with:
#include <Arduboy.h> Arduboy arduboy; // Continue on using API V1, such as: arduboy.begin();
To switch to API 2, the sketch would do something similar to:
#define USE_ARDUBOY_API_V2 #include <Arduboy.h> Arduboy arduboy; // Continue on using API V2, such as: arduboy.begin();
However, the Arduino environment doesn’t allow #defines in a sketch to be passed to a library, or any other technique used (that I know of), such that the library will conditionally compile from the influence of a sketch.
With a separate Arduboy2 library:
We’ll disregard the fact that there are actually two libraries, Arduboy and Arduboy2, installed in the IDE. From a sketch developers point of view, to use API V1 the same thing is done as above.
To switch to API 2, the sketch would do:
#include <Arduboy2.h> Arduboy2 arduboy; // Continue on using API V2, such as: arduboy.begin();
So, again from a sketch developers point of view, the difference between the ideal way of specifying the API version, and the slightly less ideal way of specifying the API version, is that instead of using a #define, the desired API version number is added to the end of the #included header file name and the class name.
That would be the plan: Revert Arduboy to V1.1.x and put a note right at the start of the README.md file stating that the library was frozen and to use Arduboy2 for new sketch development, and include links to Arduboy2. Likewise, Arduboy2 would contain a note stating that it was just a continuation of the retired Arduboy library, to be used for new sketch development.
This same information would also be made available in the Quick Start Guide and any development documentation and tutorials. It would also be added to the descriptions given for the libraries in the Arduino IDE Library Manager (as specified in file library.properties).
In other words, we would do everything we could to get the word out.