Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. The Lounge
  3. I've been stuck for two days on nothing

I've been stuck for two days on nothing

Scheduled Pinned Locked Moved The Lounge
helpquestiondesignhardwarejson
36 Posts 13 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • H honey the codewitch

    There is no polymorphism. Draw targets are those handles you write to.

    draw::point(my_draw_target,spoint16(10,15),color_max::red);

    Here, my_draw_target is what gets drawn to. above draws a point at (10,16), color of red my_draw_target in this case, is say, screen mode 0 but I now want to switch screen modes

    // switch the driver to a new screen mode:
    auto my_draw_target2 = driver.mode<1>();
    // now draw to the new screen
    draw::line(my_draw_target2,srect16(0,0,9,14),color_max::antique_white);

    In the above case, once you have my_draw_target2, my_draw_target becomes persona non grata. How that is handled is the question, meaning what happens if i then try to draw again to my_draw_target? PS: It may appear that my_draw_target and my_draw_target2 are polymorphic but they are not. They do sort of have a shared interface, but they don't. It's complicated. I bind using templates, not virtual base classes

    Real programmers use butterflies

    Greg UtasG Offline
    Greg UtasG Offline
    Greg Utas
    wrote on last edited by
    #19

    The Witch wrote:

    I bind using templates, not virtual base classes

    That's your problem right there. :laugh:

    Robust Services Core | Software Techniques for Lemmings | Articles
    The fox knows many things, but the hedgehog knows one big thing.

    <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
    <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

    H 1 Reply Last reply
    0
    • N NeverJustHere

      No, I've never developed anything in C++. Plenty of other languages, including plain C, but not C++. I have a vague theoretical understanding of what you're doing and would love to have time to explore it more (sadly, I don't) Logically, if I have a screen device configured in a particular mode and I reconfigure it to a new, incompatible mode, then I am essentially removing one device and adding another. All reference to the original device is now invalid, and any attempt to reference it is invalid. If, as a programmer using your library, I make an invalid call, I would expect a simple error back. The trickier question now becomes, if I reconfigure it back, am I adding the original device back? I'd say no, it is a new device with the same configuration as one that was previously removed.

      H Offline
      H Offline
      honey the codewitch
      wrote on last edited by
      #20

      Thank you! That's actually very helpful. I've been considering your approach but my fear was that it would be difficult or counterintuitive. Since you basically articulated to me that you expect precisely one of the avenues I was considering, it seems I have a clear winner in terms of approaches to this.

      Real programmers use butterflies

      E 1 Reply Last reply
      0
      • Greg UtasG Greg Utas

        The Witch wrote:

        I bind using templates, not virtual base classes

        That's your problem right there. :laugh:

        Robust Services Core | Software Techniques for Lemmings | Articles
        The fox knows many things, but the hedgehog knows one big thing.

        H Offline
        H Offline
        honey the codewitch
        wrote on last edited by
        #21

        It would be impossible to do what I am doing efficiently and by hand in C++ using any other method than what I'm doing. Generic programming has no real substitute in terms of C++ functionality. You basically *can't* replace it with virtual base classes unless you were using it where you didn't need it in the first place. Consider this: I have a pixel. The pixel is user-defined in terms of the number of color channels it has, their names, and what their binary layout, min and max channel values are, etc. This is too involved to compute at run time. It would kill performance Now, for every draw method, it deals in pixels like this, but because a pixel must be typed to its functionality, literally the only way I could make it polymorphic is to use a vtbl every time i needed a pixel. That's just not acceptable in terms of performance. Binding using templates is the solution. That way you can inline, or you can otherwise aggressively optimize away those calls.

        Real programmers use butterflies

        Greg UtasG 1 Reply Last reply
        0
        • H honey the codewitch

          It would be impossible to do what I am doing efficiently and by hand in C++ using any other method than what I'm doing. Generic programming has no real substitute in terms of C++ functionality. You basically *can't* replace it with virtual base classes unless you were using it where you didn't need it in the first place. Consider this: I have a pixel. The pixel is user-defined in terms of the number of color channels it has, their names, and what their binary layout, min and max channel values are, etc. This is too involved to compute at run time. It would kill performance Now, for every draw method, it deals in pixels like this, but because a pixel must be typed to its functionality, literally the only way I could make it polymorphic is to use a vtbl every time i needed a pixel. That's just not acceptable in terms of performance. Binding using templates is the solution. That way you can inline, or you can otherwise aggressively optimize away those calls.

          Real programmers use butterflies

          Greg UtasG Offline
          Greg UtasG Offline
          Greg Utas
          wrote on last edited by
          #22

          Wouldn't polymorphic flyweights work? You've piqued my interest. If one of your recent articles discusses this code, please point me to it.

          Robust Services Core | Software Techniques for Lemmings | Articles
          The fox knows many things, but the hedgehog knows one big thing.

          <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
          <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

          H 1 Reply Last reply
          0
          • Greg UtasG Greg Utas

            Wouldn't polymorphic flyweights work? You've piqued my interest. If one of your recent articles discusses this code, please point me to it.

            Robust Services Core | Software Techniques for Lemmings | Articles
            The fox knows many things, but the hedgehog knows one big thing.

            H Offline
            H Offline
            honey the codewitch
            wrote on last edited by
            #23

            I don't have an article that explicitly talks about how the code works, just how to use it. But.. gfx_demo/gfx_pixel.hpp at master · codewitch-honey-crisis/gfx_demo · GitHub[^] Consider the convert<>() routine starting at line 690. It's massive. It's ugly. It would be slow as heck to do at runtime. This will get called width*height times during a call to draw a bitmap when format conversion needs to be done. If any of the routine did not result in aggressive compile time operations, to where this routine translates to a few shifts and multiply/divides at worst - the thing would slow to a crawl if I had any JMPs in there. There are none despite what it looks like, except sometimes for clamping, which often gets compiled to ifless code anyway.

            Real programmers use butterflies

            M 1 Reply Last reply
            0
            • H honey the codewitch

              I've been spinning my wheels on a simple design issue I can't decide on for the life of me. I've spent a quarter of the time on this actually writing code - which works, and does everything it needs to - and the rest of that time I've spent on basically one method, and what to return from it. All to switch screen modes, and all because different screen modes *must be* different actual types. So you have to return something from a screen mode change operation that you can draw to. What do I with the old draw target from the previous mode???? This isn't even something I can really ask someone about. I hate problems like this. They leave me feeling paralyzed and frustrated because I can't just code my way out of it. I can't put myself in the shoes of a person using my code in this instance to a degree that satisfies me. So I can't answer the question. I've got $150 worth of hardware that was donated to me on the premise that I would write driver code for it, and I'm stuck on this one stupid issue and at this point it is ruining my day. Yes, I've already taken a break from it. That's why it is taking so long. The question isn't difficult. It's just difficult to decide. *headdesk* Anyway, I'm just venting, and also typing this in hopes that putting it out there might lead to me making some headway, as happens occasionally.

              Real programmers use butterflies

              CPalliniC Offline
              CPalliniC Offline
              CPallini
              wrote on last edited by
              #24

              Time to look at some creational design pattern?

              "In testa che avete, Signor di Ceprano?" -- Rigoletto

              In testa che avete, signor di Ceprano?

              H 1 Reply Last reply
              0
              • CPalliniC CPallini

                Time to look at some creational design pattern?

                "In testa che avete, Signor di Ceprano?" -- Rigoletto

                H Offline
                H Offline
                honey the codewitch
                wrote on last edited by
                #25

                I have no choice but to use the factory pattern for creation.

                Real programmers use butterflies

                1 Reply Last reply
                0
                • H honey the codewitch

                  I've been spinning my wheels on a simple design issue I can't decide on for the life of me. I've spent a quarter of the time on this actually writing code - which works, and does everything it needs to - and the rest of that time I've spent on basically one method, and what to return from it. All to switch screen modes, and all because different screen modes *must be* different actual types. So you have to return something from a screen mode change operation that you can draw to. What do I with the old draw target from the previous mode???? This isn't even something I can really ask someone about. I hate problems like this. They leave me feeling paralyzed and frustrated because I can't just code my way out of it. I can't put myself in the shoes of a person using my code in this instance to a degree that satisfies me. So I can't answer the question. I've got $150 worth of hardware that was donated to me on the premise that I would write driver code for it, and I'm stuck on this one stupid issue and at this point it is ruining my day. Yes, I've already taken a break from it. That's why it is taking so long. The question isn't difficult. It's just difficult to decide. *headdesk* Anyway, I'm just venting, and also typing this in hopes that putting it out there might lead to me making some headway, as happens occasionally.

                  Real programmers use butterflies

                  O Offline
                  O Offline
                  obeobe
                  wrote on last edited by
                  #26

                  When you're stuck on a super important issue with significant consequences and you just can't decide which of your options is the best one, use The Grand Query Of Decision Making (TGQODM). Its MySQL version looks like this:

                  SELECT IF(RAND() < 0.5, 'Do option 1', 'Do option 2')

                  1 Reply Last reply
                  0
                  • H honey the codewitch

                    That is one of the options - to fail on subsequent drawing operations. The other - trickier but doable option is to allow both to continue working, but at the expense of more memory usage (since its holding both frame buffers), and the fact that your whole screen will change when you start to draw to the original target again. I don't want this to be too difficult for people. That's one of the reason I kind of don't like the failing options. The problem with failing is that in this environment I cannot use exceptions. If people don't check return values, the fails are all silent. But maybe in this case that's for the best. After writing this out to you I'm leaning toward that. :thumbsup:

                    Real programmers use butterflies

                    K Offline
                    K Offline
                    Kirk Wolak
                    wrote on last edited by
                    #27

                    Let the developer decide. You are writing an api, right? Choose a default. Allow for the opposite value. Complete the easiest path. By then, reality should be more clear. If not, implement the other path, and repeat the thought process. Finally, how is it handled in other OSes? Older systems? Maybe they were right? Good luck!

                    H 1 Reply Last reply
                    0
                    • H honey the codewitch

                      I don't have an article that explicitly talks about how the code works, just how to use it. But.. gfx_demo/gfx_pixel.hpp at master · codewitch-honey-crisis/gfx_demo · GitHub[^] Consider the convert<>() routine starting at line 690. It's massive. It's ugly. It would be slow as heck to do at runtime. This will get called width*height times during a call to draw a bitmap when format conversion needs to be done. If any of the routine did not result in aggressive compile time operations, to where this routine translates to a few shifts and multiply/divides at worst - the thing would slow to a crawl if I had any JMPs in there. There are none despite what it looks like, except sometimes for clamping, which often gets compiled to ifless code anyway.

                      Real programmers use butterflies

                      M Offline
                      M Offline
                      Member_14192382
                      wrote on last edited by
                      #28

                      does this help? C++ reading and writing BMP images | Solarian Programmer[^]

                      H 1 Reply Last reply
                      0
                      • M Member_14192382

                        does this help? C++ reading and writing BMP images | Solarian Programmer[^]

                        H Offline
                        H Offline
                        honey the codewitch
                        wrote on last edited by
                        #29

                        Not even a little.

                        Real programmers use butterflies

                        1 Reply Last reply
                        0
                        • K Kirk Wolak

                          Let the developer decide. You are writing an api, right? Choose a default. Allow for the opposite value. Complete the easiest path. By then, reality should be more clear. If not, implement the other path, and repeat the thought process. Finally, how is it handled in other OSes? Older systems? Maybe they were right? Good luck!

                          H Offline
                          H Offline
                          honey the codewitch
                          wrote on last edited by
                          #30

                          First one is impossible. The code either works one way or it works the other. The second one was basically my approach though both paths were non-trivial. Older OS's and older systems were developed by people that either have never heard of generic programming, or avoided using it, so they've never encountered this issue.

                          Real programmers use butterflies

                          1 Reply Last reply
                          0
                          • H honey the codewitch

                            Thank you! That's actually very helpful. I've been considering your approach but my fear was that it would be difficult or counterintuitive. Since you basically articulated to me that you expect precisely one of the avenues I was considering, it seems I have a clear winner in terms of approaches to this.

                            Real programmers use butterflies

                            E Offline
                            E Offline
                            ElectronProgrammer
                            wrote on last edited by
                            #31

                            I do not know the details of your code, only what I read in this thread, but I was thinking the same as NeverJustHere with one change. I would probably make the class defining the device/target a singleton so that getting a new target would make the old reference point to the new target and probably no errors would have to be thrown. If a method is added to check the current drawing mode you have all your bases covered. Maybe! :) Hope it helps. Good luck.

                            H 1 Reply Last reply
                            0
                            • E ElectronProgrammer

                              I do not know the details of your code, only what I read in this thread, but I was thinking the same as NeverJustHere with one change. I would probably make the class defining the device/target a singleton so that getting a new target would make the old reference point to the new target and probably no errors would have to be thrown. If a method is added to check the current drawing mode you have all your bases covered. Maybe! :) Hope it helps. Good luck.

                              H Offline
                              H Offline
                              honey the codewitch
                              wrote on last edited by
                              #32

                              Yeah that's not doable because each mode must be a fundamentally different type. You can't represent mode 1 with a class for mode 2. If you could, I'd just have a "set mode" method on the driver class, and then use the driver class as the draw target like i do with my single screen mode drivers.

                              Real programmers use butterflies

                              1 Reply Last reply
                              0
                              • H honey the codewitch

                                I've been spinning my wheels on a simple design issue I can't decide on for the life of me. I've spent a quarter of the time on this actually writing code - which works, and does everything it needs to - and the rest of that time I've spent on basically one method, and what to return from it. All to switch screen modes, and all because different screen modes *must be* different actual types. So you have to return something from a screen mode change operation that you can draw to. What do I with the old draw target from the previous mode???? This isn't even something I can really ask someone about. I hate problems like this. They leave me feeling paralyzed and frustrated because I can't just code my way out of it. I can't put myself in the shoes of a person using my code in this instance to a degree that satisfies me. So I can't answer the question. I've got $150 worth of hardware that was donated to me on the premise that I would write driver code for it, and I'm stuck on this one stupid issue and at this point it is ruining my day. Yes, I've already taken a break from it. That's why it is taking so long. The question isn't difficult. It's just difficult to decide. *headdesk* Anyway, I'm just venting, and also typing this in hopes that putting it out there might lead to me making some headway, as happens occasionally.

                                Real programmers use butterflies

                                A Offline
                                A Offline
                                AnotherKen
                                wrote on last edited by
                                #33

                                I'm not sure if I even fully understand the problem but it sounds a bit like you could benefit from a design change where you maintain state information for each draw mode. This would allow you to switch between modes without loosing anything since all relevant data would be saved before switching modes.

                                H 1 Reply Last reply
                                0
                                • A AnotherKen

                                  I'm not sure if I even fully understand the problem but it sounds a bit like you could benefit from a design change where you maintain state information for each draw mode. This would allow you to switch between modes without loosing anything since all relevant data would be saved before switching modes.

                                  H Offline
                                  H Offline
                                  honey the codewitch
                                  wrote on last edited by
                                  #34

                                  I don't have that kind of memory. The e-paper displays essentially require me to keep the frame buffer around in local RAM. So my size in bytes for monochrome black and white displays is width*height/8 and it gets worse when you introduce virtualization of higher bit depths through dithering, such that you can simulate 8-bit grayscale for example, but at that point your frame buffer size becomes simply width*height in bytes. Ouch. That's my state for each mode. It's not a good idea to hold a frame buffer around when someone is not using it on these devices. The devices I'm targeting with these displays range in RAM anywhere from about 300k to 4.5MB, with the caveat that 4MBs of that is PSRAM over SPI and thus slow.

                                  Real programmers use butterflies

                                  A 1 Reply Last reply
                                  0
                                  • H honey the codewitch

                                    I don't have that kind of memory. The e-paper displays essentially require me to keep the frame buffer around in local RAM. So my size in bytes for monochrome black and white displays is width*height/8 and it gets worse when you introduce virtualization of higher bit depths through dithering, such that you can simulate 8-bit grayscale for example, but at that point your frame buffer size becomes simply width*height in bytes. Ouch. That's my state for each mode. It's not a good idea to hold a frame buffer around when someone is not using it on these devices. The devices I'm targeting with these displays range in RAM anywhere from about 300k to 4.5MB, with the caveat that 4MBs of that is PSRAM over SPI and thus slow.

                                    Real programmers use butterflies

                                    A Offline
                                    A Offline
                                    AnotherKen
                                    wrote on last edited by
                                    #35

                                    In the past, I had to solve that kind of problem by using buffer switching. To do that you can save the buffer to the PSRAM and then when you switch back to it you can save the current buffer and then load the next buffer if it was saved.

                                    H 1 Reply Last reply
                                    0
                                    • A AnotherKen

                                      In the past, I had to solve that kind of problem by using buffer switching. To do that you can save the buffer to the PSRAM and then when you switch back to it you can save the current buffer and then load the next buffer if it was saved.

                                      H Offline
                                      H Offline
                                      honey the codewitch
                                      wrote on last edited by
                                      #36

                                      I mean yes, but there's a number of problems with that. For starters, there might not be room in NVS flash to do that. Second, it's a performance killer And finally, it doesn't seem that intuitive to hold the screen buffer for multiple simultaneous screen modes around when a screen can only display one at a time. Or at least I should say I can think of as many arguments as to why it's counterintuitive as the opposite. So given that, it's not a route I'm taking. I've actually finished 80% of this driver now - the last bit being a dithering algorithm i need to work out that takes advantage of 4 color grayscale rather than simply black and white.

                                      Real programmers use butterflies

                                      1 Reply Last reply
                                      0
                                      Reply
                                      • Reply as topic
                                      Log in to reply
                                      • Oldest to Newest
                                      • Newest to Oldest
                                      • Most Votes


                                      • Login

                                      • Don't have an account? Register

                                      • Login or register to search.
                                      • First post
                                        Last post
                                      0
                                      • Categories
                                      • Recent
                                      • Tags
                                      • Popular
                                      • World
                                      • Users
                                      • Groups