-
Notifications
You must be signed in to change notification settings - Fork 21
Description
It would be nice if there was some interface that allowed the engine and the drivers to inform the user about various errors and perhaps could be used for debug info during development. Ideally the user application should be able to intercept these log messages, so that they could be shown in a PGE console or something like that.
We could get away with passing an ostream reference to the engine and then writing to it, but that complicates intercepting messages, as it makes it hard to know where a particular message ends. For this reason, I think it would be better to follow the printf/std::format approach.
I propose to add an interface called LogListener with just one member function:
void LogListener::OnMessage(int level, const std::string_view& msg);The level argument would represent different log levels (error, info, debug, etc), and the msg would be the final message that the user receives. The default implementation would just dump the message to std::cout or std:cerr based on the level.
Since performance may be critical here, it should be possible to prevent unimportant messages from being considered at all. This will have to be done with macros, since I don't think there's any other way to prevent arguments from being evaluated.
Right now, I think that logging should look like this:
// in drivers
SWE_DRV_LOG_ERROR("Failed to initialize the backend: blah blah blah");
// in the other parts of the engine
SWE_ENG_LOG_ERROR("Oh no, the driver crashed");The necessity of different macro names for different parts of the engine is explained by the need to be able to find the engine's pointer to the LogListener implementation. It will most probably be stored in the WaveEngine class, so the drivers will need to refer to their pHost member, while the engine itself could use this.
I suppose we could just add a "get log listener" function everywhere that would return the currently used listener, but I'm not sure if that's a good way to approach this.
The macro arguments could be passed to snprintf or std::format before being sent to the listener, depending on whether we want to use C++20 features or not.
I'm really interested to hear your opinions. If you've got some ideas, please share.