Jump to content
  • Advertisement
Sign in to follow this  
Jiia

Namespaces in classes

This topic is 4988 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hehe, you're really going out on a limb to help me, and I really appreciate it. I still don't think my problem is coming out very clear. I'll try to give a really good example of the exact situation I want to clean up..


class MegaBadDesign
{
public:

// Z Buffer
void ToggleZBuffer(bool toggle);
void SetZBufferRes(float res);
void SetZBufferDepth(float depth);
void InvertZBuffer();
void FlipZBuffer();

// Stencil
void ToggleStencil(bool toggle);
void SetStencilMask(int value);
void InvertStencil();
void FlipStencil();

// Techniques
void StartTech(HANDLE tech);
void StopTech();
void LockTech();
void UnlockTech();
bool CheckTech(HANDLE tech);

// Lighting
void SetLightDir(int index, const vector &dir);
void SetLightAmp(int index, FLOAT amp);
void SetLightColor(int index, color value);
void SetShaderDir(int index, const vector &dir);
void SetShaderAmp(int index, FLOAT amp);
void SetShaderColor(int index, color value);

// Streams
void SetStream(stream *s);
bool CheckStream(const stream *s);

private:

APIShaderObject m_Thing;
};



This is still just a taste, but hopefully it's pointing in the right direction. My opinion, this would be a cleaner way to name the z buffer section:


...
// Z Buffer
void ZBuffer_Toggle(bool toggle);
void ZBuffer_SetRes(float res);
void ZBuffer_SetDepth(float depth);
void ZBuffer_Invert();
void ZBuffer_Flip();
...





As you can see, this class just needs to manipulate the APIShaderObject interface, and perhaps do some error checking or logging. There's just a lot of functions dealing with a small amount of data.

As an example of how prefixing can help organize a mass of interface functions, let's look at the IDirect3DDevice9 interface..

BeginScene
BeginStateBlock
Clear
ColorFill
CreateAdditionalSwapChain
CreateCubeTexture
CreateDepthStencilSurface
CreateIndexBuffer
CreateOffscreenPlainSurface
CreatePixelShader
CreateQuery
CreateRenderTarget
CreateStateBlock
CreateTexture
CreateVertexBuffer
CreateVertexDeclaration
CreateVertexShader
CreateVolumeTexture
DeletePatch
DrawIndexedPrimitive
DrawIndexedPrimitiveUP
DrawPrimitive
DrawPrimitiveUP
DrawRectPatch
DrawTriPatch
EndScene
EndStateBlock
EvictManagedResources
GetAvailableTextureMem
GetBackBuffer
GetClipPlane
GetClipStatus
GetCreationParameters
GetCurrentTexturePalette
GetDepthStencilSurface
GetDeviceCaps
GetDirect3D
GetDisplayMode
GetFrontBufferData
GetFVF
GetGammaRamp
GetIndices
GetLight
GetLightEnable
GetMaterial
GetNPatchMode
GetNumberOfSwapChains
GetPaletteEntries
GetPixelShader
GetPixelShaderConstantB
GetPixelShaderConstantF
GetPixelShaderConstantI
GetRasterStatus
GetRenderState
GetRenderTarget
GetRenderTargetData
GetSamplerState
GetScissorRect
GetSoftwareVertexProcessing
GetStreamSource
GetStreamSourceFreq
GetSwapChain
GetTexture
GetTextureStageState
GetTransform
GetVertexDeclaration
GetVertexShader
GetVertexShaderConstantB
GetVertexShaderConstantF
GetVertexShaderConstantI
GetViewport
LightEnable
MultiplyTransform
Present
ProcessVertices
Reset
SetClipPlane
SetClipStatus
SetCurrentTexturePalette
SetCursorPosition
SetCursorProperties
SetDepthStencilSurface
SetDialogBoxMode
SetFVF
SetGammaRamp
SetIndices
SetLight
SetMaterial
SetNPatchMode
SetPaletteEntries
SetPixelShader
SetPixelShaderConstantB
SetPixelShaderConstantF
SetPixelShaderConstantI
SetRenderState
SetRenderTarget
SetSamplerState
SetScissorRect
SetSoftwareVertexProcessing
SetStreamSource
SetStreamSourceFreq
SetTexture
SetTextureStageState
SetTransform
SetVertexDeclaration
SetVertexShader
SetVertexShaderConstantB
SetVertexShaderConstantF
SetVertexShaderConstantI
SetViewport
ShowCursor
StretchRect
TestCooperativeLevel
UpdateSurface
UpdateTexture
ValidateDevice




A lot of functions dealing with render states. Quite a few pixel shaders, and vertex shaders. Stream sources, textures, and specific buffers. Good luck trying to sort it out as you code. You need a reference for this.

I also do not like jumping to header files every time I need to access a specific object or perform a specific task. I just like to use the IDE tools to speed the process up. With this type of setup, that's not even a question to be considered.

Share this post


Link to post
Share on other sites
Advertisement
Well I'm pretty much out of ideas with regards to directly emulating namespaces.

As for the MegaBadDesign example, I'd deal with that by seperating it out into subclasses (honest to gosh seperate ones). It does require a decent bit of support framework, but that's just typing, and at my ~80WPM I spend much more time thinking about my design(s) than I spend typing.

Share this post


Link to post
Share on other sites
As the OP has designed his system, all these responsibilities belong to this class, so there's no point hacking around trying to seperate them into different classes from the few scraps of the design we've been given. Doing this properly would require redefining what the class itself is, so it doesn't have all these responsibilities to begin with. Right now it is aware of every operation that has to be performed on it. Changing this requires changing the way in which these operations are performed, and hence the way in which all other classes which are aware of it interact with it, which looks like it'll be pretty much everything (which is one of the problems of low cohesion incidentally).

Share this post


Link to post
Share on other sites
Your solution is as good as it gets, as far as I can imagine. I just think the change is really big compared to the goal.

I totally agree that dividing the tasks up is a great way to simplify and organize. But in my case, it's just the function list that I want to divide. I don't want seperate objects.

For what it's worth, I didn't really expect anyone to invent a solution to the problem. I was just curious to know if there was already such a thing being used.

edit @ Nemesis2k2: What you see is what you get. There's no hidden part of the design that's going to change your perspective. Compare it to the Direct3D device. It's an object (a human being) who has a lot of branches in functionality. It already contains a lot of classes seperating that functionality. But so does the Direct3D device. Yet, look at it's interface. I would hate to see it's private task list, as that is what is huge on my character class.

Share this post


Link to post
Share on other sites
Quote:
edit @ Nemesis2k2: What you see is what you get. There's no hidden part of the design that's going to change your perspective. Compare it to the Direct3D device. It's an object (a human being) who has a lot of branches in functionality. It already contains a lot of classes seperating that functionality. But so does the Direct3D device. Yet, look at it's interface. I would hate to see it's private task list, as that is what is huge on my character class.

There is still a lot of vital documentation to understanding the overall design of your system that is not in this thread, but at any rate, there are many different ways to design a system to solve a given problem, especially one as complex as this. For example, my engine has a Renderer base class, through which any portion of the scene can be rendered. The Renderer itself currently has only 5 functions in its public interface, and as the system has been designed, that is sufficient in order to:

-Assign a rendering target
-Sort all renderable assets
-Mask out "categories" of renderable assets (categories are used to classify resources, to allow discriminate rendering, such as not rendering reflections within reflections, using lower detail objects for a perticular view, etc etc)
-Generate any volatile resources that must be created first. Eg, a reflection texture.
-Lock certain material states to specified values (eg, force everything to render in wireframe)
-Render the scene on demand; either selected portions or in its entirety
-Clear the list of assets to be rendered, in order to reuse the object for another rendering task

Achieving such low coupling however requires first of all aiming for it as a design objective, and it needs to be pervasive throughout the architecture of your system. IMO, it is something worth aiming for. The end result is easier to understand for people using your system, it's easier to maintain, and it's more resiliant to future changes. Build your systems however you like of course, but I do recommend when you approach systems in the future, you think of ways to minimize coupling from the outset. Just some constructive feedback.

Share this post


Link to post
Share on other sites
In general, I use a lot of functions. I seperate medium tasks into several smaller tasks. I find it much easier to flow through code this way. The public interface of my character class is virtually non-existent. It's derived from a map based object class, and most of the game engine doesn't even interact specifically with characters (small exceptions, like menu routines working with inventory lists). It's the private section that is complex. The number of data members is lower than ten, but the number of functions in the private area is mega huge. This is the problem area. The inner functionality of my characters is becoming very complex.

I might be way off, but I don't see how low coupling strategy is going to help. The private tasks all work with the same small amount of data. They just do a very wide range of things with it. They are coupled in their origin, not by design.

Share this post


Link to post
Share on other sites
It sounds like the best solution in C++ would be to create friend classes that only contain methods and are passed a pointer to the master character class.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!