Playing unique blade array audio idents on live array switching

Ah cool, good point. I think I was close:

So maybe we should move the increment down to after the deactivation.
I mean, it seems it was working ok, but maybe that’s happenstance.
Also, in my testing I was just glued to the Serial Monitor and never even turned the battery power on, so I have no idea what the blade looked like (merging or not).

@Sabersense can you see if this still works, while hopefully also clearing up the “merging”?
and @hkwwinger could you see if this fixes your freezing?
I’ll be around later.


  void NextBladeArray() {
    // current_config = blades + (current_config - blades + 1) % NELEM(blades);
    FakeFindBladeAgain();
    // option if no array.wavs used, play font.wav instead
    //  SaberBase::DoNewFont();
    SFX_array.Select(current_config - blades);
    hybrid_font.PlayCommon(&SFX_array);
  }

  // Manual Blade Array Selection version of FindBladeAgain()
  void FakeFindBladeAgain() {
    // Reverse everything FindBladeAgain does, except for recalculating best_config
    ONCEPERBLADE(UNSET_BLADE_STYLE)

#undef DEACTIVATE
#define DEACTIVATE(N) do {                      \
    if (current_config->blade##N)               \
      current_config->blade##N->Deactivate();   \
  } while(0);

    ONCEPERBLADE(DEACTIVATE);
    SaveVolumeIfNeeded();
    current_config = blades + (current_config - blades + 1) % NELEM(blades);

#undef ACTIVATE
#define ACTIVATE(N) do {                        \
    if (!current_config->blade##N) {            \
      goto bad_blade;                           \
    }                                           \
    current_config->blade##N->Activate(N);      \
  } while(0);

    ONCEPERBLADE(ACTIVATE);
    RestoreGlobalState();

#ifdef SAVE_PRESET
    ResumePreset();
#else
    SetPreset(0, false);
#endif // SAVE_PRESET
    PVLOG_NORMAL << "** FakeFindBladeAgain() Completed\n";
    return;

#if NUM_BLADES != 0
  bad_blade:
    ProffieOSErrors::error_in_blade_array();
#endif
  }
1 Like

@NoSloppy
I have mixed emotions…

On the one hand joy, because I just tried that amended code to manually cycle arrays and it now works flawlessly! :smiley: :ok_hand:

On the other hand disappointment because the code you came up with is vastly superior to the clunky code I spent ages working on to achieve the same thing. :laughing:

Seriously though, great work Brian! It’s a really slick and elegant solution. Much respect! :clap: :clap: :clap:

Now I feel bad. :upside_down_face: I wasn’t trying to “steal your thunder”. It was your idea, it just appealed to me as I think it’s useful and wanted to make it work for myself to use as well. I have an addictive focus, so making this work was a fun challenge with which I found myself unable to stop until it worked.
You’re code wasn’t clunky per-se. I really only leveraged code that already existed. It was your idea, and you started with fresh, unique classes and such.
I just happen to be familiar enough with the OS that I knew where to look for code that already did very similar stuff.
I also have learned some things along the way about ProffieOS code development.

  • It needs to work. But it also needs to be efficient, make sense, and readability is very important. Code needs to be maintained by others who aren’t in your head, so always use comments if needed and variable/function names that are as self explanatory as possible. This way anybody can follow the flow if they read it for the first time. (you had this covered)

  • It should use as little memory as possible. This means that if it’s a custom thing YOU want to use, then guarding it with a #define or making sure that it only counts against memory use if it’s called upon, especially if it would affect everyone all the time if it’s to be part of the main OS. (you had this covered)

  • It should be well coded to follow the style of the rest of the OS. Repurposing existing code is a great way to manage this, since it’s already correct in what it does and how it’s used, and can likely be integrated in some way to help your intent by just applying a few tweaks instead of reinventing the wheel.
    There are lots of things C++ can do, but ProffieOS has it’s own “flavor” of how to do things that you should try to stay aligned with. Take type casting for example. At some point, some thing I wanted to do could have benefitted from using static_cast or similar, but in searching through the code base, it seems that’s really only used “in a pinch” here and there. So I found a more common way to deal with it.

  • Ask for help (you had this covered). Posting here on the Crucible is IMO the best way to get answers for how things can/should work. Now, that said, I probably should have “made you” do the work to assemble a working solution by sharing what I thought of as possible ways to do it instead of just going ahead and doing it myself. I’ll try to do more of that in the future. However, I think / hope I explained along the way how things might work so that you had a chance to ingest helpful info as this thread went on. We tested things, discussed goals, and wound up expanding on the original idea even.

I’m pretty sure it’s still kludgy as I AM NO EXPERT by any means so please do not praise me in any way! Yeah, I can hack my way through some things, but I guarantee it’s not the BEST solution at all.
I am always learning more things every single editing session, and there’s a ton I don’t really get.

2 Likes

See also:

1 Like

LOL! Not at all! :laughing: The collaboration is what makes it both interesting and educational. And I know what you mean about not being able to put something down once the idea is in your head, as I’m exactly the same! LOL!

And on all your points, yes, I concur instinctively, even if I don’t necessarily know how to achieve some of those aims. (That’s why I’m at the Crucible after all! :smiley: ).

As for asking for help, I know it may not seem like it sometimes, but I do really try to do this as sparingly as possible. People’s time is precious and I’m perpetually grateful to those, like your good self, wiling to spare some to help other saber fans take a step forward towards a given goal. :pray: :slight_smile:

Anyway great job on the code, :ok_hand: and if you’ve no objection I have stolen the bulk of it! LOL! Though naturally I’ve tweaked it - gotta have up for forward, down for back, as my prop is all about simplicity and consistency of rules across all variants of all functions. :smiley: Thanks again. :pray:

I could 100% say the exact same thing to you further up in this thread haha.

THis is the way. Go-go open source!

1 Like

Finding the right time to ask for help can be tricky.
Nobody wants to “do it for you”, but nobody wants you to waste your time doing something that is a 2-minute thing for someone else either.

I think it becomes a little easier if you think of it as “learning how to do it” rather than “getting it to work” though. If your goal is to learn how to do something, then you naturally want to try yourself first, and it also shapes your questions. I for one like answering questions if I feel like the person asking them is actually learning from it.

1 Like

Yes, this is working 100% now. I can’t wait to explore several ideas on my sabers moving forward. This community is pretty amazing and I am learning a ton and having a blast. @NoSloppy thank you for helping , and taking the time to teach me a few new things .

This is eminently valid, and I realise I’ve been guilty of the former from time to time, but that has steadily changed as I’ve made more changes and become more ambitious, and also because increased knowledge and understanding has inevitably led to the birth of new ideas which bring new challenges that I then want to solve, and so the cycle continues.

Which leads me onto one particular question which I’m curious about…

One of the big challenges for people like me who are new to programming languages is the interdependency of different commands between different files, as it makes tracking the full path of how features and functions work quite involved. So while thinking about how the system knows what code is in which file. it occurred to me to ask - when we first did the FakeBladeID thing, with it just toggling between two arrays, the only way it could work was to put the code above the very top line of code in the prop file. What was the purpose of that, as Brian’s new code above achieves essentially the same thing, but only needs to go in the main code block in the prop (the buttons class?)? Did putting that early version above the top effectively serve to put that code in a different file but without having to actually mess with (and possibly mess up) that different file? And if so, which file was it effectively going in?

Really just curious is all, as I think understanding that may start to give me an insight into the logic of how these various files interact with one another.

1 Like

Your original implementation used struct SabersenseArraySelector and had it’s own unique set of instructions written from scratch inside that container. It didn’t depend on anything externally to run.

The version I did uses some code that lives in the prop_base file, so it needs to use inheritance in order to access it. You might want to read up on derived classes and inheritance a bit, as that will explain some of what you were asking about as far as code in other files and how it gets accessed from another place.

Because the SaberBCButtons class (SabersenseButtons in your case) inherits from and is therefore a derived class of PropBase (PropBase is the parent class), the code in prop_base.h can only be accessed from within the derived class. SO that’s where I put it.

For example, the function FakeFindBladeAgain() calls RestoreGlobalState(), but that lives in prop_base.h. So if it’s placed above and outside of the SaberBCButtons derived class, it won’t have access to PropBase, and therefore won’t be able to find any function named RestoreGlobalState().

.

1 Like

This is great info - and with some useful pointers as to what to read up on, which I shall definitely do.
Sincere thanks Brian. :pray:

So, ProffieOS is a weird program, because all the code is sucked in into ProffieOS.ino using #include. That means that as far as the compiler is concerned, there is only one single file. That also means that most of the organization, and splitting things in files is entirely up to me.

The compiler (and C++) also doesn’t really care which file you put the code in. However, the order inside the file matters. If you want to access the “prop” object, the compiler has to know about the prop object, and what type of object it is. The compiler is not able to “see” things further down the file, so the prop object has to be declared before you can use it. These sort of dependencies imposes an order on the code within the file.

The rest if just code organization, grouping related code into clases, which then go in a file with a name that makes sense and in a directory grouping things together. Ultimately, when reading code you’re not familiar with, it’s best to just use a search to find stuff. Smart editors can do that for you, and then you can just click on a word in the code, and the editor will go find the definition of that define/function/class/variable for you.

1 Like

you are now at the point of greatest learning, you have now upgraded from unconscious incompetence to conscious incompetence, this means you are prime & geared to hit that massively expansive learning curve. you are now skilled enough to know that you know nothing. enjoy the ride.

1 Like

LOL! Spot on! :rofl:

1 Like

Thanks so much for the explanation Prof. I’ve been using it to try to get to grips with the next function I want to build in. Progress made, but I plan to keep going for a while before I resort to asking stuff about it on here. :slight_smile:

1 Like
  • within the same file. I wish it was smart enough to follow included files and parent classes. That would make life easy.

I don’t suppose Sublimetext is “smart” enough to do that, or is it ?

I don’t know. I don’t use sublime text.
When I need it, I use etags, which is supported by several editors, but it’s an old command-line utility, so I would think there are probably better ways…

“git grep …” is also a good and fast way to do this.

Thank you @profezzorn, I will look into them.

Is that something from Github ?

No, it’s a part of git.

1 Like