Passing Custom Objects to Print

I’m working on a game where I wanted some info to display on the screen for each object, but I just wanted to pass the object to the arduboy.print() function. I was thinking of defining a toString like function that is common in other languages, so did a google search and came across https://arduino.stackexchange.com/questions/53732/is-it-possible-to-print-a-custom-object-by-passing-it-to-serial-print.

So I went and implemented it.

        size_t printTo(Print& p) const
        {
          size_t line = 0;
          size_t x = Arduboy2::getCursorX();
          size_t y = Arduboy2::getCursorY();
          
          line += p.print(this->getName());

          y += 8;

          Arduboy2::setCursor(x, y);
          line += p.print("Weight");

          y += 8;

          Arduboy2::setCursor(x, y);
          line += p.print(this->getWeight());

          return line;
        }

What is extra neat is that I could use the arduboy.setCursor() function inside the printTo function and only call arduboy.print(obj) and it laid out my text info how I wanted it! Below is how I’m passing my custom object to the print function. levels[levelIndex][lastObjIndex] is a 2d array storing my objects for each level.

arduboy.print(levels[levelIndex][lastObjIndex]);

Thought this was pretty neat and wanted to share with others.

1 Like

That would be a bad idea.

You need to store the string somewhere and if you’re choosing to return the string then you’d have to do dynamic memory allocation with new which is generally a bad idea on a system like the Arduboy that has so little memory.

If you were on desktop or a system with a much larger pool of memory then it wouldn’t be too bad, although it would still be a tad wasteful because you’d probably be deleting the memory right after printing it.

I’d generally advise people not to use Printable because virtual functions are expensive on AVR and should generally be avoided if possible.
(Note that in the StackExchange question you link to the person in question is using an ESP8266, which has significantly more resources.)

It would be significantly cheaper to not inherit Printable but provide a printTo function anyway and then use levels[levelIndex][lastObjectIndex].printTo(arduboy) instead.

The perceived convinience of doing arduboy.print(object) instead of object.printTo(arduboy) is simply not worth the expense of virtual functions.

In your case it would make more sense for printTo to only accept a reference to Arduboy2 anyway because you’re manipulating the cursor. It would be odd if, for example, you passed Serial to printTo and Arduboy2's cursor changed position.

If you were using println instead it would make more sense to use Print because then the function would be truly agnostic to what kind of Print was being used without having potentially unwanted side-effects.


Sorry if it feels like I’m raining on your parade a bit, but I would be remiss if I didn’t point out the potential downsides to this particular approach.


Personally I believe Arduino’s Printable class is an example of when OOP thinking goes wrong and results in a flawed design.
Inheritance is the wrong tool for the job.

2 Likes

No worries! It is good to get the downsides of this approach from someone with more knowledge than I do on the subject! Good info for those who come across this topic looking for something similar.

2 Likes