Skip to content

Advanced Replacement Tags

Giorgioggì edited this page Jan 8, 2021 · 3 revisions

Sometimes you feel the need to use the same replacement functions for different tags. For instance, in my SmartStrip project I have a function that returns whether a relay is ON or OFF. I have 4 relays though, whose state is kept in a singel array, and I'd rather avoid having to write a different replacement function for every relay, since they would all look the same and just access a different element of the array. Wouldn't it be great if I could pass the relay number to the replacement function?

Yes, and Webbino does support this, in fact. The EasyReplacementTag macro has an optional fourth argument which is a a void pointer. Whatever you put there will be passed as the single argument of the replacement function, which you might have noticed was totally unused in the ReplacementTags example.

Code

This code is taken from SmartStrip:

EasyReplacementTag (tagRelay1Status, RELAY1_ST, evaluate_relay_status, reinterpret_cast<void *> (1));
EasyReplacementTag (tagRelay2Status, RELAY2_ST, evaluate_relay_status, reinterpret_cast<void *> (2));
EasyReplacementTag (tagRelay3Status, RELAY3_ST, evaluate_relay_status, reinterpret_cast<void *> (3));
EasyReplacementTag (tagRelay4Status, RELAY4_ST, evaluate_relay_status, reinterpret_cast<void *> (4));

As you can see, we associate the same replacement function to different tags, each one with a different fourth argument. Here we explicitly cast it to void *, but this is often unnecessary.

The actual function looks like this:

PString& evaluate_relay_status (void *data) {
	int relayNo = reinterpret_cast<int> (data);
	if (relayNo >= 1 && relayNo <= RELAYS_NO) {
		if (relays[relayNo - 1].enabled) {
			pBuffer.print (F("ON"));
		} else {
			pBuffer.print (F("OFF"));
		}
	}

	return pBuffer;
}

The first thing we do is recast the void pointer to the correct type. We know we passed integers, so we can just transform it into an int. So now we know what relay we should check the state of, and in the rest of the code we can access the corresponding array element.