0

I have a base class representing a handler for some (generic) hardwre, from which specific instances derive. The command protocol that the handler receives includes a string which determines the function that the handler executes.

I would like to construct a static mapping of strings to function pointers using HashMap (which is basically similar to std::map as far as I know, so this should apply more-or-less equally to JUCE and std). I want this to be static because this mapping will not change, and I don't want to have to rebuild it every time I instantiate a handler (which might happen a lot).

//general hardware handler
class HandlerBase {
public:

    // all command handlers take a BazCommand reference and return success
    typedef bool (HandlerBase::* commandHandler)(BazCommand&);

    // this is the mapping of String to the handler function that
    // determines which function to run when getting a command
    typedef HashMap<String, commandHandler> CmdList;
}

// handler for the Foomatic Barrifier 2000
class FoomaticHandler : public HandlerBase {
public:

    //one of the Foomatic handler functions
    bool barrify(BazCommand& cmd) {
        return true;
    }

    static CmdList createCmdMapping() {
        CmdList l;

        l.set("bar", (commandHandler) &FoomaticHandler::barrify);
        // add all Foomatic handler functions here

        return l;
    }

    bool doCommand(BazCommand& cmd) {
        String cmdString = cmd.getCmdString();

        //execute correct function here
    }

    //this cmdList is static and shared betweeen all Foomatic handlers
    static CmdList cmdList;
}

// set up the Foomatic command hashmap
FoomaticHandler::CmdList FoomaticHandler::cmdList =
        FoomaticHandler::createCmdMapping();

However, this approach generates a lot of errors. I have tried several alternative arrangments. This particular one produces:

../core/../../../juce/JuceLibraryCode/modules/juce_audio_basics/../juce_core/containers/juce_HashMap.h: In static member function ‘static HandlerBase::CmdList FoomaticHandler::createCmdMapping()’:
 ../core/../../../juce/JuceLibraryCode/modules/juce_audio_basics/../juce_core/containers/juce_HashMap.h:445:5: error: ‘juce::HashMap<KeyType, ValueType, HashFunctionToUse, TypeOfCriticalSectionToUse>::HashMap(const juce::HashMap<KeyType, ValueType, HashFunctionToUse, TypeOfCriticalSectionToUse>&) [with KeyType = juce::String, ValueType = bool (HandlerBase::*)(BazCommand&), HashFunctionToUse = juce::DefaultHashFunctions, TypeOfCriticalSectionToUse = juce::DummyCriticalSection, juce::HashMap<KeyType, ValueType, HashFunctionToUse, TypeOfCriticalSectionToUse> = juce::HashMap<juce::String, bool (HandlerBase::*)(BazCommand&)>]’ is private
 FoomaticHandler.cpp:77:16: error: within this context

What is the right way to create such a static string -> member function mappings? And can the createCmdList() be made pure virtual to enforce implementation?

Inductiveload
  • 6,094
  • 4
  • 29
  • 55
  • You don't seem to have any definition for packetHandler, and you use concepts in FoomaticHandler that are defined in HandlerBase even though you don't inherit from it. Try looking at std::function for way to bind up your method calls in a standard way. – woolstar Nov 22 '13 at 18:15
  • Sorry, that's just clumsy code reduction. I'll look at `std::function`. – Inductiveload Nov 22 '13 at 18:18

0 Answers0