我想创建一个游戏引擎作为培训和投资组合项目,模块化方法听起来很有前途,但我在模块设计方面遇到了一些问题。
首先,我想创建低级模块,如渲染、应用程序、实用程序等,然后在 Terrain 等高级模块中使用它们。 所以依赖关系看起来像这样 Game<-Engine<-Terrain<-Rendering.
我想创建多个渲染“子模块”,如 Rendering.Direct3D11 和 Rendering.OpenGL。那就是我会有循环依赖的地方。子模块会使用 Rendering 接口(interface),Rendering 需要管理子模块,对吧? 游戏<-引擎<-地形<-渲染<-->渲染.Direct3D11
我或许可以创建一个像 RenderingInterfaces 这样的模块并打破循环依赖,但这似乎是一个棘手的解决方法。我打算多次使用“子模块设计”,例如: 游戏<-引擎<-应用程序<-->Application.Windows
子模块设计丑吗?有没有办法使用没有循环依赖的子模块设计?
最佳答案
你可以抽象地解决这个问题。假设您有三个动态库:Game.dll
、Renderer.dll
、SubRenderer.dll
。
渲染器界面可能看起来像这样(简化):
// Renderer.h
class SubRenderer
{
public:
virtual ~SubRenderer() {}
virtual void render() = 0;
};
class API Renderer
{
public:
explicit Renderer(SubRenderer* sub_renderer);
void render();
private:
SubRenderer* sub_renderer;
};
你可以把它放在 Renderer.h
或类似的东西中,Renderer 构造函数和 render
方法可以在 Renderer.cpp
中实现> 您将其包含在输出 Renderer.dll
的项目中。
现在在 SubRenderer.dll
中,您可能有这样一个函数:
// SubRenderer.h
class SubRenderer;
API SubRenderer* create_opengl_renderer();
这可以在 SubRenderer.cpp
中实现,它被编译/链接到输出 `SubRenderer.dll。它可能看起来像这样:
// SubRenderer.cpp
#include "SubRenderer.h"
#include <Renderer.h>
class OpenGlRenderer: public SubRenderer
{
public:
virtual void render() override {...}
};
SubRenderer* create_opengl_renderer()
{
return new OpenGlRenderer;
}
最后但同样重要的是,在 Game.dll 的某些源文件中,您可以在某些 Game.cpp
中执行类似的操作:
// Game.cpp
#include <Renderer.h>
#include <SubRenderer.h>
int main()
{
SubRenderer* opengl_renderer = create_opengl_renderer();
Renderer renderer(opengl_renderer);
renderer.render(); // render a frame
...
delete opengl_renderer;
}
...当然希望有符合 RAII 的更安全的设计。
对于这种系统,您有这些 header 依赖项:
`Game.cpp->Renderer.h`
`Game.cpp->SubRenderer.h`
`SubRenderer.cpp->Renderer.h`
在模块依赖方面:
`Game.dll->Renderer.dll`
`Game.dll->SubRenderer.dll`
就是这样——任何地方都没有循环依赖。 Game.dll
依赖于Renderer.dll
和SubRenderer.dll
,但是Renderer.dll
和SubRenderer .dll
完全相互独立。
这是可行的,因为这个 Renderer
可以使用给定其虚拟接口(interface)的 SubRenderer
而不知道它到底是什么(因此不需要依赖于具体类型的“子渲染器” ').
您可以将 Renderer.h
放在可以从所有三个项目集中访问的位置,这些项目具有共同的包含路径(例如:在 SDK
目录中)。无需复制。
关于c++ - 模块化游戏引擎 : DLL circular dependencies,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33630692/