Just a quick question. I have implemented tools in my editor like Create, Translate, Rotate and Scale. To do this, I've used a structure for each tool, which contains function pointers to each of the tool's functions, like Initialize, MouseDown and Draw. Changing the current tool just requires switching a tool pointer to the right tool structure. Each tool has it's own header and implementation file, which contains the function definitions and the functions themselves, along with any auxiliary functions. It recently occurred to me that they would probably be better as classes, because their variables are not private, and I only want to expose certain functions, as mentioned above.
So, should I create a CTool class, with virtual functions for Initialize, MouseDown, Draw, etc., then derive all my tool classes from that? Then I could override the virtual functions to provide the tool's functionality, correct? So say I do that, and create a CTranslateTool class. Can my global tool variable just be of type CTool? Also, does this seem to be the best way to implement tools? I'm not sure of either method, so I guess I'll have to try and come up with a solution that's better, if I can. I should probably mention that C is my language, and I'm still in the process of learning C++ and OOP. Anyway, thanks in advance for any replies...guess it wasn't so quick after all, eh?
Windows 95 - 32 bit extensions and a graphical shell for a 16 bit patch
to an 8 bit operating system originally coded for a 4 bit microprocessor,
written by a 2 bit company that can't stand 1 bit of competition.
[edited by - iNsAn1tY on February 27, 2004 5:13:39 PM]
Implementing tools as classes...
Your idea has merit, I dont know if I would say it is the perfect design, but it is definitely a good start towards enhancing your C++ skills.
A suggestion (of untested merit): Instead of making each tool do it''s own interface, define a standard way for a tool to ask for inputs, and then have the framework deal with extracting that info from the user.
For example, for Translate, you need an object and a position. The tool class just has to set the object''s position to the given position. It might be a little more work upfront, but I''d say it''d be worth it overall if you''re going to have more than three tools... at least, if I were writing a modeller (which I nearly did but instead tried to learn blender, which sucked out my mind and left me not wanting to model at all for two years) then that is what I''d do.
For example, for Translate, you need an object and a position. The tool class just has to set the object''s position to the given position. It might be a little more work upfront, but I''d say it''d be worth it overall if you''re going to have more than three tools... at least, if I were writing a modeller (which I nearly did but instead tried to learn blender, which sucked out my mind and left me not wanting to model at all for two years) then that is what I''d do.
OK, I''m annoyed now. Coding the tools is simple, but it''s figuring out the architecture that''s a bitch. I have several different types of object: brushes, entities, paths, etc. They can all be selected, translated, rotated and scaled, (like in 3DS Max) but I''m at a loss as to how I''d code this. Individual object types also have specialist tools which only operate on them (paths have a tool which allows you to move the control points for the beziers). How should I go about coding this? I swear, it''s driving me nuts, and I''ve been working on this for so long, and nothing ever seems to go right, and it''s really getting on my nerves. It''s come on in leaps and bounds recently, but i had to change the architecture to accommodate entities, paths, etc. and it''s just gone wrong. If I can finish it, it will be an excellent tool for creating 3D worlds (I already created so pretty decent stuff with the old brush-only version), but this problem''s really got me...
Windows 95 - 32 bit extensions and a graphical shell for a 16 bit patch
to an 8 bit operating system originally coded for a 4 bit microprocessor,
written by a 2 bit company that can''t stand 1 bit of competition.
Windows 95 - 32 bit extensions and a graphical shell for a 16 bit patch
to an 8 bit operating system originally coded for a 4 bit microprocessor,
written by a 2 bit company that can''t stand 1 bit of competition.
It is indeed a tricky problem, one which I bumped into frequently in V-Script. I currently use a system with a generic EditorMode interface. This basically receives mouse events and has hooks into the engine at various points (the most used being the one that lets them render arbitrary overlays - good for drag handles etc.).
Each EditorMode then becomes a single functioning unit, perhaps broken up into smaller chunks. These sub-modes have almost exactly the same interface (minus a couple of icon/name type stuff). This means I can have a generic Geometry mode, and sub modes for creating, moving and colouring the actual geometry.
Alongside that I found what works best is a generic set of controls. Almost a default mode as it were. And events that are passed to the modes are either handled or not, and if indicated that its not handled (function returns false) it gets passed on to the default mode. This way things like scrolling and selection work in all modes.
Just one possible way. Works well for me after trying several different methods
[S-Type] [V-Script]
Each EditorMode then becomes a single functioning unit, perhaps broken up into smaller chunks. These sub-modes have almost exactly the same interface (minus a couple of icon/name type stuff). This means I can have a generic Geometry mode, and sub modes for creating, moving and colouring the actual geometry.
Alongside that I found what works best is a generic set of controls. Almost a default mode as it were. And events that are passed to the modes are either handled or not, and if indicated that its not handled (function returns false) it gets passed on to the default mode. This way things like scrolling and selection work in all modes.
Just one possible way. Works well for me after trying several different methods
[S-Type] [V-Script]
well to answer one of your questions in c++ you can create a base class that has an instance of subclass without problems. It only gets tricky when the subclass has functions your trying to call that don''t exist in the base class.
So Tool* myTool = TranslateTool();
would work fine as long as TranslateTool is a subclass of tool.
as for handling tools I would suggest creating an abstract base class which all tools are derived from. As well as create a tool handler class which will handle all the communications between tools and the main program.
So you would have:
class Tool
class Translate : Tool
class Create : Tool
class Rotate : Tool
class Scale : Tool
class ToolHandler
In your main program you would pass the messages to ToolHandler.
With calls like this:
ToolHandler.translate();
which would then call that function in ToolHandler and set the current tool to translate.
The other messages, intialize, mouseDown, and draw would be passed to ToolHandler in the same way, then tool handler would do the appropreite work and make the calls to current tool.
as for the diffrent objects there are a couple of ways to handle this one is to simply create overload functions for each object.
so in ToolHandler you would have:
mouseDown(Brush);
mouseDown(Path);
mouseDown(Entity);
...
ToolHandler would call the function corresponding to the object passed to it and do any needed work.
as for specilized tools treat those like another tool expect that toolHandler simply ignores sany attempt to use them be an inapprorite object.
hope that helps.
-----------------------------------------------------
Writer, Programer, Cook, I''m a Jack of all Trades
Current Design project
Chaos Factor Design Document
So Tool* myTool = TranslateTool();
would work fine as long as TranslateTool is a subclass of tool.
as for handling tools I would suggest creating an abstract base class which all tools are derived from. As well as create a tool handler class which will handle all the communications between tools and the main program.
So you would have:
class Tool
class Translate : Tool
class Create : Tool
class Rotate : Tool
class Scale : Tool
class ToolHandler
In your main program you would pass the messages to ToolHandler.
With calls like this:
ToolHandler.translate();
which would then call that function in ToolHandler and set the current tool to translate.
The other messages, intialize, mouseDown, and draw would be passed to ToolHandler in the same way, then tool handler would do the appropreite work and make the calls to current tool.
as for the diffrent objects there are a couple of ways to handle this one is to simply create overload functions for each object.
so in ToolHandler you would have:
mouseDown(Brush);
mouseDown(Path);
mouseDown(Entity);
...
ToolHandler would call the function corresponding to the object passed to it and do any needed work.
as for specilized tools treat those like another tool expect that toolHandler simply ignores sany attempt to use them be an inapprorite object.
hope that helps.
-----------------------------------------------------
Writer, Programer, Cook, I''m a Jack of all Trades
Current Design project
Chaos Factor Design Document
OK, so I thought about a solution to this problem, taking into account your helpful posts. I''m going to create each tool as a class. I''m also going to make all my objects classes. There will be a set of functions built into a base class, all of which will be virtual. Overriding them will give the functionality of the basic tools: Translate, Rotate and Scale. If the object does not override them, the default action is to do nothing. Other tools, such as Vertex Drag for brushes, will be specially implemented to check which types of object are currently stored in the selection pointer list (I save a reference to selected objects in a CPtrList, which is efficent) so they don''t crash the system, and I can build serialization into each object class too (which is fancy, as I can just pass the CArchive to each object and it will write itself to disk). If the current selection is not suitable for the tool, the user will be informed (if an entity is selected, and they try to use Vertex Drag, it will tell them they can only do this on a brush, for instance). Selection will become more global (it was previously just a tool). This way I can add other stuff like an object for the skybox (only one per map) and perhaps for animating models, and stuff like that.
Windows 95 - 32 bit extensions and a graphical shell for a 16 bit patch
to an 8 bit operating system originally coded for a 4 bit microprocessor,
written by a 2 bit company that can''t stand 1 bit of competition.
Windows 95 - 32 bit extensions and a graphical shell for a 16 bit patch
to an 8 bit operating system originally coded for a 4 bit microprocessor,
written by a 2 bit company that can''t stand 1 bit of competition.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement