Skip to content

Commit 9a5f260

Browse files
authored
Merge pull request #158 from skylicht-lab/features/ecs-system-for-gui
2 parents 59db56c + 3aecc71 commit 9a5f260

File tree

33 files changed

+807
-344
lines changed

33 files changed

+807
-344
lines changed

BuildCommand/GenerateVCPrj2022.cmd

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
cd ..
2+
cd Assets
3+
python BuildAssetBundles.py
4+
cd ..
5+
cmake -S . -B ./PrjVisualStudio -G "Visual Studio 17 2022" -A x64

Projects/Skylicht/Engine/Source/Graphics2D/CCanvas.cpp

Lines changed: 68 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ This file is part of the "Skylicht Engine".
2626
#include "CCanvas.h"
2727
#include "Graphics2D/CGraphics2D.h"
2828

29+
#include "GUISystem/CGUILayoutSystem.h"
30+
2931
namespace Skylicht
3032
{
3133
CCanvas::CCanvas() :
@@ -44,7 +46,13 @@ namespace Skylicht
4446

4547
// add root
4648
m_root = new CGUIElement(this, NULL, m_rect);
47-
m_root->setDock(CGUIElement::DockFill);
49+
m_root->setDock(EGUIDock::DockFill);
50+
51+
m_systems.push_back(new CGUILayoutSystem());
52+
for (IEntitySystem* system : m_systems)
53+
{
54+
system->init(NULL);
55+
}
4856

4957
// add this canvas
5058
CGraphics2D::getInstance()->addCanvas(this);
@@ -69,19 +77,72 @@ namespace Skylicht
6977
{
7078
}
7179

72-
void CCanvas::layout()
80+
void CCanvas::onResize()
7381
{
7482
// layout on 2d ui
7583
if (m_renderCamera->getProjectionType() == CCamera::OrthoUI)
7684
{
7785
// get current screen size
7886
CGraphics2D* g = CGraphics2D::getInstance();
79-
float w = (float)g->getScreenSize().Width;
80-
float h = (float)g->getScreenSize().Height;
87+
core::dimension2du s = g->getScreenSize();
8188

89+
float w = (float)s.Width;
90+
float h = (float)s.Height;
91+
92+
// update the root rect
8293
m_rect = core::rectf(0.0f, 0.0f, w, h);
94+
}
95+
}
8396

84-
m_root->layout(m_rect);
97+
void CCanvas::updateEntities()
98+
{
99+
for (u32 i = 0; i < MAX_ENTITY_DEPTH; i++)
100+
{
101+
m_depth[i].reset();
102+
}
103+
104+
CEntity** entities = m_entityMgr->getEntities();
105+
int numEntity = m_entityMgr->getNumEntities();
106+
107+
int maxDepth = 0;
108+
109+
for (int i = 0; i < numEntity; i++)
110+
{
111+
CEntity* entity = entities[i];
112+
if (entity->isAlive())
113+
{
114+
CWorldTransformData* world = GET_ENTITY_DATA(entity, CWorldTransformData);
115+
116+
m_depth[world->Depth].push(entity);
117+
118+
if (maxDepth < world->Depth)
119+
maxDepth = world->Depth;
120+
121+
if (world->ParentIndex != -1)
122+
world->Parent = GET_ENTITY_DATA(entities[world->ParentIndex], CWorldTransformData);
123+
else
124+
world->Parent = NULL;
125+
}
126+
}
127+
128+
m_alives.reset();
129+
130+
// copy and sort the alives by depth
131+
int count = 0;
132+
for (int i = 0; i <= maxDepth; i++)
133+
{
134+
CEntity** entitiesPtr = m_depth[i].pointer();
135+
136+
for (int j = 0, n = m_depth[i].count(); j < n; j++)
137+
m_alives.push(entitiesPtr[j]);
138+
}
139+
140+
// update systems
141+
for (IEntitySystem* system : m_systems)
142+
{
143+
system->beginQuery(NULL);
144+
system->onQuery(NULL, m_alives.pointer(), m_alives.count());
145+
system->update(NULL);
85146
}
86147
}
87148

@@ -98,10 +159,11 @@ namespace Skylicht
98159
CGUIElement* entity = renderEntity.top();
99160
renderEntity.pop();
100161

162+
// skip the invisible
101163
if (entity->isVisible() == false)
102164
continue;
103165

104-
// update position layout
166+
// update the entity
105167
entity->update(camera);
106168

107169
// apply mask
@@ -128,7 +190,6 @@ namespace Skylicht
128190
if (mask != NULL)
129191
mask->endMaskTest();
130192

131-
// note
132193
// we use stack to render parent -> child
133194
// so we must inverse render position because stack = Last-In First-Out (LIFO)
134195
for (int i = (int)entity->m_childs.size() - 1; i >= 0; i--)

Projects/Skylicht/Engine/Source/Graphics2D/CCanvas.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,13 @@ This file is part of the "Skylicht Engine".
3737
#include "GUI/CGUIMask.h"
3838

3939
#include "Entity/CEntityPrefab.h"
40-
41-
#define MAX_CHILD_DEPTH 512
40+
#include "Entity/CEntityManager.h"
4241

4342
namespace Skylicht
4443
{
4544
class CCanvas : public CComponentSystem
4645
{
4746
protected:
48-
CEntityPrefab* m_entityMgr;
49-
5047
core::rectf m_rect;
5148

5249
CGUIElement* m_root;
@@ -59,6 +56,14 @@ namespace Skylicht
5956

6057
CCamera* m_renderCamera;
6158

59+
// ECS System
60+
CEntityPrefab* m_entityMgr;
61+
62+
std::vector<IEntitySystem*> m_systems;
63+
64+
CFastArray<CEntity*> m_depth[MAX_ENTITY_DEPTH];
65+
CFastArray<CEntity*> m_alives;
66+
6267
public:
6368
CCanvas();
6469

@@ -68,7 +73,9 @@ namespace Skylicht
6873

6974
virtual void updateComponent();
7075

71-
virtual void layout();
76+
virtual void onResize();
77+
78+
void updateEntities();
7279

7380
void render(CCamera* camera);
7481

Projects/Skylicht/Engine/Source/Graphics2D/CGraphics2D.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ namespace Skylicht
8080
{
8181
for (CCanvas* c : m_canvas)
8282
{
83-
c->layout();
83+
c->onResize();
8484
}
8585
}
8686

@@ -214,6 +214,15 @@ namespace Skylicht
214214

215215
CGUIElement* root = canvas->getRootElement();
216216

217+
// set screensize for root
218+
core::dimension2du s = getScreenSize();
219+
float w = (float)s.Width;
220+
float h = (float)s.Height;
221+
root->setRect(core::rectf(0.0f, 0.0f, w, h));
222+
223+
// update canvas layout, position...
224+
canvas->updateEntities();
225+
217226
core::matrix4 world;
218227

219228
if (canvas->isEnable3DBillboard() == true && camera->getProjectionType() != CCamera::OrthoUI)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
!@
3+
MIT License
4+
5+
Copyright (c) 2022 Skylicht Technology CO., LTD
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
8+
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
9+
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
10+
subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19+
20+
This file is part of the "Skylicht Engine".
21+
https://github.com/skylicht-lab/skylicht-engine
22+
!#
23+
*/
24+
25+
#include "pch.h"
26+
#include "CGUIAlignData.h"
27+
28+
namespace Skylicht
29+
{
30+
IMPLEMENT_DATA_TYPE_INDEX(CGUIAlignData);
31+
32+
CGUIAlignData::CGUIAlignData() :
33+
Vertical(EGUIVerticalAlign::Top),
34+
Horizontal(EGUIHorizontalAlign::Left),
35+
Dock(EGUIDock::NoDock)
36+
{
37+
38+
}
39+
40+
CGUIAlignData::~CGUIAlignData()
41+
{
42+
43+
}
44+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
/*
2+
!@
3+
MIT License
4+
5+
Copyright (c) 2022 Skylicht Technology CO., LTD
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
8+
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
9+
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
10+
subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19+
20+
This file is part of the "Skylicht Engine".
21+
https://github.com/skylicht-lab/skylicht-engine
22+
!#
23+
*/
24+
25+
#pragma once
26+
27+
#include "Entity/IEntityData.h"
28+
29+
namespace Skylicht
30+
{
31+
enum class EGUIVerticalAlign
32+
{
33+
Top,
34+
Middle,
35+
Bottom
36+
};
37+
38+
enum class EGUIHorizontalAlign
39+
{
40+
Left,
41+
Center,
42+
Right
43+
};
44+
45+
enum class EGUIDock
46+
{
47+
NoDock,
48+
DockLeft,
49+
DockRight,
50+
DockTop,
51+
DockBottom,
52+
DockFill
53+
};
54+
55+
struct SMargin
56+
{
57+
float Left;
58+
float Top;
59+
float Right;
60+
float Bottom;
61+
62+
SMargin()
63+
{
64+
Left = 0.0f;
65+
Top = 0.0f;
66+
Right = 0.0f;
67+
Bottom = 0.0f;
68+
}
69+
};
70+
71+
class CGUIAlignData : public IEntityData
72+
{
73+
friend class CGUILayoutSystem;
74+
75+
public:
76+
DECLARE_DATA_TYPE_INDEX;
77+
78+
EGUIDock Dock;
79+
80+
SMargin Margin;
81+
82+
EGUIVerticalAlign Vertical;
83+
84+
EGUIHorizontalAlign Horizontal;
85+
86+
public:
87+
CGUIAlignData();
88+
89+
virtual ~CGUIAlignData();
90+
91+
DECLARE_GETTYPENAME(CGUIAlignData);
92+
};
93+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
!@
3+
MIT License
4+
5+
Copyright (c) 2022 Skylicht Technology CO., LTD
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
8+
(the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,
9+
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
10+
subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15+
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
16+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
17+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19+
20+
This file is part of the "Skylicht Engine".
21+
https://github.com/skylicht-lab/skylicht-engine
22+
!#
23+
*/
24+
25+
#include "pch.h"
26+
#include "CGUITransformData.h"
27+
28+
namespace Skylicht
29+
{
30+
IMPLEMENT_DATA_TYPE_INDEX(CGUITransformData);
31+
32+
CGUITransformData::CGUITransformData() :
33+
HasChanged(true),
34+
Parent(NULL),
35+
m_scale(1.0f, 1.0f, 1.0f)
36+
{
37+
38+
}
39+
40+
CGUITransformData::~CGUITransformData()
41+
{
42+
43+
}
44+
}

0 commit comments

Comments
 (0)