How to pass debug option to multiple classes?

professionally, we had a 32-bit (or larger) debug flags and used each bit to enable debug in various modules.

in a java application, i'm creating either global dbg variables for an entire class or a dbg variable within a function. Of course a class can use a dbg flag with bit fields to enable various debugging

what is a common way for enabling debugging within various classes from some global context (e.g. main())?

if you want that at run time, it could be a global variable that is made available to everyone (declared extern in a global.h file that is imported by all modules)

if this is something static that you set at compile time, it could be passed when you compile with a -D option on the compile line for each module

ie if you have

-DDEBUG_FLAG=0xF0F0F0F0

on the compile line, you can do in the code things like

#ifdef DEBUG_FLAG // not really needed if you provided a default value
// Your code here
#endif

and to provide a default value, at the very beginning of each compile unit you could have

#ifndef DEBUG_FLAG
#define DEBUG_FLAG 0x00000000 // default value
#endif

just in case the -D option was not passed at compile time.


in typical environment where you manage a makefile, you would be able to make debug and your make file would have a debug target where you set the DEBUG_FLAG

debug:
    g++ -g -DDEBUG_FLAG= 0xF0F0F0F0 your_file.cpp -o your_executable_debug

yes, and thanks. i could use a #define, but am asking about using a variable that can be changed at run-time, in particular in a java application (yes i know this is an arduino forum, but applies to Arduino applications using multiple classes)

a global could be used, but then, as you mentioned, there needs to be an extern reference and it needs to be defined somewhere. not a big deal, but not what i was trying to ask

i am defining a dbg variable locally both global within a class as well as local to a function. I'm looking for "conventional approaches" for setting a dbg variable within a class. The only way i can think of, perhaps obvious, is to have a method within the class for setting the flag. That method would be invoked from some higher level function that monitors keypresses into the application and would invoke the methods for setting the dbg value.

but an obvious problem is are multiple input "keys" needed, one to set the dbg for each class or is there some more common approach

as i said, professionally we uses a 32-bit dbg variable and am curiosu how others may have done this to debug GUI applications

I'm assuming all instances of the class would share the same debug variable ➜ class instance variable
if you make it public you don't need the setters and getters methods

public class MyClass {
    // Public static variable shared by all instances
    public static int dbg = 0;
...

access that with MyClass.dbg

(not sure I understood the question correctly)

yes, but there are several classes, each with it's own dbg variable

so from from interface (e.g. keyboard, mouse) how would you set/manage the dbg state for ClassA, ClassB, ...

does the keyboard or mouse represent one or two bits each from the dbg variable or does the keyboard dbg variable is fully separated from the mouse dbg variable?

if the dbg variable is shared amongst "stuffs" then it can't be a class variable of each stuff, it's a global singleton and everyone can access the dbg instance

is having a dbgSet() method really the most appropriate approach?

from a gui, there could be a menu to set one of multiple dbg options. from a keyboard, a preceding numeric value could distinguish dbg flags for different option. but the interface is not the question, it's how to pass it to the class

create a debug class. each time you want a debug variable (local or global) get an instance of the class and have the class maintain a list of all the instances.

in the constructor you pass parameters describing what the instance is for and you provide some methods to play with the flag

you could make that more user friendly by adding some other class that is a DebugBitfield description which identify a bit or a range of bits with a name and the DebugVariable class would hold a list of the active DebugBitfields for this DebugVariable

import java.util.ArrayList;
import java.util.List;

public class DebugBitfield {
    private String name;
    private byte startBit;
    private byte endBit;

    public DebugBitfield(String name, byte startBit, byte endBit) {
        this.name = name;
        this.startBit = startBit;
        this.endBit = endBit;
    }

    public String getName() { return name; }
    public byte getStartBit() { return startBit; }
    public byte getEndBit() { return endBit; }

    public void setName(String name) { this.name = name; }
    public void setStartBit(byte startBit) { this.startBit = startBit; }
    public void setEndBit(byte endBit) { this.endBit = endBit; }
}


public class DebugVariable {
    private static List<DebugVariable> instances = new ArrayList<>();
    private String description;
    private int debugFlag;
    private List<DebugBitfield> bitfields;

    public DebugVariable(String description) {
        this.description = description;
        instances.add(this);
        bitfields = new ArrayList<>();
    }

    public String getDescription() { return description; }

    public int getDebugFlag() { return debugFlag; }
    public void setDebugFlag(int debugFlag) { this.debugFlag = debugFlag; }

    public boolean isBitSet(int bitPosition) { return (debugFlag & (1 << bitPosition)) != 0; }
    public void setBit(int bitPosition) { debugFlag |= (1 << bitPosition); }
    public void clearBit(int bitPosition) { debugFlag &= ~(1 << bitPosition); }

    public void addDebugBitfield(DebugBitfield bitfield) {bitfields.add(bitfield);}
    public List<DebugBitfield> getDebugBitfields() {return bitfields;}

    public static int getNumberOfInstances() { return instances.size(); }
    public static List<DebugVariable> getAllInstances() { return instances; }
}

you could instantiate 3 DebugVariable instances for example

public class Main {
    public static void main(String[] args) {
        // Creating DebugVariable instances
        DebugVariable keyboard = new DebugVariable("Keyboard");
        DebugVariable mouse = new DebugVariable("Mouse");
        DebugVariable screen = new DebugVariable("Screen");

        // Adding DebugBitfield ranges for Keyboard
        keyboard.addDebugBitfield(new DebugBitfield("dbgLevel", (byte)0, (byte)3));
        keyboard.addDebugBitfield(new DebugBitfield("KDB1", (byte)4, (byte)4));
        keyboard.addDebugBitfield(new DebugBitfield("KBD2", (byte)5, (byte)5));

        // Adding DebugBitfield range for Mouse
        mouse.addDebugBitfield(new DebugBitfield("dbgLevel", (byte)0, (byte)3));

        // Adding DebugBitfield ranges for Screen
        screen.addDebugBitfield(new DebugBitfield("dbgLevel", (byte)0, (byte)3));
        screen.addDebugBitfield(new DebugBitfield("SCREEN1", (byte)4, (byte)8));
    }
}

(here done in main but could be done in your devices constructors)

Then you could build dynamically a UI to modify all the flags as you can ask for the list of all the DebugVariable instances and for each show their description and the bits fields of interest

(all typed here so I don't claim it's proper Java code... did not try it at all)

thanks
sorry if i'm not clear enough

In C++ you could probably also do it by making all classes inherit from, say Debuggable or Loggable, and there you would have a method to control what is collected/output which you could call from a controller. But Java inheritance, as far as I remember, is not so flexible as C++.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.