2

Following situation:

My system gets an hardware signal and writes a time value to a buffer in my signal handler routine. Afterwards a (software) signal is sent with the time value as argument to the appropriate slot function. The slot routine gets called correctly, but here my problem lays in:

In the slot function I have a simple switch-case statement like this:

switch(id) {
    case 1:
        do something..
        id = 2;
        break;

    case 2:
        start_time = val;
        id = 3;
        break;

    case 3:
        end_time = val;
        id = 1;
        break;
}

In those three cases I store a start and end time value between case 2 and 3 and out of those time values I determine the elapsed time between the hardware signals. This works fine, but now I have to measure the time sometimes "longer", depening on parameter. This means, I can't stop the measurement at case 3 instead I have case 4, 5, 6 and so on . What is an elegant and optimal solution for this "problem" instead of writing:

if (param < xy) {
    switch(id) {
        case 1:
            ...
            break;
        case 2:
            ...
            break;
    } else if (param > xy) {
        switch(id) {
            case 1:
                ...;
                break;

           case 2:
                ...;
                break;

           case 3:
                ...;
                break;

           case 4:
                ...;
                break;

           case 5:
                ...;
                break;
        }
    }
}
arge
  • 635
  • 1
  • 7
  • 16
  • Does the code also change, say with `case 1`? Or no matter which if-else block it goes, the code in common cases is exactly same? – Nawaz Sep 12 '11 at 16:16
  • cant you use link list funda & avoid this type of logic – Jeegar Patel Sep 12 '11 at 16:17
  • @ Nawaz, no the code in the case doesn't change it's always the same, depening on the if-else block sometimes there are 3 cases or more... – arge Sep 12 '11 at 16:26
  • Since you like to think in terms of signals and slots, Qt has a state machine library which you might want to check out: http://doc.qt.nokia.com/latest/statemachine-api.html – spraff Sep 12 '11 at 16:30

4 Answers4

4

What you are describing is called a finite state machine there are a large number of excellent state machine libraries out there that will take care of the heavy lifting for you.

Take a look at this question and some of the others that it references.

Community
  • 1
  • 1
joshperry
  • 41,167
  • 16
  • 88
  • 103
2

You can try following:

switch ((param - xy) >= 0 ? id : -id) {
    // param >= xy cases
    case 1:
        ...
        break;
    case 2:
        ...
        break;
    ...
    // param < xy cases
    case -1:
        ...
        break;
    case -2:
        ...
        break;
    ...
}
qrdl
  • 34,062
  • 14
  • 56
  • 86
0

Or for something fun an exciting, you could write some self modifying code to dynamically change your swithc jump table as the parameters it receives differ. You'd have to allocate a large enough area for the largest table size and play around with funciton pointers or assembler, but it could be done.

Michael Dorgan
  • 12,453
  • 3
  • 31
  • 61
0

Try using a std::map of function pointers, a.k.a. jump table, rather than a switch statement. The map allows flexibility during run-time.

Store a pointer to the function, along with the case value. Search the map for the case value, retrieve the pointer and dereference to call the function.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154