Developing a Vectorworks 2011 tool plug-in, TDD-style – Episode 2

With a basic mock implementation of the tool point collecting part of a Vectorworks tool under our belt, let’s try to connect this class to a “real” Vectorworks tool event sink.

Using the MockRedGreenLineTool from within a CTool_EventSink doesn’t sound quite right. After all it’s supposed to be a mock implementation. We need to use a real tool implementation in the CTool_EventSink. Let’s do some restructuring to accomplish that. First, create a new class RedGreenLineTool with the code from MockRedGreenLineTool.

class RedGreenLineTool {
	virtual ~RedGreenLineTool() {

 	void AddPoint(const WorldPt3& p) {

	virtual void PopPoint() {

	short GetNumToolPoints() const {
		return fToolPoints.NumItems();
	TSmallArray<WorldPt3> fToolPoints;


Now, make MockRedGreenLineTool a subclass of RedGreenLineTool:

class MockRedGreenLineTool : public RedGreenLineTool {

and create VectorworksRedGreenLineTool, which is also a subclass of RedGreenLineTool.

class VectorworksRedGreenLineTool : public RedGreenLineTool {

This sure looks better to our TDD newbie eye. We have a common implementation for both the MockRedGreenLineTool used for testing and a VectorworksRedGreenLineTool used to connect the code to Vectorworks. Running the tests shows we didn’t break anything. Now we are able to use VectorworksRedGreenLineTool in a VWToolDefaultLine_EventSink implementation:

long CTool_EventSink::LegacyMain(long action, long message1, long message2)
	long result = 0;
	switch (action) {

		case kToolDoSetup:
			result = VWToolDefaultLine_EventSink::LegacyMain(action, message1, message2);
			fRedGreenLineTool = new VectorworksRedGreenLineTool();
		case kToolDoSetDown:
			result = VWToolDefaultLine_EventSink::LegacyMain(action, message1, message2);

			if (fRedGreenLineTool)
				delete fRedGreenLineTool;
			fRedGreenLineTool = NULL;
		case kToolPointAdded: {

			WorldPt3 toolPoint;
			if (gSDK->GetToolPt3D(gSDK->GetNumToolPts() - 1, toolPoint))
		case kToolPointRemoved:
			result = VWToolDefaultLine_EventSink::LegacyMain(action, message1, message2);

	return result;

Using the debugger, we are able to verify that everything is working out as expected.

Not a lot of functional but structural code changes in this episode, but we ended up with a class hierarchy which hints at things to come. We expect to push code common between the mock and Vectorworks implementation of the tool up the class hierarchy and code specific to the mock or Vectorworks implementation of the tool in the subclasses.

Let’s see how this class hierarchy holds up in the next episode when we tackle creating a line – test first, of course.

Previous Episode | Next Episode