so i'm finally getting round to adding an OLED to Pepper.
my Pepper programs are PureData, so i'm running O2O in the background.
the plan is to use the loop_ function to switch between patches.

now, my noob question for O2O: with an arduino i'd probably just have a separate .ino open for every program in the loop, like separate tabs for clarity's sake, and combine them when compiling.
is there a way to do this in the O2O? can i just throw in an extra .cpp file for every patch that needs the display?

Do you need O2O to behave differently for each program that's running? The best way would probably be to extend O2O's code to accept a wider set of messages and then every program sends to different OSC addresses of a unified O2O program to achieve project-specific functionalities. The alternative is to have a custom pd render with integrated O2O support for each project and get rid of the stand-alone O2O process

    giuliomoro Do you need O2O to behave differently for each program that's running?

    well, it'd be very nice to have that flexibility. 😛
    hmm let me rephrase that - we already HAVE that flexibility, but was just wondering if there's a way to avoid a scrollfest by breaking the code up into dedicated pages (.cpp files?) in the IDE. like Tabs in an arduino sketch.

      Remork like Tabs in an arduino sketch.

      Can't be done at the moment, but you can have different browser tabs, each with its own file if that is helpful. I am not sure if this question is just about being able to edit multiple files side by side, but I'll take the longer approach of explaining how to split custom handling code for O2O across different source files: if you have a single O2O instance, then you could split incoming messages based on the paths of individual programs and write the code to handle each path in a different file.

      You'd then need some header file osc-handlers.h where you declare the handler functions and make the Error enum accessible from multiple files:

      #include <oscpkt.hh>
      #include "u8g2/U8g2LinuxI2C.h"
      
      enum Error {
      	kOk = 0,
      	kUnmatchedPattern,
      	kWrongArguments,
      	kInvalidMode,
      	kOutOfRange,
      };
      enum Error handleProject0(U8G2& u8g2, const oscpkt::Message& msg);
      enum Error handleProject1(U8G2& u8g2, const oscpkt::Message& msg);

      Two changes are then needed for the stock parseMessage() function:

      • account for the global enum: repalace the definition of the error variable with a simpler enum Error error = kOk.
      • call these external handlers. For instance, after the else if (msg.match("/waveform")){...} block, you'd add:
        	} else if (msg.match("/waveform"))
        	{
        // existing code here
        // ...
        	} else if (msg.partialMatch("/project0/"))
        	{
        		error = handleProject0(u8g2, args);
        	} else if (msg.partialMatch("/project1/"))
        	{
        		error = handleProject1(u8g2, args);
        	} else
        		error = kUnmatchedPattern;

      Then you can have some HandleProject0.cpp and HandleProject1.cpp files where in each you implement all the functions and possible pattern matches for each of the partial matches /project0/ and /project1/. These will follow the blueprint of the chained msg.match() calls present in parseMessage(), with minimal boilerplate code to get the arguments and return the result, e.g. HandleProject0.cpp:

      #include 
      enum Error handleProject0(U8G2& u8g2, const oscpkt::Message& msg)
      {
      	oscpkt::Message::ArgReader args = msg.arg();
      	if (msg.match("/project0/test"))
      	{
      		if(!args.isOkNoMoreArgs()){
      			error = kWrongArguments;
      		}
      		else {
      			printf("received /project0/test\n");
      			u8g2.setFont(u8g2_font_ncenB08_tr);
      			u8g2.setFontRefHeightText();
      			u8g2.drawStr(0, displayHeight * 0.5, "PROJECT0 TEST");
      		}
      	}  else if (msg.match("/project0/another-pattern/") {
      		// ...
      	}
      	return error;
      }

      With this approach, each of the Handle*.cpp files will be smaller and easier to scroll through and it conveniently keeps implementations out of the main file.

      If you wanted to embed an O2O instance inside each project, then you could use a similar approach to use a unified custom Pd render.cpp shared across all projects, where you enable the O2O functionalities, then adding anything that's project-specific in a dedicated HandleOsc.cpp file.

        a single O2O instance fanning out across different files is exactly what i was thinking.
        thank you so much!
        will try asap!

        Btw I added a few more functions a couple of days ago for drawing dots of varying size with persistence and also to print a more or less arbitrary number of text lines.

        'more or less arbitrary' sounds intriguing 🙂

        I mean I put a limit of 3 lines but it doesn't have to be that way

        that persistence thing is pretty funky!

        alright, been trying to get the handlers thing up and running.
        had to remove #include "u8g2/U8g2LinuxI2C.h" from osc-handlers.h because of multiple definitions.

        in the end, still getting this error:

        no matching function for call to 'handleProject0' column: 11, line: 506
        /root/Bela/projects/O2OPepperSplit/main.cpp:506:11: error: no matching function for call to 'handleProject0'
        error = handleProject0(u8g2, args);
        ^~~~~~~~~~~~~~
        /root/Bela/projects/O2OPepperSplit/osc-handlers.h:10:12: note: candidate function not viable: no known conversion from 'oscpkt::Message::ArgReader' to 'const oscpkt::Message' for 2nd argument
        enum Error handleProject0(U8G2& u8g2, const oscpkt::Message& msg);
        ^
        1 error generated.
        make: *** [/root/Bela/projects/O2OPepperSplit/build/main.o] Error 1

        wish i knew how to solve this myself, but can someone hold my hand on this one as well?

        thanks for a swift reply on a saturday!

        that seems to have fixed that error, however now i'm getting this one about the #include at the top of the handleproject0.cpp file:

        expected "FILENAME" or <FILENAME> column: 10, line: 1
        /root/Bela/projects/O2OPepperSplit/handleProject0.cpp:1:10: error: expected "FILENAME" or <FILENAME>
        #include
        ^
        1 error generated.
        make: *** [/root/Bela/projects/O2OPepperSplit/build/handleProject0.o] Error 1

        feels like this is getting awfully close to working though 🙂

        too bad my C++ knowledge is rather limited - find myself going back and forth to online manuals and explainers since i'd like to at least understand whats going on, but i still find myself scratching my head rather often.

        like i have some questions about why everything seems to be included in a sort of error-determination-package, but maybe that would take this too far

        I left a blank there for no reason...
        That should be #include "osc-handlers.h"

        well. hmm.
        if i #include "u8g2/U8g2LinuxI2C.h" in osc-handlers.h i get the 'multiply defined' errors.
        and if i don't include it, it seems to not know what to do without it?

        In file osc-handlers.h: unknown type name 'U8G2' column: 27, line: 10
        In file osc-handlers.h: unknown type name 'U8G2' column: 27, line: 11
        unknown type name 'U8G2' column: 27, line: 2
        use of undeclared identifier 'error' column: 4, line: 8
        use of undeclared identifier 'u8g2_font_ncenB08_tr' column: 17, line: 12
        use of undeclared identifier 'displayHeight' column: 20, line: 14
        use of undeclared identifier 'error' column: 9, line: 19

          Remork if i #include "u8g2/U8g2LinuxI2C.h" in osc-handlers.h i get the 'multiply defined' errors.

          good, this one is not my fault. I don't have time to look into this right now, but what are the symbols that get "multiply defined" ?

            giuliomoro replace the definition of the error variable with a simpler enum Error error = kOk.

            if i move that definition to the beginning of main.cpp osc-handlers.h
            so it's not inside the parsing function, but rather under the enum Error {} , that improves matters.

            i also added #include "u8g2/U8g2LinuxI2C.h" to handleProject0.cpp instead.

            i'm down to three errors now:

            In file osc-handlers.h: unknown type name 'U8G2' column: 27, line: 13
            In file osc-handlers.h: unknown type name 'U8G2' column: 27, line: 14
            In file handleProject0.cpp: use of undeclared identifier 'displayHeight' column: 20, line: 16

            if i move int displayHeight = 64 to osc-handlers.h, that gets rid of the last error.
            (moved its brother displayWidth along. constants for a single OLED in my case)

            i figured, since both .cpp files include the handlers.. not sure if that is good practice?

            not sure what to do about the final two errors though.

            In file osc-handlers.h: unknown type name 'U8G2' column: 27, line: 13
            In file osc-handlers.h: unknown type name 'U8G2' column: 27, line: 14

            for clarity, osc-handlers.h now looks like this:

            #include <oscpkt.hh>
            int displayWidth = 128;
            int displayHeight = 64;
            enum Error {
            kOk = 0,
            kUnmatchedPattern,
            kWrongArguments,
            kInvalidMode,
            kOutOfRange,
            };
            enum Error error = kOk;
            enum Error handleProject0(U8G2& u8g2, const oscpkt::Message& msg);
            enum Error handleProject1(U8G2& u8g2, const oscpkt::Message& msg);

              giuliomoro but what are the symbols that get "multiply defined" ?

              am i getting ahead of myself moving #include "u8g2/U8g2LinuxI2C.h" to handleProject0.cpp?
              just dabbling :/

              let me move that back to the header for you.
              here goes:

              In file u8g2/U8g2LinuxI2C.h: redefinition of 'U8G2LinuxI2C' column: 7, line: 12
              In file u8g2/U8g2LinuxI2C.h: redefinition of 'U8G2_SH1106_128X64_NONAME_F_HW_I2C_LINUX' column: 7, line: 20
              In file u8g2/U8g2LinuxI2C.h: redefinition of 'U8G2_SSD1306_128X64_NONAME_F_HW_I2C_LINUX' column: 7, line: 26
              In file u8g2/U8g2LinuxI2C.h: redefinition of 'U8G2_SSD1309_128X64_NONAME2_F_HW_I2C_LINUX' column: 7, line: 32

              In file included from /root/Bela/projects/O2OPepperSplit/main.cpp:27:
              In file included from /root/Bela/projects/O2OPepperSplit/osc-handlers.h:2:
              /root/Bela/projects/O2OPepperSplit/u8g2/U8g2LinuxI2C.h:12:7: error: redefinition of 'U8G2LinuxI2C'
              class U8G2LinuxI2C : public U8G2 {
              ^
              /root/Bela/projects/O2OPepperSplit/u8g2/U8g2LinuxI2C.h:12:7: note: previous definition is here
              class U8G2LinuxI2C : public U8G2 {
              ^
              In file included from /root/Bela/projects/O2OPepperSplit/main.cpp:27:
              In file included from /root/Bela/projects/O2OPepperSplit/osc-handlers.h:2:
              /root/Bela/projects/O2OPepperSplit/u8g2/U8g2LinuxI2C.h:20:7: error: redefinition of 'U8G2_SH1106_128X64_NONAME_F_HW_I2C_LINUX'
              class U8G2_SH1106_128X64_NONAME_F_HW_I2C_LINUX : public U8G2LinuxI2C {
              ^
              /root/Bela/projects/O2OPepperSplit/u8g2/U8g2LinuxI2C.h:20:7: note: previous definition is here
              class U8G2_SH1106_128X64_NONAME_F_HW_I2C_LINUX : public U8G2LinuxI2C {
              ^
              In file included from /root/Bela/projects/O2OPepperSplit/main.cpp:27:
              In file included from /root/Bela/projects/O2OPepperSplit/osc-handlers.h:2:
              /root/Bela/projects/O2OPepperSplit/u8g2/U8g2LinuxI2C.h:26:7: error: redefinition of 'U8G2_SSD1306_128X64_NONAME_F_HW_I2C_LINUX'
              class U8G2_SSD1306_128X64_NONAME_F_HW_I2C_LINUX : public U8G2LinuxI2C {
              ^
              /root/Bela/projects/O2OPepperSplit/u8g2/U8g2LinuxI2C.h:26:7: note: previous definition is here
              class U8G2_SSD1306_128X64_NONAME_F_HW_I2C_LINUX : public U8G2LinuxI2C {
              ^
              In file included from /root/Bela/projects/O2OPepperSplit/main.cpp:27:
              In file included from /root/Bela/projects/O2OPepperSplit/osc-handlers.h:2:
              /root/Bela/projects/O2OPepperSplit/u8g2/U8g2LinuxI2C.h:32:7: error: redefinition of 'U8G2_SSD1309_128X64_NONAME2_F_HW_I2C_LINUX'
              class U8G2_SSD1309_128X64_NONAME2_F_HW_I2C_LINUX : public U8G2LinuxI2C {
              ^
              /root/Bela/projects/O2OPepperSplit/u8g2/U8g2LinuxI2C.h:32:7: note: previous definition is here
              class U8G2_SSD1309_128X64_NONAME2_F_HW_I2C_LINUX : public U8G2LinuxI2C {