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
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;
...
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)
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++.