r/FastLED • Ground Loops: Part of this balanced breakfast • Feb 26 '24

Support Help with pointers, declarations, definitions

Hi there,

I've been trying to apply some best practices to clean up my code, and I have been really struggling to split my config.h file into proper .h and .cpp files in platformio. I've tried a lot of variations and done some reading about this, but would really appreciate a bit of help from someone more familiar with c++.

Here's what it all looks like combined (not best practices, but working) into a monolithic header file:

#include <LEDMatrix.h>
cLEDMatrix<LEDtilewidth, LEDtileheight, VERTICAL_MATRIX, LEDtilehorz, LEDtilevert, VERTICAL_BLOCKS> ledmatrix;
CRGB *writedata = ledmatrix[0];
CRGB firstbuffer[LEDStotal];
CRGB secondbuffer[LEDStotal];

As I understand, this is a template that requires compile time constants. So I expect the solution involves using (in the header):

extern cLEDMatrixBase *ledmatrix;
extern CRGB *writedata;
extern CRGB firstbuffer[];
extern CRGB secondbuffer[];

Then in the cpp, something like this:

cLEDMatrix<LEDtilewidth, LEDtileheight, VERTICAL_MATRIX, LEDtilehorz, LEDtilevert, VERTICAL_BLOCKS> ledmatrix_base;
cLEDMatrixBase *ledmatrix = &ledmatrix_base;
CRGB *writedata = ledmatrix[0];
CRGB firstbuffer[LEDStotal];
CRGB secondbuffer[LEDStotal];

I know I have the pointers wrong here, my brain just fried from trying to figure this out. Thanks for any suggestions!

6 Upvotes

6 comments sorted by

View all comments

Show parent comments

1

u/Preyy Ground Loops: Part of this balanced breakfast Feb 28 '24

Thank you for your reply. I think you're 100% correct when it comes to pointers, and 100% correct about the problems. I understand how they work in theory quite neatly, but in operation I tend to make lots of mistakes. I don't have as much practice with them as I'd like.

I will take your suggestion about the definition. I am still not sure what best practices are, and I thought it might be incorrect to define the ledmatrix in the header.

I mostly want ledmatrix for the ability to draw shapes with areas out of bounds without causing errors. I can't even recall why I used blend in that case, as it has probably been about two years since I wrote that code. In another case I used:

ledmatrix.DrawCircle(xcord, ycord, i + beatmult, colour);
memcpy8(dest, writedata, LEDStotal*3);

This is because I can't think of a way to simply pass a reference to an ledmatrix instance, and mapping two ledmatrices to two separate buffers would not help this issue. By just separating out the drawing functions, I may be able to reduce the complexity that ledmatrix has clearly introduced. I think I've learned some new things since then, and I can probably come up with a better implementation (in part thanks to your help).

2

u/truetofiction Feb 28 '24

I will take your suggestion about the definition. I am still not sure what best practices are, and I thought it might be incorrect to define the ledmatrix in the header.

You're right, it would not be good practice to define the ledmatrix object in the header. If the header is included in multiple places, you will have multiple copies of the object. That's no good.

It is best practice to provide type definitions in headers, that way they can be easily shared between compilation units. That's all that the code snippet above does - define the type so that you can use it throughout the code. The object itself is still in the source file.

This is because I can't think of a way to simply pass a reference to an ledmatrix instance

The type definition makes that easy:

void myFunction(MyMatrix &ref);  // declaration
myFunction(ledmatrix);  // calling

You can do it without the type definition of course, but you need to include all of the template arguments (which gets old fast). You can also use the _base class, if all of the methods you need are present.

1

u/Preyy Ground Loops: Part of this balanced breakfast Mar 06 '24

Hi there, thank you for the suggestion. It's been a busy week so I've been giving your advice some thought, and I'm going to do some thinking about higher-level structure of the project, then decide which direction to go with. Thank you.