├── .clang-format
├── .editorconfig
├── .gitattributes
├── .gitignore
├── Base
├── Strings
│ └── StringTransform.cpp
├── Sync
│ ├── CriticalSection.cpp
│ ├── SRWLock.cpp
│ └── Sync.cpp
├── Threading
│ ├── ParallelTaskRunnerImpl.hpp
│ ├── SequencedTaskRunnerImpl.cpp
│ ├── SequencedTaskRunnerImpl.h
│ ├── TaskRunner.cpp
│ ├── TaskRunnerDispatchImpl.cpp
│ ├── TaskRunnerDispatchImpl.h
│ ├── TaskRunnerImpl.cpp
│ ├── TaskRunnerImpl.h
│ ├── ThreadPool.h
│ ├── ThreadPoolForLinux.cpp
│ ├── ThreadPoolForLinux.h
│ ├── ThreadPoolForWindows.cpp
│ ├── ThreadPoolForWindows.h
│ ├── ThreadPoolTimerManger.h
│ ├── ThreadPoolWaitManger.h
│ ├── ThreadTaskRunnerImpl.cpp
│ ├── ThreadTaskRunnerImpl.h
│ └── ThreadTaskRunnerProxyImpl.h
└── Utils
│ ├── FileInfo.cpp
│ └── SystemInfo.cpp
├── Directory.Build.props
├── Directory.Build.targets
├── Example
├── Example.cpp
├── Example.h
├── Example.ico
├── Example.rc
├── Example.vcxproj
├── Example.vcxproj.filters
├── Example.xml
├── Resource.h
├── framework.h
├── small.ico
└── targetver.h
├── Include
├── Base
│ ├── Containers
│ │ ├── Array.h
│ │ ├── ArrayView.h
│ │ ├── BitMap.h
│ │ ├── ConstructorPolicy.h
│ │ ├── DoublyLinkedList.h
│ │ ├── HashSet.h
│ │ ├── Optional.h
│ │ └── SingleLinkedList.h
│ ├── Encoding.h
│ ├── ErrorCode.h
│ ├── Exception.h
│ ├── IO
│ │ └── File.h
│ ├── Memory
│ │ ├── Alloc.h
│ │ ├── RefPtr.h
│ │ ├── UniquePtr.h
│ │ └── WeakPtr.h
│ ├── SAL.h
│ ├── SafeCast.h
│ ├── Shared
│ │ └── Windows
│ │ │ └── km.h
│ ├── Strings
│ │ ├── NString.h
│ │ ├── String.h
│ │ ├── StringTransform.h
│ │ └── StringView.h
│ ├── Sync
│ │ ├── AutoLock.h
│ │ ├── CriticalSection.h
│ │ ├── Interlocked.h
│ │ ├── InterlockedQueue.h
│ │ ├── InterlockedSingleLinkedList.h
│ │ ├── SRWLock.h
│ │ └── Sync.h
│ ├── Threading
│ │ ├── Coroutine.h
│ │ ├── ProcessThreads.h
│ │ └── TaskRunner.h
│ ├── Time
│ │ ├── Common.h
│ │ ├── TickCount.h
│ │ └── TimeSpan.h
│ ├── Utils
│ │ ├── ComObjectImpl.h
│ │ ├── FileInfo.h
│ │ ├── MathUtils.h
│ │ ├── SystemInfo.h
│ │ └── Version.h
│ ├── YY.h
│ └── tchar.h
├── Media
│ ├── Brushes
│ │ └── Brush.h
│ ├── Color.h
│ ├── Font.h
│ ├── Graphics
│ │ └── DrawContext.h
│ ├── Pens
│ │ └── Pen.h
│ ├── Point.h
│ ├── Rect.h
│ ├── Resource.h
│ └── Size.h
└── MegaUI
│ ├── Base
│ └── MegaUITypeInt.h
│ ├── Control
│ ├── Button.h
│ └── TextBox.h
│ ├── Core
│ ├── ControlInfo.h
│ ├── ControlInfoImp.h
│ ├── DeferCycle.h
│ ├── Element.h
│ ├── Layout.h
│ ├── Property.h
│ ├── StyleSheet.h
│ ├── TextScaleManger.h
│ ├── UIEvent.h
│ ├── Unit.h
│ └── Value.h
│ ├── Parser
│ └── UIParser.h
│ ├── Render
│ ├── FontEnumMap.h
│ └── Render.h
│ └── Window
│ ├── Window.h
│ └── WindowElement.h
├── Media
├── Font.cpp
└── Graphics
│ ├── D2D
│ ├── D2D1_0DrawContext.cpp
│ ├── D2D1_0DrawContext.h
│ ├── D2D1_1DrawContext.cpp
│ ├── D2D1_1DrawContext.h
│ ├── DWriteHelper.cpp
│ └── DWriteHelper.h
│ ├── D3D
│ ├── D3D11DrawContext.cpp
│ ├── D3D11DrawContext.h
│ ├── SolidColorPixelShader.hlsl
│ └── VertexShader.hlsl
│ ├── DrawAsyncCommandContext.cpp
│ ├── DrawAsyncCommandContext.h
│ ├── DrawContext.cpp
│ └── GDIPlus
│ ├── GDIPlusDrawContext.cpp
│ ├── GDIPlusDrawContext.h
│ ├── GDIPlusHelper.h
│ └── GdiPlusTextLayout.hpp
├── MegaUI.sln
├── MegaUI
├── Accessibility
│ └── UIAutomation
│ │ ├── AccessibleEventManager.cpp
│ │ ├── AccessibleEventManager.h
│ │ ├── ElementAccessibleProviderImpl.cpp
│ │ ├── ElementAccessibleProviderImpl.h
│ │ ├── ElementPatternProviderImpl.h
│ │ ├── PatternProviderImpl.h
│ │ ├── WindowElementAccessibleProviderImpl.cpp
│ │ ├── WindowElementAccessibleProviderImpl.h
│ │ └── WindowElementPatternProviderImpl.h
├── Common.xml
├── Control
│ ├── Button.cpp
│ └── TextBox.cpp
├── Core
│ ├── Unit.cpp
│ ├── Value.cpp
│ └── Windows
│ │ └── TextScaleManger.cpp
├── MegaUI.cpp
├── MegaUI.natvis
├── MegaUI.vcxproj
├── MegaUI.vcxproj.filters
├── Parser
│ ├── UIParser.cpp
│ └── ValueParser.h
├── Render
│ ├── FontEnumMap.cpp
│ └── Render.cpp
├── Window
│ ├── Window.cpp
│ └── WindowElement.cpp
├── core
│ ├── ControlInfo.cpp
│ ├── Element.cpp
│ └── StyleSheet.cpp
├── framework.h
├── pch.cpp
└── pch.h
├── ThirdParty
└── rapidxml
│ ├── license.txt
│ ├── rapidxml.hpp
│ ├── rapidxml_iterators.hpp
│ ├── rapidxml_print.hpp
│ └── rapidxml_utils.hpp
├── UnitTest
├── AsyncFileUnitTest.cpp
├── BitMapUnitTest.cpp
├── DynamicArrayUnitTest.cpp
├── StringUnitTest.cpp
├── TaskRunnerUnitTest.cpp
├── UnitTest.vcxproj
├── UnitTest.vcxproj.filters
├── ValueParserUnitTest.cpp
├── pch.cpp
└── pch.h
├── YY C++风格.md
└── readme.md
/.clang-format:
--------------------------------------------------------------------------------
1 | # https://clang.llvm.org/docs/ClangFormatStyleOptions.html
2 |
3 | Language: Cpp
4 | # BasedOnStyle: Microsoft
5 |
6 | Standard : c++14
7 |
8 | IndentWidth : 4
9 | AccessModifierOffset : -4
10 | IndentAccessModifiers : false
11 | PointerAlignment: Left
12 | ReferenceAlignment : Left
13 | ColumnLimit : 0
14 |
15 | TabWidth: 4
16 | UseTab: Never
17 |
18 | # 命名空间缩进
19 | NamespaceIndentation : All
20 | CompactNamespaces : false
21 | # 命名空间结束添加 注释 // namespace XXX
22 | FixNamespaceComments : true
23 |
24 |
25 | IndentWrappedFunctionNames: false
26 |
27 | AlignArrayOfStructures: Left
28 |
29 | # public结束后有一个回车
30 | EmptyLineBeforeAccessModifier : LogicalBlock
31 |
32 |
33 | BreakConstructorInitializers : BeforeComma
34 | BreakInheritanceList : BeforeComma
35 | # template后面不要有空格
36 | SpaceAfterTemplateKeyword : false
37 |
38 | Cpp11BracedListStyle : true
39 |
40 | # AlignEscapedNewlines : DontAlign
41 | SpaceBeforeCpp11BracedList : true
42 |
43 | # AllowAllParametersOfDeclarationOnNextLine : false
44 | SortUsingDeclarations : false
45 | SortIncludes : Never
46 |
47 | BreakBeforeBraces: Custom
48 | BraceWrapping:
49 | AfterFunction : true
50 | AfterNamespace : true
51 | AfterUnion : true
52 | AfterExternBlock : true
53 | BeforeElse : true
54 | BeforeWhile : false
55 | SplitEmptyFunction : true
56 | SplitEmptyRecord : true
57 | AfterCaseLabel : true
58 | AfterControlStatement: Always
59 | BeforeLambdaBody : true
60 | AfterClass : true
61 | AfterStruct : true
62 | AfterEnum : true
63 |
64 | SpaceBeforeParens : ControlStatements
65 |
66 | SpaceBeforeCaseColon : false
67 | SpacesInContainerLiterals : true
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: https://EditorConfig.org
2 |
3 |
4 | # 代码文件尽可能的使用 UTF-8,因为英语字符占据大多数。
5 | # 数据文件比如 XML,json统一缩进 2,因为外部规范往往如此
6 |
7 | [*]
8 | end_of_line = crlf
9 | insert_final_newline = true
10 | charset = utf-8-bom
11 | indent_style = space
12 | indent_size = 4
13 |
14 | [*.{vcxproj,xml,props,targets}]
15 | indent_style = space
16 | indent_size = 2
17 | insert_final_newline = false
18 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=crlf
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/Base/Sync/CriticalSection.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | __YY_IGNORE_INCONSISTENT_ANNOTATION_FOR_FUNCTION()
4 |
5 | namespace YY
6 | {
7 | namespace Base
8 | {
9 | namespace Sync
10 | {
11 | void __YYAPI CriticalSection::Lock() noexcept
12 | {
13 | const auto _uCurrentThreadId = Threading::GetCurrentThreadId();
14 | if (uOwnerThreadId == _uCurrentThreadId)
15 | {
16 | ++uLockRef;
17 | return;
18 | }
19 |
20 | oSRWLock.Lock();
21 | uOwnerThreadId = _uCurrentThreadId;
22 | uLockRef = 0;
23 | }
24 |
25 | bool __YYAPI CriticalSection::TryLock() noexcept
26 | {
27 | const auto _uCurrentThreadId = Threading::GetCurrentThreadId();
28 | if (uOwnerThreadId == _uCurrentThreadId)
29 | {
30 | ++uLockRef;
31 | return true;
32 | }
33 |
34 | if (oSRWLock.TryLock())
35 | {
36 | uOwnerThreadId = _uCurrentThreadId;
37 | uLockRef = 0;
38 | return true;
39 | }
40 |
41 | return false;
42 | }
43 |
44 | void __YYAPI CriticalSection::Unlock() noexcept
45 | {
46 | --uLockRef;
47 | if (uLockRef == 0)
48 | {
49 | uOwnerThreadId = 0;
50 | oSRWLock.Unlock();
51 | }
52 | }
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/Base/Sync/SRWLock.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | namespace YY
4 | {
5 | namespace Base
6 | {
7 | namespace Sync
8 | {
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Base/Sync/Sync.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | __YY_IGNORE_INCONSISTENT_ANNOTATION_FOR_FUNCTION()
5 |
6 | namespace YY
7 | {
8 | namespace Base
9 | {
10 | namespace Sync
11 | {
12 | template
13 | bool __YYAPI WaitEqualOnAddress(
14 | volatile ValueType* _pAddress,
15 | ValueType _CompareValue,
16 | TimeSpan _uMilliseconds) noexcept
17 | {
18 | if (_uMilliseconds.GetMilliseconds() <= 0)
19 | {
20 | return *_pAddress == _CompareValue;
21 | }
22 | else if (_uMilliseconds == TimeSpan::GetMax())
23 | {
24 | for (;;)
25 | {
26 | auto _Temp = *_pAddress;
27 | if (_Temp == _CompareValue)
28 | break;
29 |
30 | WaitOnAddress(_pAddress, &_Temp, sizeof(_Temp), UINT32_MAX);
31 | }
32 |
33 | return true;
34 | }
35 | else
36 | {
37 | const auto _uExpireTick = TickCount::GetCurrent() + _uMilliseconds;
38 | for (;;)
39 | {
40 | auto _Temp = *_pAddress;
41 | if (_Temp == _CompareValue)
42 | break;
43 |
44 | const auto _uCurrent = TickCount::GetCurrent();
45 | if (_uCurrent > _uExpireTick)
46 | return false;
47 |
48 | if (!WaitOnAddress(_pAddress, &_Temp, sizeof(_Temp), (_uExpireTick - _uCurrent).GetMilliseconds()))
49 | return false;
50 | }
51 |
52 | return true;
53 | }
54 | }
55 |
56 | bool __YYAPI WaitEqualOnAddress(
57 | volatile void* Address,
58 | void* CompareAddress,
59 | size_t AddressSize,
60 | TimeSpan _uMilliseconds) noexcept
61 | {
62 | switch (AddressSize)
63 | {
64 | case 1:
65 | {
66 | using Type = uint8_t;
67 | return WaitEqualOnAddress((volatile Type*)(Address), *(Type*)(CompareAddress), _uMilliseconds);
68 | }
69 | case 2:
70 | {
71 | using Type = uint16_t;
72 | return WaitEqualOnAddress((volatile Type*)(Address), *(Type*)(CompareAddress), _uMilliseconds);
73 | }
74 | case 4:
75 | {
76 | using Type = uint32_t;
77 | return WaitEqualOnAddress((volatile Type*)(Address), *(Type*)(CompareAddress), _uMilliseconds);
78 | }
79 | case 8:
80 | {
81 | using Type = uint64_t;
82 | return WaitEqualOnAddress((volatile Type*)(Address), *(Type*)(CompareAddress), _uMilliseconds);
83 | }
84 | default:
85 | return false;
86 | break;
87 | }
88 | }
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/Base/Threading/SequencedTaskRunnerImpl.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | #pragma pack(push, __YY_PACKING)
6 |
7 | namespace YY
8 | {
9 | namespace Base
10 | {
11 | namespace Threading
12 | {
13 | class SequencedTaskRunnerImpl : public SequencedTaskRunner
14 | {
15 | friend YY::Base::Threading::ThreadPool;
16 | private:
17 | InterlockedQueue oTaskQueue;
18 |
19 | union
20 | {
21 | volatile uint32_t uWakeupCountAndPushLock;
22 | struct
23 | {
24 | volatile uint32_t bPushLock : 1;
25 | volatile uint32_t bStopWakeup : 1;
26 | volatile uint32_t bInterrupt : 1;
27 | volatile uint32_t uWakeupCount : 29;
28 | };
29 | };
30 | enum : uint32_t
31 | {
32 | LockedQueuePushBitIndex = 0,
33 | StopWakeupBitIndex,
34 | InterruptBitIndex,
35 | WakeupCountStartBitIndex,
36 | StopWakeupRaw = 1 << StopWakeupBitIndex,
37 | InterruptRaw = 1 << InterruptBitIndex,
38 | WakeupOnceRaw = 1 << WakeupCountStartBitIndex,
39 | LockQueuePushLockAndWakeupOnceRaw = WakeupOnceRaw + (1u << LockedQueuePushBitIndex),
40 | TerminateTaskRunnerRaw = StopWakeupRaw | InterruptRaw,
41 | };
42 |
43 | uString szThreadDescription;
44 |
45 | public:
46 | SequencedTaskRunnerImpl(uString _szThreadDescription = uString());
47 |
48 | ~SequencedTaskRunnerImpl() override;
49 |
50 | SequencedTaskRunnerImpl(const SequencedTaskRunnerImpl&) = delete;
51 |
52 | SequencedTaskRunnerImpl& operator=(const SequencedTaskRunnerImpl&) = delete;
53 |
54 | /////////////////////////////////////////////////////
55 | // TaskRunner
56 | virtual TaskRunnerStyle __YYAPI GetStyle() const noexcept override;
57 |
58 | HRESULT __YYAPI Join(TimeSpan _nWaitTimeOut) noexcept override;
59 |
60 | HRESULT __YYAPI Interrupt() noexcept override;
61 |
62 | void __YYAPI operator()();
63 |
64 | private:
65 | HRESULT __YYAPI PostTaskInternal(_In_ RefPtr _pTask) override;
66 |
67 | void __YYAPI CleanupTaskQueue() noexcept;
68 |
69 | void __YYAPI ExecuteTaskRunner();
70 | };
71 | }
72 | }
73 | } // namespace YY
74 |
75 | #pragma pack(pop)
76 |
--------------------------------------------------------------------------------
/Base/Threading/TaskRunnerDispatchImpl.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #pragma pack(push, __YY_PACKING)
14 |
15 | /*
16 | TaskRunnerDispatch 仅处理调度任务(比如定时器、异步IO),无法参执行其他Task。
17 |
18 | */
19 |
20 | namespace YY
21 | {
22 | namespace Base
23 | {
24 | namespace Threading
25 | {
26 | class TaskRunnerDispatch
27 | {
28 | public:
29 | static _Ret_notnull_ TaskRunnerDispatch* __YYAPI Get() noexcept;
30 |
31 | #if defined(_WIN32)
32 | virtual bool __YYAPI BindIO(_In_ HANDLE _hHandle) const noexcept = 0;
33 | #endif
34 |
35 | virtual void __YYAPI SetTimerInternal(_In_ RefPtr _pTimer) noexcept = 0;
36 |
37 | virtual HRESULT __YYAPI SetWaitInternal(_In_ RefPtr _pWait) noexcept = 0;
38 |
39 | ///
40 | /// 发起异步请求成功后请调用此函数。内部将对完成端口进行监听。
41 | ///
42 | ///
43 | virtual void __YYAPI StartIo() noexcept = 0;
44 |
45 | protected:
46 | static void __YYAPI DispatchTask(RefPtr _pDispatchTask) noexcept
47 | {
48 | if (!_pDispatchTask)
49 | return;
50 |
51 | do
52 | {
53 | if (_pDispatchTask->IsCanceled())
54 | break;
55 |
56 | // 不属于任何TaskRunner,因此在线程池随机唤醒
57 | if (_pDispatchTask->pOwnerTaskRunnerWeak == nullptr)
58 | {
59 | auto _hr = ThreadPool::PostTaskInternal(_pDispatchTask.Get());
60 | return;
61 | }
62 |
63 | // 任务所属的 TaskRunner 已经释放?
64 | auto _pResumeTaskRunner = _pDispatchTask->pOwnerTaskRunnerWeak.Get();
65 | if (_pResumeTaskRunner == nullptr)
66 | break;
67 |
68 | _pResumeTaskRunner->PostTaskInternal(std::move(_pDispatchTask));
69 | return;
70 | } while (false);
71 |
72 | _pDispatchTask->Wakeup(YY::Base::HRESULT_From_LSTATUS(ERROR_CANCELLED));
73 | }
74 | };
75 | }
76 | }
77 | } // namespace YY
78 |
79 | #pragma pack(pop)
80 |
--------------------------------------------------------------------------------
/Base/Threading/TaskRunnerImpl.cpp:
--------------------------------------------------------------------------------
1 | #include "TaskRunnerImpl.h"
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | __YY_IGNORE_INCONSISTENT_ANNOTATION_FOR_FUNCTION()
8 |
9 | namespace YY
10 | {
11 | namespace Base
12 | {
13 | namespace Threading
14 | {
15 | thread_local WeakPtr g_pTaskRunnerWeak;
16 |
17 | uint32_t __YYAPI GenerateNewTaskRunnerId()
18 | {
19 | static uint32_t s_TaskRunnerId = 0;
20 | return Sync::Increment(&s_TaskRunnerId);
21 | }
22 |
23 | uint32_t __YYAPI GetWaitTimeSpan(TickCount _uWakeupTickCount) noexcept
24 | {
25 | if (_uWakeupTickCount == TickCount::GetMax())
26 | return UINT32_MAX;
27 |
28 | auto _nTimeSpan = _uWakeupTickCount - TickCount::GetCurrent();
29 | if (_nTimeSpan.GetInternalValue() <= 0)
30 | {
31 | return 1ul;
32 | }
33 | else if (_nTimeSpan.GetMilliseconds() >= UINT32_MAX)
34 | {
35 | return UINT32_MAX;
36 | }
37 |
38 | return (uint32_t)(std::max)(_nTimeSpan.GetMilliseconds(), 1ll);
39 | }
40 | }
41 | }
42 | } // namespace YY::Base::Threading
43 |
--------------------------------------------------------------------------------
/Base/Threading/TaskRunnerImpl.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 |
6 | #pragma pack(push, __YY_PACKING)
7 |
8 | namespace YY
9 | {
10 | namespace Base
11 | {
12 | namespace Threading
13 | {
14 | extern thread_local WeakPtr g_pTaskRunnerWeak;
15 |
16 | uint32_t __YYAPI GenerateNewTaskRunnerId();
17 |
18 | uint32_t __YYAPI GetWaitTimeSpan(_In_ TickCount _uWakeupTickCount) noexcept;
19 | }
20 | }
21 | } // namespace YY::Base::Threading
22 |
23 | #pragma pack(pop)
24 |
--------------------------------------------------------------------------------
/Base/Threading/ThreadPool.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #if defined(_WIN32)
4 | #include
5 | #else
6 | #include
7 | #endif
8 |
--------------------------------------------------------------------------------
/Base/Threading/ThreadPoolForLinux.cpp:
--------------------------------------------------------------------------------
1 | #include "pch.h"
2 | #include "ThreadPoolForLinux.h"
3 |
4 | #include
5 |
6 | #include
7 | #include
8 |
9 | __YY_IGNORE_INCONSISTENT_ANNOTATION_FOR_FUNCTION()
10 |
11 | namespace YY::Base::Threading
12 | {
13 | constexpr uint32_t MinThreadsCount = 10;
14 | constexpr uint32_t MaxThreadsCount = 500;
15 |
16 | HRESULT __YYAPI ThreadPool::ExecuteTask(ThreadPoolSimpleCallback _pfnCallback, void* _pUserData) noexcept
17 | {
18 | auto _pThread = oIdleThreadQueue.Pop();
19 | if (_pThread)
20 | {
21 | _pThread->pUserData = _pUserData;
22 | _pThread->pfnCallback = _pfnCallback;
23 |
24 | pthread_kill(_pThread->hThread, SIGUSR1);
25 | return S_OK;
26 | }
27 |
28 | for (auto uCurrentThreadCount = uThreadCount;;)
29 | {
30 | if (uCurrentThreadCount >= MaxThreadsCount)
31 | {
32 | // 达到线程创建上限
33 | auto _pTask = New(_pfnCallback, _pUserData);
34 | if(!_pTask)
35 | return E_OUTOFMEMORY;
36 |
37 | oPendingTaskQueue.Push(_pTask);
38 | return S_OK;
39 | }
40 |
41 | const auto _uLast = Sync::CompareExchange(&uThreadCount, uCurrentThreadCount + 1, uCurrentThreadCount);
42 | if (_uLast == uCurrentThreadCount)
43 | {
44 | break;
45 | }
46 |
47 | uCurrentThreadCount = _uLast;
48 | }
49 |
50 | _pThread = New();
51 | if (!_pThread)
52 | {
53 | Sync::Decrement(&uThreadCount);
54 | return E_OUTOFMEMORY;
55 | }
56 |
57 | _pThread->pfnCallback = _pfnCallback;
58 | _pThread->pUserData = _pUserData;
59 | _pThread->pThreadPool = this;
60 |
61 | const auto _iResult = pthread_create(&_pThread->hThread, nullptr,
62 | [](void* _pUserData) -> void*
63 | {
64 | auto _pThread = (ThreadInfoEntry*)_pUserData;
65 | return _pThread->pThreadPool->TaskExecuteRoutine(_pThread);
66 | }, _pThread);
67 |
68 | if (_iResult == 0)
69 | {
70 | return S_OK;
71 | }
72 |
73 | Sync::Decrement(&uThreadCount);
74 | Delete(_pThread);
75 |
76 | // TODO: 错误代码转换
77 | return E_FAIL;
78 | }
79 |
80 | void* ThreadPool::TaskExecuteRoutine(ThreadInfoEntry* _pThread) noexcept
81 | {
82 | sigset_t set;
83 | sigemptyset(&set);
84 | sigaddset(&set, SIGUSR1);
85 | int signo;
86 |
87 | for (;;)
88 | {
89 | if (_pThread->pfnCallback)
90 | {
91 | _pThread->pfnCallback(_pThread->pUserData);
92 | _pThread->pfnCallback = nullptr;
93 | _pThread->pUserData = nullptr;
94 | }
95 |
96 | for (;;)
97 | {
98 | auto _pTask = oPendingTaskQueue.Pop();
99 | if (!_pTask)
100 | break;
101 |
102 | _pTask->pfnCallback(_pTask->pUserData);
103 |
104 | Delete(_pTask);
105 | }
106 |
107 |
108 | _pThread->pThreadPool->oIdleThreadQueue.Push(_pThread);
109 |
110 | pthread_sigmask(SIG_SETMASK, &set, nullptr);
111 | if (sigwait(&set, &signo) != 0)
112 | {
113 | break;
114 | }
115 |
116 | if (signo != SIGUSR1)
117 | break;
118 | }
119 |
120 | Sync::Decrement(&uThreadCount);
121 | Delete(_pThread);
122 | pthread_detach(pthread_self());
123 | return nullptr;
124 | }
125 |
126 | ThreadPool* __YYAPI ThreadPool::Get() noexcept
127 | {
128 | static ThreadPool s_ThreadPool;
129 | return &s_ThreadPool;
130 | }
131 | }
132 |
--------------------------------------------------------------------------------
/Base/Threading/ThreadPoolForLinux.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #include
5 | #include
6 | #include
7 |
8 | #pragma pack(push, __YY_PACKING)
9 |
10 | namespace YY::Base::Threading
11 | {
12 | typedef void(__YYAPI* ThreadPoolSimpleCallback)(void* _pUserData);
13 |
14 | struct ThreadPoolTaskEntry
15 | {
16 | ThreadPoolSimpleCallback pfnCallback = nullptr;
17 | void* pUserData = nullptr;
18 | };
19 |
20 | class ThreadPool;
21 |
22 | struct ThreadInfoEntry
23 | {
24 | ThreadInfoEntry* pNext = nullptr;
25 | pthread_t hThread = 0;
26 | ThreadPoolSimpleCallback pfnCallback = nullptr;
27 | void* pUserData = nullptr;
28 | ThreadPool* pThreadPool = nullptr;
29 | };
30 |
31 | class ThreadPool
32 | {
33 | private:
34 | InterlockedSingleLinkedList oIdleThreadQueue;
35 | InterlockedQueue oPendingTaskQueue;
36 |
37 | volatile uint32_t uThreadCount = 0;
38 |
39 | constexpr ThreadPool() = default;
40 |
41 | public:
42 | template
43 | static HRESULT __YYAPI PostTaskInternalWithoutAddRef(_In_ Task* _pTask) noexcept
44 | {
45 | return Get()->ExecuteTask(
46 | [](_In_ void* _pUserData)
47 | {
48 | auto _pTask = reinterpret_cast(_pUserData);
49 | _pTask->operator()();
50 | },
51 | _pTask);
52 | }
53 |
54 | template
55 | static HRESULT __YYAPI PostTaskInternal(_In_ Task* _pTask) noexcept
56 | {
57 | _pTask->AddRef();
58 | auto _hr = Get()->ExecuteTask(
59 | [](_In_ void* _pUserData)
60 | {
61 | auto _pTask = reinterpret_cast(_pUserData);
62 | _pTask->operator()();
63 | _pTask->Release();
64 | },
65 | _pTask);
66 |
67 | if (FAILED(_hr))
68 | {
69 | _pTask->Release();
70 | }
71 | return _hr;
72 | }
73 |
74 | private:
75 | void* TaskExecuteRoutine(ThreadInfoEntry* _pThread) noexcept;
76 |
77 | static _Ret_notnull_ ThreadPool* __YYAPI Get() noexcept;
78 |
79 | HRESULT __YYAPI ExecuteTask(_In_ ThreadPoolSimpleCallback _pfnCallback, _In_opt_ void* _pUserData) noexcept;
80 | };
81 | }
82 |
83 | namespace YY
84 | {
85 | using namespace YY::Base::Threading;
86 | }
87 |
88 | #pragma pack(pop)
89 |
--------------------------------------------------------------------------------
/Base/Threading/ThreadPoolForWindows.cpp:
--------------------------------------------------------------------------------
1 | #include "ThreadPoolForWindows.h"
2 |
3 | __YY_IGNORE_INCONSISTENT_ANNOTATION_FOR_FUNCTION()
4 |
5 | namespace YY
6 | {
7 | namespace Base
8 | {
9 | namespace Threading
10 | {
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Base/Threading/ThreadPoolForWindows.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #pragma pack(push, __YY_PACKING)
7 |
8 | namespace YY
9 | {
10 | namespace Base
11 | {
12 | namespace Threading
13 | {
14 | class ThreadPool
15 | {
16 | public:
17 | template
18 | static HRESULT __YYAPI PostTaskInternalWithoutAddRef(_In_ Task* _pTask) noexcept
19 | {
20 | auto _bRet = TrySubmitThreadpoolCallback(
21 | [](_Inout_ PTP_CALLBACK_INSTANCE _pInstance,
22 | _In_ PVOID _pContext)
23 | {
24 | auto _pTask = reinterpret_cast(_pContext);
25 | _pTask->operator()();
26 | },
27 | _pTask,
28 | nullptr);
29 |
30 | return _bRet ? S_OK : HRESULT_From_LSTATUS(GetLastError());
31 | }
32 |
33 | template
34 | static HRESULT __YYAPI PostTaskInternal(_In_ Task* _pTask) noexcept
35 | {
36 | _pTask->AddRef();
37 | auto _bRet = TrySubmitThreadpoolCallback(
38 | [](_Inout_ PTP_CALLBACK_INSTANCE _pInstance,
39 | _In_ PVOID _pContext)
40 | {
41 | auto _pTask = reinterpret_cast(_pContext);
42 | _pTask->operator()();
43 | _pTask->Release();
44 | },
45 | _pTask,
46 | nullptr);
47 |
48 | if (!_bRet)
49 | {
50 | auto _hr = HRESULT_From_LSTATUS(GetLastError());
51 | _pTask->Release();
52 | return _hr;
53 | }
54 |
55 | return S_OK;
56 | }
57 | };
58 | }
59 | }
60 | }
61 |
62 | namespace YY
63 | {
64 | using namespace YY::Base::Threading;
65 | }
66 |
67 | #pragma pack(pop)
68 |
--------------------------------------------------------------------------------
/Base/Threading/ThreadTaskRunnerImpl.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | #pragma pack(push, __YY_PACKING)
14 |
15 | namespace YY
16 | {
17 | namespace Base
18 | {
19 | namespace Threading
20 | {
21 | class ThreadTaskRunnerBaseImpl
22 | : public ThreadTaskRunner
23 | {
24 | public:
25 | virtual uintptr_t __YYAPI RunTaskRunnerLoop() = 0;
26 | };
27 |
28 | class ThreadTaskRunnerImpl
29 | : public ThreadTaskRunnerBaseImpl
30 | , public ThreadPoolTimerManger
31 | , public ThreadPoolWaitMangerForSingleThreading
32 | {
33 | private:
34 | InterlockedQueue oTaskQueue;
35 |
36 | // |uWeakupCount| bStopWakeup | bPushLock |
37 | // | 31 ~ 2 | 1 | 0 |
38 | union
39 | {
40 | volatile uint32_t uWakeupCountAndPushLock;
41 | struct
42 | {
43 | volatile uint32_t bPushLock : 1;
44 | volatile uint32_t bStopWakeup : 1;
45 | volatile uint32_t bInterrupt : 1;
46 | volatile uint32_t bBackgroundLoop : 1;
47 | uint32_t uWakeupCount : 28;
48 | };
49 | };
50 | enum : uint32_t
51 | {
52 | LockedQueuePushBitIndex = 0,
53 | StopWakeupBitIndex,
54 | InterruptBitIndex,
55 | BackgroundLoopIndex,
56 | WakeupCountStartBitIndex,
57 | StopWakeupRaw = 1 << StopWakeupBitIndex,
58 | InterruptRaw = 1 << InterruptBitIndex,
59 | BackgroundLoopRaw = 1 << BackgroundLoopIndex,
60 | WakeupOnceRaw = 1 << WakeupCountStartBitIndex,
61 | UnlockQueuePushLockBitAndWakeupOnceRaw = WakeupOnceRaw - (1u << LockedQueuePushBitIndex),
62 | TerminateTaskRunnerRaw = StopWakeupRaw | InterruptRaw,
63 | };
64 |
65 | volatile uint32_t uThreadId;
66 | uString szThreadDescription;
67 |
68 | public:
69 | ThreadTaskRunnerImpl(_In_ uint32_t _uThreadId = Threading::GetCurrentThreadId(), _In_ bool _bBackgroundLoop = false, uString _szThreadDescription = uString());
70 |
71 | ///
72 | /// 从线程池借用一个线程,执行TaskRunner。
73 | ///
74 | ///
75 | // ThreadTaskRunnerImpl(_In_ uint32_t _uTaskRunnerId);
76 |
77 | ThreadTaskRunnerImpl(const ThreadTaskRunnerImpl&) = delete;
78 |
79 | ~ThreadTaskRunnerImpl();
80 |
81 | ThreadTaskRunnerImpl& operator=(const ThreadTaskRunnerImpl&) = delete;
82 |
83 | /////////////////////////////////////////////////////
84 | // TaskRunner
85 | virtual TaskRunnerStyle __YYAPI GetStyle() const noexcept override;
86 |
87 | HRESULT __YYAPI Join(TimeSpan _nWaitTimeOut) noexcept override;
88 |
89 | HRESULT __YYAPI Interrupt() noexcept override;
90 |
91 | /////////////////////////////////////////////////////
92 | // ThreadTaskRunner
93 |
94 | virtual uint32_t __YYAPI GetThreadId() override;
95 |
96 | //
97 | ////////////////////////////////////////////////////
98 |
99 | void __YYAPI EnableWakeup(_In_ bool _bEnable);
100 |
101 | void __YYAPI operator()();
102 |
103 | uintptr_t __YYAPI RunTaskRunnerLoop() override;
104 |
105 | private:
106 | HRESULT __YYAPI PostTaskInternal(_In_ RefPtr _pTask) override;
107 |
108 | HRESULT __YYAPI SetTimerInternal(_In_ RefPtr _pTask) override;
109 |
110 | HRESULT __YYAPI SetWaitInternal(_In_ RefPtr _pTask) override;
111 |
112 | void __YYAPI DispatchTimerTask(RefPtr _pTimerTask) override;
113 |
114 | void __YYAPI DispatchWaitTask(RefPtr _pWaitTask) override;
115 |
116 | void __YYAPI CleanupTaskQueue() noexcept;
117 |
118 | HRESULT __YYAPI Wakeup() noexcept;
119 |
120 | uintptr_t __YYAPI RunUIMessageLoop();
121 |
122 | ///
123 | /// 运行后台循环,改模式UI相关处理极为滞后!
124 | ///
125 | ///
126 | uintptr_t __YYAPI RunBackgroundLoop();
127 | };
128 | }
129 | }
130 | } // namespace YY
131 |
132 | #pragma pack(pop)
133 |
--------------------------------------------------------------------------------
/Base/Utils/FileInfo.cpp:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 | #include
5 |
6 | __YY_IGNORE_INCONSISTENT_ANNOTATION_FOR_FUNCTION()
7 |
8 | namespace YY
9 | {
10 | namespace Base
11 | {
12 | namespace Utils
13 | {
14 | HRESULT __YYAPI GetFileVersion(LPCWSTR _szFilePath, Version* _pVersion) noexcept
15 | {
16 | _pVersion->uInternalValue = 0;
17 | auto _hFileMoudle = LoadLibraryExW(_szFilePath, NULL, LOAD_LIBRARY_AS_DATAFILE);
18 | if (!_hFileMoudle)
19 | return HRESULT_From_LSTATUS(GetLastError());
20 |
21 | auto _lStatus = GetFileVersion(_hFileMoudle, _pVersion);
22 | FreeLibrary(_hFileMoudle);
23 | return _lStatus;
24 | }
25 |
26 | HRESULT __YYAPI GetFileVersion(HMODULE _hMoudle, Version* _pVersion) noexcept
27 | {
28 | _pVersion->uInternalValue = 0;
29 | __try
30 | {
31 | HRSRC _hRsrcVersion = FindResourceExW(_hMoudle, RT_VERSION, MAKEINTRESOURCE(1), MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
32 |
33 | if (_hRsrcVersion == NULL)
34 | {
35 | return HRESULT_From_LSTATUS(GetLastError());
36 | }
37 |
38 | HGLOBAL _hGlobal = LoadResource(_hMoudle, _hRsrcVersion);
39 | if (_hGlobal == NULL)
40 | {
41 | return HRESULT_From_LSTATUS(GetLastError());
42 | }
43 |
44 | VS_FIXEDFILEINFO* _pFileInfo = NULL;
45 | UINT _cbFileInfo;
46 | #ifndef _ATL_XP_TARGETING
47 | if (!VerQueryValueW(_hGlobal, L"\\", (LPVOID*)&_pFileInfo, &_cbFileInfo))
48 | {
49 | return HRESULT_From_LSTATUS(GetLastError());
50 | }
51 | #else
52 | // XP系统不允许直接调用,不然会触发内存非法访问。所以先复制到一个内存块上
53 | const DWORD _cbFileInfoBuffer = SizeofResource(_hMoudle, _hRsrcVersion);
54 | void* _pFileInfoBuffer = alloca(_cbFileInfoBuffer);
55 |
56 | memcpy(_pFileInfoBuffer, _hGlobal, _cbFileInfoBuffer);
57 |
58 | if (!VerQueryValueW(_pFileInfoBuffer, L"\\", (LPVOID*)&_pFileInfo, &_cbFileInfo))
59 | {
60 | return HRESULT_From_LSTATUS(GetLastError());
61 | }
62 | #endif
63 |
64 | _pVersion->uLowPart = _pFileInfo->dwFileVersionLS;
65 | _pVersion->uHightPart = _pFileInfo->dwFileVersionMS;
66 | return S_OK;
67 | }
68 | //抓取EXCEPTION_IN_PAGE_ERROR异常,防止IO问题导致程序崩溃。
69 | __except ((GetExceptionCode() == EXCEPTION_IN_PAGE_ERROR || GetExceptionCode() == 0xC000009C) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
70 | {
71 | return HRESULT_From_LSTATUS(ERROR_DISK_OPERATION_FAILED);
72 | }
73 | }
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/Base/Utils/SystemInfo.cpp:
--------------------------------------------------------------------------------
1 | #define _Disallow_YY_KM_Namespace
2 |
3 | #include
4 |
5 | #define WIN32_NO_STATUS
6 | #include
7 |
8 | namespace YY
9 | {
10 | namespace Base
11 | {
12 | namespace Utils
13 | {
14 | #if defined(_WIN32)
15 | Version __YYAPI YY::Base::Utils::GetOperatingSystemVersion() noexcept
16 | {
17 | const auto _pPeb = ((TEB*)NtCurrentTeb())->ProcessEnvironmentBlock;
18 | Version _uOsVersion(uint16_t(_pPeb->OSMajorVersion), uint16_t(_pPeb->OSMinorVersion), uint16_t(_pPeb->OSBuildNumber));
19 |
20 | if (_uOsVersion == kWindowsNT5_1)
21 | {
22 | switch (HIBYTE(_pPeb->OSCSDVersion))
23 | {
24 | case 0:
25 | break;
26 | case 1:
27 | _uOsVersion.uRevision = 1106;
28 | break;
29 | case 2:
30 | _uOsVersion.uRevision = 2180;
31 | break;
32 | case 3:
33 | default:
34 | _uOsVersion.uRevision = 5512;
35 | break;
36 | }
37 | }
38 | else if(_uOsVersion == kWindowsNT5_2)
39 | {
40 | switch (HIBYTE(_pPeb->OSCSDVersion))
41 | {
42 | case 0:
43 | break;
44 | case 1:
45 | default:
46 | _uOsVersion.uRevision = 1830;
47 | break;
48 | }
49 | }
50 |
51 | return _uOsVersion;
52 | }
53 | #endif
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | native,Version=v0.0
10 |
11 | win;win-x86;win-x64;win-arm;win-arm64
12 |
13 |
14 |
15 |
16 | $([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../'))
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | true
7 |
8 |
9 |
10 | $([MSBuild]::GetPathOfFileAbove('Directory.Build.targets', '$(MSBuildThisFileDirectory)../'))
11 |
12 |
13 |
14 | MultiThreadedDebugDLL
15 |
16 |
17 | MultiThreadedDLL
18 |
19 |
20 |
21 |
22 | MultiThreadedDebug
23 |
24 |
25 | MultiThreaded
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Example/Example.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #if defined(_WIN32)
4 | #include "resource.h"
5 | #endif
6 |
--------------------------------------------------------------------------------
/Example/Example.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chuyu-Team/MegaUI/142dfb135d8df5fba4c3591a5e353ed7568322de/Example/Example.ico
--------------------------------------------------------------------------------
/Example/Example.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chuyu-Team/MegaUI/142dfb135d8df5fba4c3591a5e353ed7568322de/Example/Example.rc
--------------------------------------------------------------------------------
/Example/Example.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
7 |
8 |
9 | {93995380-89BD-4b04-88EB-625FBE52EBFB}
10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
11 |
12 |
13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms
15 |
16 |
17 |
18 |
19 | 头文件
20 |
21 |
22 | 头文件
23 |
24 |
25 | 头文件
26 |
27 |
28 | 头文件
29 |
30 |
31 |
32 |
33 | 源文件
34 |
35 |
36 |
37 |
38 | 资源文件
39 |
40 |
41 |
42 |
43 | 资源文件
44 |
45 |
46 | 资源文件
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/Example/Example.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
50 |
51 |
62 |
64 |
65 |
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/Example/Resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ 生成的包含文件。
3 | // 供 Example.rc 使用
4 | //
5 | #define IDC_MYICON 2
6 | #define IDD_EXAMPLE_DIALOG 102
7 | #define IDS_APP_TITLE 103
8 | #define IDD_ABOUTBOX 103
9 | #define IDM_ABOUT 104
10 | #define IDM_EXIT 105
11 | #define IDI_EXAMPLE 107
12 | #define IDI_SMALL 108
13 | #define IDC_EXAMPLE 109
14 | #define IDR_MAINFRAME 128
15 | #define IDR_UI1 129
16 | #define IDR_UI_COMMON 130
17 | #define IDC_STATIC -1
18 |
19 | // Next default values for new objects
20 | //
21 | #ifdef APSTUDIO_INVOKED
22 | #ifndef APSTUDIO_READONLY_SYMBOLS
23 | #define _APS_NO_MFC 1
24 | #define _APS_NEXT_RESOURCE_VALUE 131
25 | #define _APS_NEXT_COMMAND_VALUE 32771
26 | #define _APS_NEXT_CONTROL_VALUE 1000
27 | #define _APS_NEXT_SYMED_VALUE 110
28 | #endif
29 | #endif
30 |
--------------------------------------------------------------------------------
/Example/framework.h:
--------------------------------------------------------------------------------
1 | // header.h: 标准系统包含文件的包含文件,
2 | // 或特定于项目的包含文件
3 | //
4 |
5 | #pragma once
6 |
7 | #include "targetver.h"
8 |
9 | #if defined(_WIN32)
10 | #define WIN32_LEAN_AND_MEAN // 从 Windows 头文件中排除极少使用的内容
11 | // Windows 头文件
12 | #include
13 | #endif
14 | // C 运行时头文件
15 | #include
16 | #include
17 | #include
18 |
19 |
--------------------------------------------------------------------------------
/Example/small.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chuyu-Team/MegaUI/142dfb135d8df5fba4c3591a5e353ed7568322de/Example/small.ico
--------------------------------------------------------------------------------
/Example/targetver.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | // // 包含 SDKDDKVer.h 可定义可用的最高版本的 Windows 平台。
4 | // 如果希望为之前的 Windows 平台构建应用程序,在包含 SDKDDKVer.h 之前请先包含 WinSDKVer.h 并
5 | // 将 _WIN32_WINNT 宏设置为想要支持的平台。
6 |
7 | #if defined(_WIN32)
8 | #include
9 | #endif
10 |
--------------------------------------------------------------------------------
/Include/Base/Containers/ArrayView.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #pragma pack(push, __YY_PACKING)
6 |
7 | namespace YY
8 | {
9 | namespace Base
10 | {
11 | namespace Containers
12 | {
13 | template
14 | class ArrayView
15 | {
16 | private:
17 | _Type* pData;
18 | uint_t cData;
19 |
20 | public:
21 | ArrayView()
22 | : pData(nullptr)
23 | , cData(0)
24 | {
25 | }
26 |
27 | ArrayView(_Type* _pData, uint_t _cData)
28 | : pData(_pData)
29 | , cData(_pData ? _cData : 0)
30 | {
31 | }
32 |
33 | template
34 | ArrayView(_Type (&_Array)[_uArrayCount])
35 | : pData(_Array)
36 | , cData(_uArrayCount)
37 | {
38 | }
39 |
40 | _Type* __YYAPI GetData() noexcept
41 | {
42 | return pData;
43 | }
44 |
45 | const _Type* __YYAPI GetData() const noexcept
46 | {
47 | return pData;
48 | }
49 |
50 | uint_t __YYAPI GetSize() const
51 | {
52 | return cData;
53 | }
54 |
55 | void __YYAPI Slice(uint_t _uRemoveStart, uint_t _uRemoveEnd = 0u)
56 | {
57 | if (_uRemoveStart + _uRemoveEnd >= cData)
58 | {
59 | cData = 0;
60 | }
61 | else
62 | {
63 | pData += _uRemoveStart;
64 | cData -= _uRemoveStart;
65 | cData -= _uRemoveEnd;
66 | }
67 | }
68 |
69 | _Type& __YYAPI operator[](_In_ uint_t _uIndex)
70 | {
71 | return pData[_uIndex];
72 | }
73 |
74 | const _Type& __YYAPI operator[](_In_ uint_t _uIndex) const
75 | {
76 | return pData[_uIndex];
77 | }
78 |
79 | _Type* __YYAPI begin() noexcept
80 | {
81 | return pData;
82 | }
83 |
84 | _Type* __YYAPI end() noexcept
85 | {
86 | return pData + GetSize();
87 | }
88 |
89 | const _Type* __YYAPI begin() const noexcept
90 | {
91 | return pData;
92 | }
93 |
94 | const _Type* __YYAPI end() const noexcept
95 | {
96 | return pData + GetSize();
97 | }
98 |
99 | _Type* __YYAPI _Unchecked_begin() noexcept
100 | {
101 | return pData;
102 | }
103 |
104 | _Type* __YYAPI _Unchecked_end() noexcept
105 | {
106 | return pData + GetSize();
107 | }
108 |
109 | const _Type* __YYAPI _Unchecked_begin() const noexcept
110 | {
111 | return pData;
112 | }
113 |
114 | const _Type* __YYAPI _Unchecked_end() const noexcept
115 | {
116 | return pData + GetSize();
117 | }
118 | };
119 | } // namespace Containers
120 | } // namespace Base
121 |
122 | using namespace YY::Base::Containers;
123 | } // namespace YY
124 |
125 | #pragma pack(pop)
126 |
--------------------------------------------------------------------------------
/Include/Base/Containers/ConstructorPolicy.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chuyu-Team/MegaUI/142dfb135d8df5fba4c3591a5e353ed7568322de/Include/Base/Containers/ConstructorPolicy.h
--------------------------------------------------------------------------------
/Include/Base/Containers/HashSet.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #pragma pack(push, __YY_PACKING)
6 |
7 | namespace YY
8 | {
9 | namespace Base
10 | {
11 | namespace Containers
12 | {
13 | // 暂时仅适用于指针
14 | template
15 | class HashSet
16 | {
17 | private:
18 | struct HashSetEntry
19 | {
20 | HashSetEntry* pNext;
21 | _Key Data;
22 | };
23 |
24 | HashSetEntry* pBuckets[_uBuckets];
25 |
26 | public:
27 | HashSet()
28 | : pBuckets {}
29 | {
30 | }
31 |
32 | ~HashSet()
33 | {
34 | for (auto _pBucket : pBuckets)
35 | {
36 | for (auto _pItem = _pBucket; _pItem;)
37 | {
38 | auto _pTmp = _pItem;
39 | _pItem = _pItem->pNext;
40 | free(_pTmp);
41 | }
42 | }
43 | }
44 |
45 | _Key Pop()
46 | {
47 | for (auto& _pBucket : pBuckets)
48 | {
49 | if (_pBucket)
50 | {
51 | auto _Tmp = _pBucket;
52 | _pBucket = _Tmp->pNext;
53 | return _Tmp->Data;
54 | }
55 | }
56 |
57 | return nullptr;
58 | }
59 |
60 | HRESULT __YYAPI Insert(_Key _pKey)
61 | {
62 | const auto _uIndex = reinterpret_cast(_pKey) % _uBuckets;
63 |
64 | for (auto _pEntry = pBuckets[_uIndex]; _pEntry; _pEntry = _pEntry->pNext)
65 | {
66 | if (_pEntry->Data == _pKey)
67 | return S_FALSE;
68 | }
69 |
70 | auto pNewEntry = (HashSetEntry*)Alloc(sizeof(HashSetEntry));
71 | if (!pNewEntry)
72 | return E_OUTOFMEMORY;
73 |
74 | auto& _FirstEntry = pBuckets[_uIndex];
75 |
76 | pNewEntry->Data = _pKey;
77 | pNewEntry->pNext = _FirstEntry;
78 | _FirstEntry = pNewEntry;
79 |
80 | return S_OK;
81 | }
82 |
83 | HRESULT __YYAPI Remove(_Key _pKey)
84 | {
85 | const auto _uIndex = reinterpret_cast(_pKey) % _uBuckets;
86 | HashSetEntry* _pLastEntry = nullptr;
87 |
88 | for (auto _pEntry = pBuckets[_uIndex]; _pEntry; _pEntry = _pEntry->pNext)
89 | {
90 | if (_pEntry->Data == _pKey)
91 | {
92 | auto _pNext = _pEntry->pNext;
93 |
94 | if (_pLastEntry)
95 | {
96 | _pLastEntry->pNext = _pNext;
97 | }
98 | else
99 | {
100 | pBuckets[_uIndex] = _pNext;
101 | }
102 |
103 | free(_pEntry);
104 |
105 | return S_OK;
106 | }
107 |
108 | _pLastEntry = _pEntry;
109 | }
110 |
111 | return S_FALSE;
112 | }
113 | };
114 | } // namespace Containers
115 | } // namespace Base
116 |
117 | using namespace YY::Base::Containers;
118 | } // namespace YY
119 |
120 | #pragma pack(pop)
121 |
--------------------------------------------------------------------------------
/Include/Base/Containers/SingleLinkedList.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #pragma pack(push, __YY_PACKING)
5 |
6 | namespace YY
7 | {
8 | namespace Base
9 | {
10 | namespace Containers
11 | {
12 | template
13 | struct SingleLinkedListEntryImpl
14 | {
15 | EntryType* pNext = nullptr;
16 | };
17 |
18 | ///
19 | /// 原始的单项链表。
20 | /// * 不支持多线程操作,需要自己加锁。
21 | /// * 不会自动释放内存,请自己释放内存。
22 | ///
23 | ///
24 | template
25 | class SingleLinkedList
26 | {
27 | private:
28 | EntryType* pFirst = nullptr;
29 | EntryType* pLast = nullptr;
30 |
31 | public:
32 | constexpr SingleLinkedList() = default;
33 |
34 | constexpr SingleLinkedList(SingleLinkedList&& _oList) noexcept
35 | {
36 | pFirst = _oList.pFirst;
37 | pLast = _oList.pLast;
38 | _oList.pFirst = nullptr;
39 | _oList.pLast = nullptr;
40 | }
41 |
42 | SingleLinkedList(const SingleLinkedList&) = delete;
43 | SingleLinkedList& operator=(const SingleLinkedList&) = delete;
44 |
45 | _Ret_maybenull_ constexpr EntryType* __YYAPI GetFirst() const noexcept
46 | {
47 | return pFirst;
48 | }
49 |
50 | _Ret_maybenull_ constexpr EntryType* __YYAPI GetLast() const noexcept
51 | {
52 | return pLast;
53 | }
54 |
55 | _Ret_maybenull_ EntryType* __YYAPI Pop() noexcept
56 | {
57 | if (pFirst == nullptr)
58 | return nullptr;
59 |
60 | auto _pOldFirst = pFirst;
61 | pFirst = _pOldFirst->pNext;
62 |
63 | if (!pFirst)
64 | {
65 | pLast = nullptr;
66 | }
67 |
68 | return _pOldFirst;
69 | }
70 |
71 | void __YYAPI Push(_In_ EntryType* _pEntry) noexcept
72 | {
73 | _pEntry->pNext = nullptr;
74 |
75 | if (pLast)
76 | {
77 | pLast->pNext = _pEntry;
78 | }
79 | else
80 | {
81 | pFirst = _pEntry;
82 | }
83 |
84 | pLast = _pEntry;
85 | }
86 |
87 | void __YYAPI Push(SingleLinkedList&& _oList) noexcept
88 | {
89 | if (this == &_oList)
90 | return;
91 |
92 | if (_oList.IsEmpty())
93 | return;
94 |
95 | if (pLast == nullptr)
96 | {
97 | pFirst = _oList.pFirst;
98 | pLast = _oList.pLast;
99 | }
100 | else
101 | {
102 | pLast->pNext = _oList.pFirst;
103 | pLast = _oList.pLast;
104 | }
105 | _oList.pFirst = nullptr;
106 | _oList.pLast = nullptr;
107 | }
108 |
109 | constexpr bool __YYAPI IsEmpty() const noexcept
110 | {
111 | return pFirst == nullptr;
112 | }
113 | };
114 |
115 | }
116 | } // namespace Base
117 |
118 | using namespace YY::Base::Containers;
119 | } // namespace YY
120 |
121 | #pragma pack(pop)
122 |
--------------------------------------------------------------------------------
/Include/Base/Encoding.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace YY
5 | {
6 | namespace Base
7 | {
8 | enum class Encoding
9 | {
10 | // 使用默认代码页的ANSI,具体取决与运行环境
11 | ANSI = 0,
12 |
13 | GB2312 = 936,
14 | // 小端编码方式的 UTF16
15 | UTF16LE = 1200,
16 | // 大端编码方式的 UTF16
17 | UTF16BE = 1201,
18 | // 默认UTF16值,自动根据平台选择大小端
19 | UTF16 = UTF16LE,
20 |
21 | // 小端编码方式的 UTF32
22 | UTF32LE = 12000,
23 | // 大端编码方式的 UTF32
24 | UTF32BE = 12001,
25 | // 默认UTF32值,自动根据平台选择大小端
26 | UTF32 = UTF32LE,
27 |
28 | UTF8 = 65001,
29 | // 本机wchar_t编码
30 | UTFW = sizeof(wchar_t) == 2 ? UTF16 : UTF32,
31 | // 最佳Unciode编码
32 | UTFN = sizeof(uchar_t) == 1 ? UTF8 : UTFW,
33 |
34 | };
35 |
36 | template
37 | struct DetaultEncoding;
38 |
39 | template<>
40 | struct DetaultEncoding
41 | {
42 | static constexpr Encoding eEncoding = Encoding::ANSI;
43 | };
44 |
45 | #if defined(__cpp_lib_char8_t) || defined(__cpp_char8_t)
46 | template<>
47 | struct DetaultEncoding
48 | {
49 | static constexpr Encoding eEncoding = Encoding::UTF8;
50 | };
51 | #endif
52 |
53 | template<>
54 | struct DetaultEncoding
55 | {
56 | static constexpr Encoding eEncoding = Encoding::UTF16;
57 | };
58 |
59 | template<>
60 | struct DetaultEncoding
61 | {
62 | static constexpr Encoding eEncoding = Encoding::UTF32;
63 | };
64 |
65 | inline bool __YYAPI IsANSI(Encoding _eEncoding)
66 | {
67 | switch (_eEncoding)
68 | {
69 | case Encoding::UTF8:
70 | case Encoding::UTF16LE:
71 | case Encoding::UTF16BE:
72 | case Encoding::UTF32LE:
73 | case Encoding::UTF32BE:
74 | return false;
75 | default:
76 | return true;
77 | }
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Include/Base/ErrorCode.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #ifdef _WIN32
4 | #include
5 | #endif
6 |
7 | #include
8 |
9 | namespace YY
10 | {
11 | namespace Base
12 | {
13 | #ifndef _WIN32
14 | #ifndef SUCCEEDED
15 | #define SUCCEEDED(hr) (((HRESULT)(hr)) >= 0)
16 | #endif
17 |
18 | #ifndef FAILED
19 | #define FAILED(hr) (((HRESULT)(hr)) < 0)
20 | #endif
21 |
22 | constexpr HRESULT S_OK = 0;
23 | constexpr HRESULT S_FALSE = 0;
24 |
25 | constexpr HRESULT E_INVALIDARG = 1;
26 | constexpr HRESULT E_OUTOFMEMORY = 2;
27 | constexpr HRESULT E_POINTER = 3;
28 | constexpr HRESULT E_UNEXPECTED = 4;
29 | constexpr HRESULT E_BOUNDS = 5;
30 | constexpr HRESULT E_NOINTERFACE = 5;
31 | constexpr HRESULT E_NOTIMPL = 5;
32 | constexpr HRESULT E_FAIL = 5;
33 | constexpr HRESULT E_PENDING = 5;
34 | constexpr HRESULT E_ABORT = 5;
35 | constexpr HRESULT E_NOT_SET = 5;
36 |
37 | constexpr LSTATUS ERROR_SUCCESS = 0;
38 | constexpr LSTATUS ERROR_CANCELLED = 5;
39 | constexpr LSTATUS ERROR_BAD_FORMAT = 5;
40 | #endif
41 | constexpr inline _Translates_Win32_to_HRESULT_(_lStatus) HRESULT HRESULT_From_LSTATUS(_In_ LSTATUS _lStatus) noexcept
42 | {
43 | if (_lStatus == ERROR_SUCCESS)
44 | return S_OK;
45 | #ifdef _WIN32
46 | return __HRESULT_FROM_WIN32(_lStatus);
47 | #else
48 | return ((HRESULT)(_lStatus) <= 0 ? ((HRESULT)(_lStatus)) : ((HRESULT)(((_lStatus) & 0x0000FFFF) | (/*FACILITY_WIN32*/ 7 << 16) | 0x80000000)));
49 | #endif
50 | }
51 |
52 |
53 | #ifdef _WIN32
54 | inline LSTATUS WINAPI DosErrorFormNtStatus(long _Status) noexcept
55 | {
56 | if (_Status == 0)
57 | return ERROR_SUCCESS;
58 |
59 | static void* g_pfnRtlNtStatusToDosError = nullptr;
60 |
61 | if (g_pfnRtlNtStatusToDosError == nullptr)
62 | {
63 | auto _pfn = GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlNtStatusToDosError");
64 | if (_pfn)
65 | {
66 | g_pfnRtlNtStatusToDosError = _pfn;
67 | }
68 | else
69 | {
70 | g_pfnRtlNtStatusToDosError = (void*)-1;
71 | }
72 | }
73 |
74 | if (g_pfnRtlNtStatusToDosError == (void*)-1)
75 | {
76 | // 找不到这函数就转换到一个通用错误。
77 | return E_FAIL;
78 | }
79 |
80 | return ((decltype(DosErrorFormNtStatus)*)g_pfnRtlNtStatusToDosError)(_Status);
81 | }
82 | #endif
83 | }
84 | } // namespace YY::Base
85 |
86 | namespace YY
87 | {
88 | using namespace YY::Base;
89 | }
90 |
--------------------------------------------------------------------------------
/Include/Base/Exception.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #include
5 |
6 | #pragma pack(push, __YY_PACKING)
7 |
8 | namespace YY
9 | {
10 | namespace Base
11 | {
12 | class Exception : public std::exception
13 | {
14 | private:
15 | const uchar_t* szErrorMessage;
16 | HRESULT hr;
17 |
18 | public:
19 | ///
20 | /// 构造一个 Exception
21 | ///
22 | /// 必须指向一个常量或者有用足够声明周期的缓冲区,Exception不负责维护
23 | /// 错误代码
24 | Exception(const uchar_t* _szErrorMessage = nullptr, HRESULT _hr = 0x8000FFFFL /* E_UNEXPECTED */)
25 | : szErrorMessage(_szErrorMessage)
26 | , hr(_hr)
27 | {
28 | }
29 |
30 | Exception(HRESULT _hr)
31 | : szErrorMessage(nullptr)
32 | , hr(_hr)
33 | {
34 | }
35 |
36 | HRESULT __YYAPI GetErrorCode() const
37 | {
38 | return hr;
39 | }
40 |
41 | const uchar_t* __YYAPI GetErrorMessage() const
42 | {
43 | return szErrorMessage ? szErrorMessage : _S("");
44 | }
45 | };
46 | } // namespace Base
47 | } // namespace YY
48 |
49 | #pragma pack(pop)
50 |
--------------------------------------------------------------------------------
/Include/Base/Memory/Alloc.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 |
6 | #include
7 |
8 | namespace YY
9 | {
10 | namespace Base
11 | {
12 | namespace Memory
13 | {
14 | _Success_(return != NULL) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_cbSize)
15 | _CRTALLOCATOR
16 | inline void* Alloc(_In_ size_t _cbSize)
17 | {
18 | return malloc(_cbSize);
19 | }
20 |
21 | _Success_(return != NULL) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_cbSize)
22 | _CRTALLOCATOR
23 | inline void* AllocAndZero(_In_ size_t _cbSize)
24 | {
25 | return calloc(1, _cbSize);
26 | }
27 |
28 | _Success_(return != NULL) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_cbSize)
29 | _CRTALLOCATOR
30 | inline void* ReAlloc(_Pre_maybenull_ _Post_invalid_ void* _pBlock, _In_ size_t _cbSize)
31 | {
32 | return realloc(_pBlock, _cbSize);
33 | }
34 |
35 | _Success_(return != NULL) _Check_return_ _Ret_maybenull_ _Post_writable_byte_size_(_cbSize)
36 | _CRTALLOCATOR
37 | inline void* ReAllocAndZero(_Pre_maybenull_ _Post_invalid_ void* _pBlock, _In_ size_t _cbSize)
38 | {
39 | #ifdef _MSC_VER
40 | return _recalloc(_pBlock, 1, _cbSize);
41 | #else
42 | auto _pNewBlock = realloc(_pBlock, _cbSize);
43 | if (_pNewBlock)
44 | {
45 | ::memset(_pNewBlock, 0, _cbSize);
46 | }
47 | return _pNewBlock;
48 | #endif
49 | }
50 |
51 | inline void Free(_Pre_maybenull_ _Post_invalid_ void* _pBlock)
52 | {
53 | free(_pBlock);
54 | }
55 |
56 | template
57 | _Success_(return != NULL) _Check_return_ _Ret_maybenull_
58 | _CRTALLOCATOR
59 | inline T* New(Args&&... args)
60 | {
61 | T* _p = (T*)Alloc(sizeof(T));
62 | if (_p)
63 | new (_p) T(std::forward(args)...);
64 |
65 | return _p;
66 | }
67 |
68 | template
69 | _Success_(return != NULL) _Check_return_ _Ret_maybenull_
70 | _CRTALLOCATOR
71 | inline T* NewAndZero(Args&&... args)
72 | {
73 | T* _p = (T*)AllocAndZero(sizeof(T));
74 | if (_p)
75 | new (_p) T(std::forward(args)...);
76 |
77 | return _p;
78 | }
79 |
80 | template
81 | inline void Delete(_Pre_maybenull_ _Post_invalid_ T* _pObject)
82 | {
83 | if (_pObject)
84 | {
85 | _pObject->~T();
86 | Free(_pObject);
87 | }
88 | }
89 | } // namespace Memory
90 | } // namespace Base
91 | using namespace YY::Base::Memory;
92 | } // namespace YY
93 |
--------------------------------------------------------------------------------
/Include/Base/Memory/WeakPtr.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #pragma pack(push, __YY_PACKING)
8 |
9 | namespace YY
10 | {
11 | namespace Base
12 | {
13 | namespace Memory
14 | {
15 | template
16 | class RefPtr;
17 |
18 | template
19 | class WeakPtrRef
20 | {
21 | };
22 |
23 | template
24 | class WeakPtr
25 | {
26 | private:
27 | _Type* p;
28 |
29 | public:
30 | constexpr WeakPtr() noexcept
31 | : p(nullptr)
32 | {
33 | }
34 |
35 | WeakPtr(_In_opt_ _Type* _pOther) noexcept
36 | : p(_pOther)
37 | {
38 | if (p)
39 | p->AddWeakRef();
40 | }
41 |
42 | constexpr WeakPtr(_In_opt_ WeakPtrRef<_Type>* _pOther) noexcept
43 | : p(reinterpret_cast<_Type*>(_pOther))
44 | {
45 | }
46 |
47 | WeakPtr(_In_ const WeakPtr& _pOther) noexcept
48 | : WeakPtr(_pOther.p)
49 | {
50 | }
51 |
52 | WeakPtr(_In_ WeakPtr&& _pOther) noexcept
53 | : p(_pOther.p)
54 | {
55 | _pOther.p = nullptr;
56 | }
57 |
58 | ~WeakPtr()
59 | {
60 | if (p)
61 | p->ReleaseWeak();
62 | }
63 |
64 | inline void __YYAPI Attach(_In_opt_ WeakPtrRef<_Type>* _pOther) noexcept
65 | {
66 | if (p)
67 | p->ReleaseWeak();
68 | p = reinterpret_cast<_Type*>(_pOther);
69 | }
70 |
71 | inline _Ret_maybenull_ WeakPtrRef<_Type>* __YYAPI Detach() noexcept
72 | {
73 | auto _p = p;
74 | p = nullptr;
75 | return reinterpret_cast*>(_p);
76 | }
77 |
78 | _Ret_maybenull_ RefPtr<_Type> __YYAPI Get() const noexcept
79 | {
80 | RefPtr<_Type> _pTmp;
81 |
82 | if (p && p->TryAddRef())
83 | {
84 | _pTmp.Attach(p);
85 | }
86 | return _pTmp;
87 | }
88 |
89 | bool operator==(_In_opt_ _Type* _pOther) const noexcept
90 | {
91 | return p == _pOther;
92 | }
93 |
94 | bool operator==(_In_opt_ const WeakPtr& _pOther) const noexcept
95 | {
96 | return p == _pOther.p;
97 | }
98 |
99 | WeakPtr& operator=(std::nullptr_t) noexcept
100 | {
101 | if (p)
102 | p->ReleaseWeak();
103 |
104 | p = nullptr;
105 | return *this;
106 | }
107 |
108 | WeakPtr& operator=(_In_opt_ _Type* _pOther) noexcept
109 | {
110 | if (p != _pOther)
111 | {
112 | if (p)
113 | p->ReleaseWeak();
114 |
115 | p = _pOther;
116 |
117 | if (p)
118 | p->AddWeakRef();
119 | }
120 | return *this;
121 | }
122 |
123 | WeakPtr& operator=(const WeakPtr& _pOther) noexcept
124 | {
125 | return this->operator=(_pOther.p);
126 | }
127 |
128 | WeakPtr& operator=(const WeakPtr&& _pOther) noexcept
129 | {
130 | if (&_pOther != this)
131 | {
132 | if (p)
133 | p->ReleaseWeak();
134 |
135 | p = _pOther.p;
136 | _pOther.p = nullptr;
137 | }
138 |
139 | return *this;
140 | }
141 | };
142 | }
143 | }
144 | }
145 |
146 | namespace YY
147 | {
148 | using namespace YY::Base::Memory;
149 | }
150 |
151 | #pragma pack(pop)
152 |
--------------------------------------------------------------------------------
/Include/Base/SAL.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #ifdef _PREFAST_
6 | #define __YY_IGNORE_UNINITIALIZED_VARIABLE(_VAR) memset(_VAR, 0, 0);
7 | #else
8 | // 忽略 C6001 警告,使用未初始化的变量警告
9 | #define __YY_IGNORE_UNINITIALIZED_VARIABLE(_VAR)
10 | #endif
11 |
12 | // 禁用函数SAL不一致警告
13 | #ifdef _MSC_VER
14 | #define __YY_IGNORE_INCONSISTENT_ANNOTATION_FOR_FUNCTION() __pragma(warning(disable:28251))
15 | #else
16 | #define __YY_IGNORE_INCONSISTENT_ANNOTATION_FOR_FUNCTION()
17 | #endif
18 |
19 | #ifndef _CRTALLOCATOR
20 | #define _CRTALLOCATOR
21 | #endif
22 |
23 | // SAL Downlevel
24 | #ifndef _Return_type_success_
25 | #define _Return_type_success_(expr)
26 | #endif
27 |
28 | #ifndef _Success_
29 | #define _Success_(expr)
30 | #endif
31 |
32 | #ifndef _When_
33 | #define _When_(expr, annos)
34 | #endif
35 |
36 | #ifndef _In_
37 | #define _In_
38 | #endif
39 |
40 | #ifndef _In_opt_
41 | #define _In_opt_ _In_
42 | #endif
43 |
44 | #ifndef _In_z_
45 | #define _In_z_ _In_
46 | #endif
47 |
48 | #ifndef _Inout_
49 | #define _Inout_
50 | #endif
51 |
52 | #ifndef _In_opt_z_
53 | #define _In_opt_z_ _In_opt_
54 | #endif
55 |
56 | #ifndef _In_reads_
57 | #define _In_reads_(size) _In_
58 | #endif
59 |
60 | #ifndef _In_reads_bytes_
61 | #define _In_reads_bytes_(size) _In_
62 | #endif
63 |
64 | #ifndef _In_reads_opt_
65 | #define _In_reads_opt_(size) _In_opt_
66 | #endif
67 |
68 | #ifndef _In_range_
69 | #define _In_range_(lb,ub) _In_
70 | #endif
71 |
72 | #ifndef _Out_
73 | #define _Out_
74 | #endif
75 |
76 | #ifndef _Out_opt_
77 | #define _Out_opt_ _Out_
78 | #endif
79 |
80 | #ifndef _Out_writes_
81 | #define _Out_writes_(size) _Out_
82 | #endif
83 |
84 | #ifndef _Outptr_
85 | #define _Outptr_ _Out_
86 | #endif
87 |
88 | #ifndef _Inout_cap_
89 | #define _Inout_cap_(size)
90 | #endif
91 |
92 | #ifndef _Always_
93 | #define _Always_(annos)
94 | #endif
95 |
96 | #ifndef _Ret_notnull_
97 | #define _Ret_notnull_
98 | #endif
99 |
100 | #ifndef _Ret_z_
101 | #define _Ret_z_
102 | #endif
103 |
104 | #ifndef _Ret_maybenull_
105 | #define _Ret_maybenull_
106 | #endif
107 |
108 | #ifndef _Ret_writes_maybenull_
109 | #define _Ret_writes_maybenull_(size) _Ret_maybenull_
110 | #endif
111 |
112 | #ifndef _Post_readable_size_
113 | #define _Post_readable_size_(size)
114 | #endif
115 |
116 | #ifndef _Field_size_
117 | #define _Field_size_(size)
118 | #endif
119 |
120 | #ifndef _Field_z_
121 | #define _Field_z_
122 | #endif
123 |
124 | #ifndef _Null_terminated_
125 | #define _Null_terminated_
126 | #endif
127 |
128 | #ifndef _Return_type_success_
129 | #define _Return_type_success_(expr)
130 | #endif
131 |
132 | #ifndef _Printf_format_string_
133 | #define _Printf_format_string_
134 | #endif
135 |
136 | #ifndef _Translates_Win32_to_HRESULT_
137 | #define _Translates_Win32_to_HRESULT_(errorCode)
138 | #endif
139 |
140 | #ifndef _Check_return_
141 | #define _Check_return_
142 | #endif
143 |
144 | #ifndef _Pre_maybenull_
145 | #define _Pre_maybenull_
146 | #endif
147 |
148 | #ifndef _Post_invalid_
149 | #define _Post_invalid_
150 | #endif
151 |
152 | #ifndef _Post_writable_byte_size_
153 | #define _Post_writable_byte_size_(size)
154 | #endif
155 |
156 | #ifndef _Acquires_exclusive_lock_
157 | #define _Acquires_exclusive_lock_(e)
158 | #endif
159 |
160 | #ifndef _Releases_exclusive_lock_
161 | #define _Releases_exclusive_lock_(e)
162 | #endif
163 |
164 | #ifndef _Acquires_shared_lock_
165 | #define _Acquires_shared_lock_(e)
166 | #endif
167 |
168 | #ifndef _Releases_shared_lock_
169 | #define _Releases_shared_lock_(e)
170 | #endif
171 |
--------------------------------------------------------------------------------
/Include/Base/SafeCast.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 | #include
5 |
6 | namespace YY
7 | {
8 | namespace Base
9 | {
10 | template
11 | bool SafeCast(_In_ const InType& _oIn, _Out_opt_ OutType* _pOut) noexcept;
12 |
13 | ///
14 | /// 安全的类型转换,如果失败则抛出异常。
15 | ///
16 | ///
17 | ///
18 | template
19 | inline OutType SafeCast(_In_ const InType& _oIn) noexcept(false)
20 | {
21 | OutType _oOut;
22 | if (!SafeCast(_oIn, &_oOut))
23 | {
24 | throw Exception(_S("指定类型转换失败。"), E_INVALIDARG);
25 | }
26 |
27 | return _oOut;
28 | }
29 |
30 | template<>
31 | inline bool SafeCast(_In_ const int32_t& _oIn, _Out_opt_ uint8_t* _pOut) noexcept
32 | {
33 | if (_oIn > UINT8_MAX || _oIn < 0)
34 | return false;
35 |
36 | if (_pOut)
37 | *_pOut = (uint8_t)_oIn;
38 | return true;
39 | }
40 |
41 | template<>
42 | inline bool SafeCast(_In_ const uint32_t& _oIn, _Out_opt_ uint16_t* _pOut) noexcept
43 | {
44 | if (_oIn > UINT16_MAX || _oIn < 0)
45 | return false;
46 |
47 | if (_pOut)
48 | *_pOut = (uint16_t)_oIn;
49 | return true;
50 | }
51 |
52 | template
53 | Type* RemoveVolatileCast(volatile Type* _pIn)
54 | {
55 | return const_cast(_pIn);
56 | }
57 |
58 | } // namespace Base
59 | } // namespace YY
60 |
--------------------------------------------------------------------------------
/Include/Base/Strings/StringTransform.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace YY
5 | {
6 | namespace Base
7 | {
8 | namespace Strings
9 | {
10 | // To ANSI
11 | HRESULT __YYAPI Transform(_In_ const aStringView& _szSrc, _Inout_ aString* _pszDst);
12 | HRESULT __YYAPI Transform(_In_ const u8StringView& _szSrc, _Inout_ aString* _pszDst);
13 | HRESULT __YYAPI Transform(_In_ const u16StringLEView& _szSrc, _Inout_ aString* _pszDst);
14 | HRESULT __YYAPI Transform(_In_ const u16StringBEView& _szSrc, _Inout_ aString* _pszDst);
15 | HRESULT __YYAPI Transform(_In_ const u32StringLEView& _szSrc, _Inout_ aString* _pszDst);
16 | HRESULT __YYAPI Transform(_In_ const u32StringBEView& _szSrc, _Inout_ aString* _pszDst);
17 |
18 | HRESULT __YYAPI Transform(_In_ const aString& _szSrc, _Inout_ aString* _pszDst);
19 |
20 | // To UTF8
21 | HRESULT __YYAPI Transform(_In_ const aStringView& _szSrc, _Inout_ u8String* _pszDst);
22 | HRESULT __YYAPI Transform(_In_ const u8StringView& _szSrc, _Inout_ u8String* _pszDst);
23 | HRESULT __YYAPI Transform(_In_ const u16StringLEView& _szSrc, _Inout_ u8String* _pszDst);
24 | HRESULT __YYAPI Transform(_In_ const u16StringBEView& _szSrc, _Inout_ u8String* _pszDst);
25 | HRESULT __YYAPI Transform(_In_ const u32StringLEView& _szSrc, _Inout_ u8String* _pszDst);
26 | HRESULT __YYAPI Transform(_In_ const u32StringBEView& _szSrc, _Inout_ u8String* _pszDst);
27 |
28 | HRESULT __YYAPI Transform(_In_ const u8String& _szSrc, _Inout_ u8String* _pszDst);
29 |
30 | // To UTF16LE
31 | HRESULT __YYAPI Transform(_In_ const aStringView& _szSrc, _Inout_ u16StringLE* _pszDst);
32 | HRESULT __YYAPI Transform(_In_ const u8StringView& _szSrc, _Inout_ u16StringLE* _pszDst);
33 | HRESULT __YYAPI Transform(_In_ const u16StringLEView& _szSrc, _Inout_ u16StringLE* _pszDst);
34 | HRESULT __YYAPI Transform(_In_ const u16StringBEView& _szSrc, _Inout_ u16StringLE* _pszDst);
35 | HRESULT __YYAPI Transform(_In_ const u32StringLEView& _szSrc, _Inout_ u16StringLE* _pszDst);
36 | HRESULT __YYAPI Transform(_In_ const u32StringBEView& _szSrc, _Inout_ u16StringLE* _pszDst);
37 |
38 | HRESULT __YYAPI Transform(_In_ const u16StringLE& _szSrc, _Inout_ u16StringLE* _pszDst);
39 | HRESULT __YYAPI Transform(_In_ u16StringBE&& _szSrc, _Inout_ u16StringLE* _pszDst);
40 |
41 | // To UTF16BE
42 | HRESULT __YYAPI Transform(_In_ const aStringView& _szSrc, _Inout_ u16StringBE* pszDst);
43 | HRESULT __YYAPI Transform(_In_ const u8StringView& _szSrc, _Inout_ u16StringBE* pszDst);
44 | HRESULT __YYAPI Transform(_In_ const u16StringLEView& _szSrc, _Inout_ u16StringBE* pszDst);
45 | HRESULT __YYAPI Transform(_In_ const u16StringBEView& _szSrc, _Inout_ u16StringBE* pszDst);
46 | HRESULT __YYAPI Transform(_In_ const u32StringLEView& _szSrc, _Inout_ u16StringBE* pszDst);
47 | HRESULT __YYAPI Transform(_In_ const u32StringBEView& _szSrc, _Inout_ u16StringBE* pszDst);
48 |
49 | HRESULT __YYAPI Transform(_In_ u16StringLE&& _szSrc, _Inout_ u16StringBE* pszDst);
50 | HRESULT __YYAPI Transform(_In_ const u16StringBE& _szSrc, _Inout_ u16StringBE* pszDst);
51 |
52 | // To UTF32LE
53 | HRESULT __YYAPI Transform(_In_ const aStringView& _szSrc, _Inout_ u32StringLE* pszDst);
54 | HRESULT __YYAPI Transform(_In_ const u8StringView& _szSrc, _Inout_ u32StringLE* pszDst);
55 | HRESULT __YYAPI Transform(_In_ const u16StringLEView& _szSrc, _Inout_ u32StringLE* pszDst);
56 | HRESULT __YYAPI Transform(_In_ const u16StringBEView& _szSrc, _Inout_ u32StringLE* pszDst);
57 | HRESULT __YYAPI Transform(_In_ const u32StringLEView& _szSrc, _Inout_ u32StringLE* pszDst);
58 | HRESULT __YYAPI Transform(_In_ const u32StringBEView& _szSrc, _Inout_ u32StringLE* pszDst);
59 |
60 | HRESULT __YYAPI Transform(_In_ const u32StringLE& _szSrc, _Inout_ u32StringLE* pszDst);
61 | HRESULT __YYAPI Transform(_In_ u32StringBE&& _szSrc, _Inout_ u32StringLE* pszDst);
62 |
63 | // To UFT32BE
64 | HRESULT __YYAPI Transform(_In_ const aStringView& _szSrc, _Inout_ u32StringBE* pszDst);
65 | HRESULT __YYAPI Transform(_In_ const u8StringView& _szSrc, _Inout_ u32StringBE* pszDst);
66 | HRESULT __YYAPI Transform(_In_ const u16StringLEView& _szSrc, _Inout_ u32StringBE* pszDst);
67 | HRESULT __YYAPI Transform(_In_ const u16StringBEView& _szSrc, _Inout_ u32StringBE* pszDst);
68 | HRESULT __YYAPI Transform(_In_ const u32StringLEView& _szSrc, _Inout_ u32StringBE* pszDst);
69 | HRESULT __YYAPI Transform(_In_ const u32StringBEView& _szSrc, _Inout_ u32StringBE* pszDst);
70 |
71 | HRESULT __YYAPI Transform(_In_ u32StringLE&& _szSrc, _Inout_ u32StringBE* pszDst);
72 | HRESULT __YYAPI Transform(_In_ const u32StringBE& _szSrc, _Inout_ u32StringBE* pszDst);
73 | } // namespace Strings
74 | } // namespace Base
75 |
76 | using namespace YY::Base::Strings;
77 | } // namespace YY
78 |
--------------------------------------------------------------------------------
/Include/Base/Sync/AutoLock.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #pragma pack(push, __YY_PACKING)
6 |
7 | namespace YY
8 | {
9 | namespace Base
10 | {
11 | namespace Sync
12 | {
13 | template
14 | class AutoLock
15 | {
16 | private:
17 | LockType& oLock;
18 |
19 | public:
20 | constexpr AutoLock(LockType& _oLock)
21 | : oLock(_oLock)
22 | {
23 | oLock.Lock();
24 | }
25 |
26 | AutoLock(const AutoLock&) = delete;
27 | AutoLock& operator=(const AutoLock&) = delete;
28 |
29 | ~AutoLock()
30 | {
31 | oLock.Unlock();
32 | }
33 | };
34 |
35 | template
36 | class AutoSharedLock
37 | {
38 | private:
39 | LockType& oLock;
40 |
41 | public:
42 | constexpr AutoSharedLock(LockType& _oLock)
43 | : oLock(_oLock)
44 | {
45 | oLock.LockShared();
46 | }
47 |
48 | AutoSharedLock(const AutoSharedLock&) = delete;
49 | AutoSharedLock& operator=(const AutoSharedLock&) = delete;
50 |
51 | ~AutoSharedLock()
52 | {
53 | oLock.UnlockShared();
54 | }
55 | };
56 | }
57 | }
58 | }
59 |
60 | #pragma pack(pop)
61 |
--------------------------------------------------------------------------------
/Include/Base/Sync/CriticalSection.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 | #include
5 | #include
6 |
7 | #pragma pack(push, __YY_PACKING)
8 |
9 | namespace YY
10 | {
11 | namespace Base
12 | {
13 | namespace Sync
14 | {
15 | class CriticalSection
16 | {
17 | private:
18 | SRWLock oSRWLock;
19 | ThreadId uOwnerThreadId = 0;
20 | uint32_t uLockRef = 0;
21 |
22 | public:
23 | constexpr CriticalSection() noexcept = default;
24 |
25 | CriticalSection(const CriticalSection&) = delete;
26 | CriticalSection& operator=(const CriticalSection&) = delete;
27 |
28 | _Acquires_exclusive_lock_(*this)
29 | void __YYAPI Lock() noexcept;
30 |
31 | _When_(return != 0, _Acquires_exclusive_lock_(*this))
32 | bool __YYAPI TryLock() noexcept;
33 |
34 | _Releases_exclusive_lock_(*this)
35 | void __YYAPI Unlock() noexcept;
36 | };
37 | }
38 | }
39 |
40 | using namespace YY::Base::Sync;
41 | }
42 |
43 | #pragma pack(pop)
44 |
--------------------------------------------------------------------------------
/Include/Base/Sync/InterlockedQueue.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | #pragma pack(push, __YY_PACKING)
6 |
7 | namespace YY
8 | {
9 | namespace Base
10 | {
11 | namespace Sync
12 | {
13 | template
14 | class InterlockedQueue;
15 |
16 | template
17 | class InterlockedQueue
18 | {
19 | private:
20 | struct Block
21 | {
22 | size_t uLastReadIndex = 0;
23 | size_t uLastWriteIndex = 0;
24 | Block* pNextBlock = nullptr;
25 | Entry* arrLoopBuffer[uMaxBlockSize];
26 |
27 | bool IsEmpty()
28 | {
29 | return uLastReadIndex == uLastWriteIndex;
30 | }
31 |
32 | bool IsFull()
33 | {
34 | return uLastReadIndex + uMaxBlockSize == uLastWriteIndex;
35 | }
36 | };
37 |
38 | Block* pFirstReadBlock = nullptr;
39 | Block* pLastWriteBlock = nullptr;
40 |
41 | public:
42 | _Ret_maybenull_ Entry* Pop() noexcept
43 | {
44 | if (!pFirstReadBlock)
45 | return nullptr;
46 |
47 | for (;;)
48 | {
49 | // 当前块任然有元素?
50 | if (!pFirstReadBlock->IsEmpty())
51 | {
52 | auto _pTmp = pFirstReadBlock->arrLoopBuffer[pFirstReadBlock->uLastReadIndex % uMaxBlockSize];
53 | pFirstReadBlock->uLastReadIndex += 1;
54 | return _pTmp;
55 | }
56 |
57 | // 尝试流转到下一块
58 | if (!pFirstReadBlock->pNextBlock)
59 | return nullptr;
60 |
61 | auto _pPendingDelete = pFirstReadBlock;
62 | pFirstReadBlock = pFirstReadBlock->pNextBlock;
63 | Delete(_pPendingDelete);
64 | }
65 |
66 | return nullptr;
67 | }
68 |
69 | void Push(_In_ Entry* _pEntry)
70 | {
71 | if (!pLastWriteBlock)
72 | {
73 | pFirstReadBlock = pLastWriteBlock = New();
74 | }
75 |
76 | // 如果满了就尝试链接到下一块
77 | if (pLastWriteBlock->IsFull())
78 | {
79 | auto _pNextBlock = New();
80 | pLastWriteBlock->pNextBlock = _pNextBlock;
81 | pLastWriteBlock = _pNextBlock;
82 | }
83 |
84 | pLastWriteBlock->arrLoopBuffer[pLastWriteBlock->uLastWriteIndex % uMaxBlockSize] = _pEntry;
85 | pLastWriteBlock->uLastWriteIndex += 1;
86 | }
87 | };
88 | }
89 | }
90 | } // namespace YY::Base::Sync
91 |
92 | namespace YY
93 | {
94 | using namespace YY::Base::Sync;
95 | }
96 |
97 | #pragma pack(pop)
98 |
--------------------------------------------------------------------------------
/Include/Base/Sync/InterlockedSingleLinkedList.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #pragma pack(push, __YY_PACKING)
6 |
7 | namespace YY
8 | {
9 | namespace Base
10 | {
11 | namespace Sync
12 | {
13 | template
14 | struct InterlockedSingleLinkedEntryBase
15 | {
16 | Entry* pNext = nullptr;
17 | };
18 |
19 | template
20 | class InterlockedSingleLinkedList;
21 |
22 | template
23 | class InterlockedSingleLinkedList
24 | {
25 | public:
26 | // 一般不应该直接操作此成员
27 | Entry volatile* pHead;
28 |
29 | constexpr InterlockedSingleLinkedList()
30 | : pHead(nullptr)
31 | {
32 | }
33 |
34 | ~InterlockedSingleLinkedList()
35 | {
36 | for (auto _pEntry = Flush(); _pEntry;)
37 | {
38 | auto _pNext = _pEntry->pNext;
39 | delete _pEntry;
40 | _pEntry = _pNext;
41 | }
42 | }
43 |
44 | InterlockedSingleLinkedList(const InterlockedSingleLinkedList&) = delete;
45 | InterlockedSingleLinkedList& operator=(const InterlockedSingleLinkedList&) = delete;
46 |
47 | ///
48 | /// 向单向链表插入一段链表。
49 | /// 注意:_pEntryBegin -> ... -> _pEntryEnd之间的元素必须首尾相连,不能产生环路,否则将死循环。
50 | /// 注意:无锁单向链表为了实现无锁,其插入是倒序的。
51 | /// 插入前:Head -> ABC
52 | /// 插入后:Head -> _pEntryBegin -> ... -> _pEntryEnd -> ABC
53 | ///
54 | ///
55 | ///
56 | void Push(_In_ Entry* _pEntryBegin, _In_ Entry* _pEntryEnd)
57 | {
58 | auto _pEntry = (Entry*)pHead;
59 | for (;;)
60 | {
61 | _pEntryEnd->pNext = _pEntry;
62 |
63 | auto _pLast = CompareExchangePoint(&pHead, _pEntryBegin, _pEntry);
64 | if (_pLast != _pEntry)
65 | {
66 | _pEntry = _pLast;
67 | // 锁定失败,换个姿势再来一次。
68 | continue;
69 | }
70 | break;
71 | }
72 | }
73 |
74 | ///
75 | /// 向单向链表插入一个元素。
76 | /// 注意:无锁单向链表为了实现无锁,其插入是倒序的。
77 | /// 插入前:Head -> ABC
78 | /// 插入后:Head -> _pEntry -> ABC
79 | ///
80 | /// 需要插入的元素。
81 | void Push(_In_ Entry* _pEntry)
82 | {
83 | return Push(_pEntry, _pEntry);
84 | }
85 |
86 | ///
87 | /// 从链表弹出一个元素。
88 | /// 警告:Pop不能并行调用,这可能导致内存非法访问。
89 | /// 警告:Pop不能与Flush并行调用,这可能导致内存非法访问。
90 | ///
91 | /// 返回当前List头部元素。
92 | Entry* Pop()
93 | {
94 | auto _pEntry = (Entry*)pHead;
95 | for (;;)
96 | {
97 | if (_pEntry == nullptr)
98 | break;
99 |
100 | // 注意,如果多线程调用此函数,`_pEntry->pNext` 可能非法访问。
101 | auto _pLast = CompareExchangePoint((Entry**)&pHead, _pEntry->pNext, _pEntry);
102 | if (_pLast == _pEntry)
103 | {
104 | _pEntry->pNext = nullptr;
105 | break;
106 | }
107 |
108 | // 交换失败,继续尝试
109 | _pEntry = _pLast;
110 | }
111 |
112 | return _pEntry;
113 | }
114 |
115 | ///
116 | /// 清空当前列表,并返回之前链表的首个元素。
117 | /// 警告:Flush不能与Pop并行调用,这可能导致内存非法访问。
118 | ///
119 | /// 链表的首个元素地址。
120 | Entry* Flush()
121 | {
122 | return ExchangePoint((Entry**)&pHead, (Entry*)nullptr);
123 | }
124 | };
125 | }
126 | }
127 | }
128 |
129 | namespace YY
130 | {
131 | using namespace YY::Base::Sync;
132 | }
133 |
134 | #pragma pack(pop)
135 |
--------------------------------------------------------------------------------
/Include/Base/Sync/SRWLock.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 | #pragma pack(push, __YY_PACKING)
6 |
7 | namespace YY
8 | {
9 | namespace Base
10 | {
11 | namespace Sync
12 | {
13 | #ifdef _WIN32
14 | class SRWLock
15 | {
16 | private:
17 | SRWLOCK oSRWLock = RTL_SRWLOCK_INIT;
18 |
19 | public:
20 | constexpr SRWLock() noexcept = default;
21 |
22 | SRWLock(const SRWLock&) = delete;
23 | SRWLock& operator=(const SRWLock&) = delete;
24 |
25 | _Acquires_exclusive_lock_(this->oSRWLock)
26 | void __YYAPI Lock() noexcept
27 | {
28 | AcquireSRWLockExclusive(&oSRWLock);
29 | }
30 |
31 | _When_(return != 0, _Acquires_exclusive_lock_(this->oSRWLock))
32 | bool __YYAPI TryLock() noexcept
33 | {
34 | return TryAcquireSRWLockExclusive(&oSRWLock);
35 | }
36 |
37 | _Releases_exclusive_lock_(this->oSRWLock)
38 | void __YYAPI Unlock() noexcept
39 | {
40 | ReleaseSRWLockExclusive(&oSRWLock);
41 | }
42 |
43 | _When_(return != 0, _Acquires_shared_lock_(this->oSRWLock))
44 | bool __YYAPI TryLockShared() noexcept
45 | {
46 | return TryAcquireSRWLockShared(&oSRWLock);
47 | }
48 |
49 | _Acquires_shared_lock_(this->oSRWLock)
50 | void __YYAPI LockShared() noexcept
51 | {
52 | AcquireSRWLockShared(&oSRWLock);
53 | }
54 |
55 | _Releases_shared_lock_(this->oSRWLock)
56 | void __YYAPI UnlockShared() noexcept
57 | {
58 | ReleaseSRWLockShared(&oSRWLock);
59 | }
60 | };
61 |
62 | #else
63 | class SRWLock
64 | {
65 | private:
66 | uintptr_t uInternalValue = 0;
67 |
68 | public:
69 | constexpr SRWLock() noexcept = default;
70 |
71 | SRWLock(const SRWLock&) = delete;
72 | SRWLock& operator=(const SRWLock&) = delete;
73 |
74 | _Acquires_exclusive_lock_(this->oSRWLock)
75 | void __YYAPI Lock() noexcept;
76 |
77 | _When_(return != 0, _Acquires_exclusive_lock_(this->oSRWLock))
78 | bool __YYAPI TryLock() noexcept;
79 |
80 | _Releases_exclusive_lock_(this->oSRWLock)
81 | void __YYAPI Unlock() noexcept;
82 |
83 | _When_(return != 0, _Acquires_shared_lock_(this->oSRWLock))
84 | bool __YYAPI TryLockShared() noexcept;
85 |
86 | _Acquires_shared_lock_(this->oSRWLock)
87 | void __YYAPI LockShared() noexcept;
88 |
89 | _Releases_shared_lock_(this->oSRWLock)
90 | void __YYAPI UnlockShared() noexcept;
91 | };
92 | #endif
93 | }
94 | }
95 | }
96 |
97 | #pragma pack(pop)
98 |
--------------------------------------------------------------------------------
/Include/Base/Sync/Sync.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | namespace YY
6 | {
7 | namespace Base
8 | {
9 | namespace Sync
10 | {
11 | #ifdef _WIN32
12 | using ::WaitOnAddress;
13 | using ::WakeByAddressSingle;
14 | using ::WakeByAddressAll;
15 |
16 | #pragma comment(lib, "Synchronization.lib")
17 |
18 | #else // !_WIN32
19 | bool
20 | __YYAPI
21 | WaitOnAddress(
22 | _In_reads_bytes_(AddressSize) volatile void* Address,
23 | _In_reads_bytes_(AddressSize) void* CompareAddress,
24 | _In_ size_t AddressSize,
25 | _In_opt_ uint32_t dwMilliseconds
26 | );
27 |
28 | void
29 | __YYAPI
30 | WakeByAddressSingle(
31 | _In_ void* Address
32 | );
33 |
34 | void
35 | __YYAPI
36 | WakeByAddressAll(
37 | _In_ void* Address
38 | );
39 | #endif // _WIN32
40 |
41 | ///
42 | /// 等待 Address的值等于 CompareAddress
43 | ///
44 | ///
45 | ///
46 | ///
47 | ///
48 | ///
49 | bool __YYAPI WaitEqualOnAddress(
50 | _In_reads_bytes_(AddressSize) volatile void* Address,
51 | _In_reads_bytes_(AddressSize) void* CompareAddress,
52 | _In_ size_t AddressSize,
53 | _In_ TimeSpan _uMilliseconds = TimeSpan::GetMax()) noexcept;
54 | }
55 | } // namespace Base
56 |
57 | using namespace YY::Base::Sync;
58 | } // namespace YY
59 |
--------------------------------------------------------------------------------
/Include/Base/Threading/Coroutine.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #if defined(_HAS_CXX20) && _HAS_CXX20
5 | #include
6 |
7 | #include
8 |
9 | #pragma pack(push, __YY_PACKING)
10 |
11 | namespace YY
12 | {
13 | namespace Base
14 | {
15 | namespace Threading
16 | {
17 | template
18 | struct Promise
19 | {
20 | using ReturnType = ReturnType_;
21 | YY::Optional oValue;
22 |
23 | TaskType get_return_object() noexcept
24 | {
25 | return {};
26 | }
27 | std::suspend_never initial_suspend() noexcept
28 | {
29 | return {};
30 | }
31 |
32 | std::suspend_never final_suspend() noexcept
33 | {
34 | return {};
35 | }
36 |
37 | void return_value(ReturnType&& _oValue) noexcept
38 | {
39 | oValue.Emplace(std::move(_oValue));
40 | }
41 |
42 | void unhandled_exception()
43 | {
44 | }
45 | };
46 |
47 | template
48 | struct Promise
49 | {
50 | using ReturnType = void;
51 |
52 | TaskType get_return_object() noexcept
53 | {
54 | return {};
55 | }
56 | std::suspend_never initial_suspend() noexcept
57 | {
58 | return {};
59 | }
60 |
61 | std::suspend_never final_suspend() noexcept
62 | {
63 | return {};
64 | }
65 |
66 | void return_void() noexcept
67 | {
68 | }
69 | void unhandled_exception()
70 | {
71 | }
72 | };
73 |
74 |
75 | template
76 | struct Coroutine
77 | {
78 | using promise_type = Promise<_ReturnType, Coroutine>;
79 | };
80 | }
81 | }
82 |
83 | using namespace YY::Base::Threading;
84 | }
85 | #pragma pack(pop)
86 |
87 | #endif
88 |
--------------------------------------------------------------------------------
/Include/Base/Threading/ProcessThreads.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #ifndef _WIN32
5 | #include
6 | #include
7 | #include
8 | #endif
9 |
10 | namespace YY
11 | {
12 | namespace Base
13 | {
14 | namespace Threading
15 | {
16 | #ifdef _WIN32
17 | using ThreadId = DWORD;
18 | using ThreadHandle = HANDLE;
19 | constexpr ThreadHandle NullThreadHandle = NULL;
20 |
21 | inline ThreadId __YYAPI GetCurrentThreadId()
22 | {
23 | return ::GetCurrentThreadId();
24 | }
25 | #else
26 | using ThreadId = pid_t;
27 | using ThreadHandle = pthread_t;
28 | constexpr ThreadHandle NullThreadHandle = 0;
29 |
30 | inline ThreadId __YYAPI GetCurrentThreadId()
31 | {
32 | return static_cast(syscall(SYS_gettid));
33 | }
34 | #endif
35 | }
36 | }
37 | } // namespace YY::Base::Threading
38 |
39 | namespace YY
40 | {
41 | using namespace YY::Base::Threading;
42 | }
43 |
--------------------------------------------------------------------------------
/Include/Base/Time/Common.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | namespace YY
4 | {
5 | namespace Base
6 | {
7 | namespace Time
8 | {
9 | enum class TimePrecise
10 | {
11 | // Nanosecond,
12 | Microsecond,
13 | Millisecond,
14 | };
15 |
16 | constexpr int64_t MicrosecondPerNanosecond = 1000000;
17 | constexpr int64_t MillisecondsPerMicrosecond = 1000;
18 | constexpr int64_t SecondsPerMillisecond = 1000;
19 | constexpr int64_t MinutesPerSecond = 60;
20 | constexpr int64_t HoursPerMinute = 60;
21 | constexpr int64_t DaysPerHour = 24;
22 | }
23 | }
24 | }
25 |
26 | namespace YY
27 | {
28 | using namespace YY::Base::Time;
29 | }
30 |
--------------------------------------------------------------------------------
/Include/Base/Utils/FileInfo.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Chuyu-Team/MegaUI/142dfb135d8df5fba4c3591a5e353ed7568322de/Include/Base/Utils/FileInfo.h
--------------------------------------------------------------------------------
/Include/Base/Utils/SystemInfo.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #pragma pack(push, __YY_PACKING)
5 |
6 | namespace YY
7 | {
8 | namespace Base
9 | {
10 | namespace Utils
11 | {
12 | #if defined(_WIN32)
13 | // 版本号参考来源:
14 | // https://github.com/MouriNaruto/MouriDocs/tree/main/docs/18
15 |
16 | // Windows 2000 RTM x86
17 | constexpr Version kWindowsNT5(5, 0, 2195, 0);
18 |
19 | // Windows XP RTM x86
20 | constexpr Version kWindowsNT5_1(5, 1, 2600, 0);
21 |
22 | constexpr Version kWindowsNT5_1_SP1(5, 1, 2600, 1106);
23 |
24 | constexpr Version kWindowsNT5_1_SP2(5, 1, 2600, 2180);
25 |
26 | constexpr Version kWindowsNT5_1_SP3(5, 1, 2600, 5512);
27 |
28 | // Windows 2003 RTM x86
29 | constexpr Version kWindowsNT5_2(5, 2, 3790, 0);
30 |
31 | // Windows XP RTM x64,Windows 2003 SP1
32 | constexpr Version kWindowsNT5_2_SP1(5, 2, 3790, 1830);
33 |
34 | // Windows Vista RTM, Windows Server 2008 RTM
35 | constexpr Version kWindowsNT6(6, 0, 6000, 0);
36 |
37 | constexpr Version kWindowsNT6_SP1(6, 0, 6001, 0);
38 |
39 | constexpr Version kWindowsNT6_SP2(6, 0, 6002, 0);
40 |
41 | // Windows 7 RTM, Windows Server 2008 R2 RTM
42 | constexpr Version kWindowsNT6_1(6, 1, 7600, 0);
43 |
44 | constexpr Version kWindowsNT6_1_SP1(6, 1, 7601, 0);
45 |
46 | // Windows 8 RTM, Windows Server 2012 RTM
47 | constexpr Version kWindowsNT6_2(6, 2, 9200, 0);
48 |
49 | // Windows 8.1 RTM, Windows Server 2012 R2 RTM
50 | constexpr Version kWindowsNT6_3(6, 3, 9600, 0);
51 |
52 | // Windows 10 1507
53 | constexpr Version kWindowsNT10_10240(10, 0, 10240, 0);
54 |
55 | // Windows 10 1607(RS1)
56 | constexpr Version kWindowsNT10_14393(10, 0, 14393, 0);
57 |
58 | // Windows 10 1703(RS2)
59 | constexpr Version kWindowsNT10_15603(10, 0, 15063, 0);
60 |
61 | // Windows 10 1709(RS3),注意ARM64从这个版本开始才支持。
62 | constexpr Version kWindowsNT10_16299(10, 0, 16299, 0);
63 |
64 | // Windows 10 2004(VB)
65 | constexpr Version kWindowsNT10_19041(10, 0, 19041, 0);
66 |
67 | // Windows Server 2022(FE)
68 | constexpr Version kWindowsNT10_20348(10, 0, 20348, 0);
69 | #endif
70 | ///
71 | /// 获取操作系统版本号。
72 | /// * Windows平台:不受系统兼容性影响,始终可获得正确版本号。
73 | ///
74 | ///
75 | Version __YYAPI GetOperatingSystemVersion() noexcept;
76 | }
77 | }
78 |
79 | using namespace YY::Base::Utils;
80 | }
81 |
82 | #pragma pack(pop)
83 |
--------------------------------------------------------------------------------
/Include/Base/Utils/Version.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #if defined(_HAS_CXX20) && _HAS_CXX20
5 | #include
6 | #endif
7 |
8 | #pragma pack(push, __YY_PACKING)
9 |
10 | namespace YY
11 | {
12 | namespace Base
13 | {
14 | namespace Utils
15 | {
16 | union Version
17 | {
18 | public:
19 | uint64_t uInternalValue = 0ull;
20 |
21 | struct
22 | {
23 | uint16_t uRevision;
24 | uint16_t uBuild;
25 | uint16_t uMinor;
26 | uint16_t uMajor;
27 | };
28 |
29 | struct
30 | {
31 | uint32_t uLowPart;
32 | uint32_t uHightPart;
33 | };
34 |
35 | constexpr Version() = default;
36 |
37 | constexpr Version(uint16_t _uMajor, uint16_t _uMinor, uint16_t _uBuild = 0, uint16_t _uRevision = 0)
38 | : uMajor(_uMajor)
39 | , uMinor(_uMinor)
40 | , uBuild(_uBuild)
41 | , uRevision(_uRevision)
42 | {
43 | }
44 |
45 | Version& __YYAPI operator=(const Version& _oOther)
46 | {
47 | uInternalValue = _oOther.uInternalValue;
48 | return *this;
49 | }
50 |
51 | constexpr bool __YYAPI operator==(const Version& _oOther) const noexcept
52 | {
53 | return uInternalValue == _oOther.uInternalValue;
54 | }
55 |
56 | #if defined(_HAS_CXX20) && _HAS_CXX20
57 | constexpr auto __YYAPI operator<=>(const Version& _oOther) const noexcept
58 | {
59 | return uInternalValue <=> _oOther.uInternalValue;
60 | }
61 | #else
62 | constexpr bool __YYAPI operator<(const Version& _oOther) const noexcept
63 | {
64 | return uInternalValue < _oOther.uInternalValue;
65 | }
66 |
67 | constexpr bool __YYAPI operator<=(const Version& _oOther) const noexcept
68 | {
69 | return uInternalValue <= _oOther.uInternalValue;
70 | }
71 |
72 | constexpr bool __YYAPI operator>=(const Version& _oOther) const noexcept
73 | {
74 | return uInternalValue >= _oOther.uInternalValue;
75 | }
76 |
77 | constexpr bool __YYAPI operator>(const Version& _oOther) const noexcept
78 | {
79 | return uInternalValue > _oOther.uInternalValue;
80 | }
81 |
82 | constexpr bool __YYAPI operator!=(const Version& _oOther) const noexcept
83 | {
84 | return uInternalValue > _oOther.uInternalValue;
85 | }
86 | #endif
87 | };
88 |
89 | static_assert(sizeof(Version) == sizeof(uint64_t), "");
90 | }
91 | }
92 |
93 | using namespace YY::Base::Utils;
94 | }
95 |
96 | #pragma pack(pop)
97 |
--------------------------------------------------------------------------------
/Include/Media/Brushes/Brush.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #include
5 | #include
6 |
7 | #pragma pack(push, __YY_PACKING)
8 |
9 | namespace YY
10 | {
11 | namespace Media
12 | {
13 | class Brush : public Resource
14 | {
15 | protected:
16 | constexpr static uint32_t uStaticDeep = Resource::uStaticDeep + 1;
17 |
18 | public:
19 | inline Brush() noexcept = default;
20 |
21 | inline Brush(std::nullptr_t) noexcept
22 | {
23 | }
24 |
25 | inline Brush(const Brush& _oOther) noexcept = default;
26 |
27 | inline Brush(Brush&& _oOther) noexcept = default;
28 |
29 | inline Brush& __YYAPI operator=(const Brush& _oOther) = default;
30 | inline Brush& __YYAPI operator=(Brush&& _oOther) = default;
31 |
32 | static const ResourceMetadata* __YYAPI GetStaticResourceMetadata() noexcept
33 | {
34 | static const ResourceMetadata s_Metadata = {Resource::GetStaticResourceMetadata(), uStaticDeep};
35 | return &s_Metadata;
36 | }
37 | };
38 |
39 | class SolidColorBrush : public Brush
40 | {
41 | protected:
42 | constexpr static uint32_t uStaticDeep = Brush::uStaticDeep + 1;
43 |
44 | class SharedData : public Brush::SharedData
45 | {
46 | public:
47 | Color oCloor;
48 |
49 | SharedData(Color _oCloor, const ResourceMetadata* _pMetadata = SolidColorBrush::GetStaticResourceMetadata())
50 | : Brush::SharedData(_pMetadata)
51 | , oCloor(_oCloor)
52 | {
53 | }
54 | };
55 |
56 | inline SharedData* GetSharedData() const
57 | {
58 | return (SharedData*)pSharedData.Get();
59 | }
60 |
61 | public:
62 | ///
63 | /// SolidColorBrush - The constructor accepts the color of the brush
64 | ///
65 | /// The color value.
66 | SolidColorBrush(Color _oCloor)
67 | {
68 | auto _pSharedData = new SharedData(_oCloor, GetStaticResourceMetadata());
69 | pSharedData.Attach(_pSharedData);
70 | }
71 |
72 | SolidColorBrush(std::nullptr_t)
73 | {
74 | }
75 |
76 | SolidColorBrush() = default;
77 | SolidColorBrush(const SolidColorBrush& _oOther) = default;
78 | SolidColorBrush(SolidColorBrush&& _oOther) = default;
79 | inline SolidColorBrush& operator=(const SolidColorBrush& _oOther) = default;
80 | inline SolidColorBrush& operator=(SolidColorBrush&& _oOther) = default;
81 |
82 | //#if defined(_HAS_CXX20) && _HAS_CXX20
83 | // bool operator==(const SolidColorBrush&) const = default;
84 | //#else
85 | // bool operator==(const SolidColorBrush& _oOther) const
86 | // {
87 | // return Brush::operator==(_oOther);
88 | // }
89 | //#endif
90 |
91 | bool operator==(std::nullptr_t _null) const
92 | {
93 | return pSharedData.Get() == nullptr;
94 | }
95 |
96 | static const ResourceMetadata* __YYAPI GetStaticResourceMetadata()
97 | {
98 | static const ResourceMetadata s_Metadata = {Brush::GetStaticResourceMetadata(), uStaticDeep};
99 | return &s_Metadata;
100 | }
101 |
102 | Color __YYAPI GetColor() const
103 | {
104 | auto _pSharedData = GetSharedData();
105 | if (!_pSharedData)
106 | abort();
107 |
108 | return _pSharedData->oCloor;
109 | }
110 | };
111 | }
112 | } // namespace YY
113 |
114 | #pragma pack(pop)
115 |
--------------------------------------------------------------------------------
/Include/Media/Color.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #ifdef _WIN32
3 | #include
4 | #include
5 | #include
6 | #endif
7 |
8 | #include
9 |
10 | #pragma pack(push, __YY_PACKING)
11 |
12 | namespace YY
13 | {
14 | namespace Media
15 | {
16 | union Color
17 | {
18 | struct
19 | {
20 | uint8_t Red;
21 | uint8_t Green;
22 | uint8_t Blue;
23 | uint8_t Alpha;
24 | };
25 |
26 | uint32_t ColorRGBA;
27 |
28 | uint32_t ColorRGB : 24;
29 |
30 | constexpr static Color __YYAPI MakeARGB(_In_ uint8_t _Alpha, _In_ uint8_t _Red, _In_ uint8_t _Green, _In_ uint8_t _Blue)
31 | {
32 | Color _Tmp(_Alpha, _Red, _Green, _Blue);
33 | return _Tmp;
34 | }
35 |
36 | constexpr static Color __YYAPI MakeRGB(_In_ uint8_t _Red, _In_ uint8_t _Green, _In_ uint8_t _Blue)
37 | {
38 | Color _Tmp(0xFFu, _Red, _Green, _Blue);
39 | return _Tmp;
40 | }
41 |
42 | constexpr static Color __YYAPI MakeRGBA(_In_ uint8_t _Red, _In_ uint8_t _Green, _In_ uint8_t _Blue, _In_ float _AlphaF)
43 | {
44 | Color _Tmp(uint8_t(_AlphaF * 0xFFu), _Red, _Green, _Blue);
45 | return _Tmp;
46 | }
47 |
48 | constexpr Color(_In_ uint8_t _Alpha, _In_ uint8_t _Red, _In_ uint8_t _Green, _In_ uint8_t _Blue)
49 | : Red(_Red)
50 | , Green(_Green)
51 | , Blue(_Blue)
52 | , Alpha(_Alpha)
53 | {
54 | }
55 |
56 | constexpr Color(_In_ uint32_t _ColorRGBA = 0u)
57 | : ColorRGBA(_ColorRGBA)
58 | {
59 | }
60 |
61 | #ifdef _WIN32
62 | __YYAPI operator DXGI_RGBA() const
63 | {
64 | DXGI_RGBA _Color;
65 | _Color.r = float(Red) / 255.0f;
66 | _Color.g = float(Green) / 255.0f;
67 | _Color.b = float(Blue) / 255.0f;
68 | _Color.a = float(Alpha) / 255.0f;
69 | return _Color;
70 | }
71 | #endif
72 |
73 | #ifdef _WIN32
74 | __YYAPI operator Gdiplus::Color() const
75 | {
76 | return Gdiplus::Color(Alpha, Red, Green, Blue);
77 | }
78 | #endif
79 | bool __YYAPI operator==(Color _Other) const
80 | {
81 | return ColorRGBA == _Other.ColorRGBA;
82 | }
83 | };
84 | } // namespace Media
85 |
86 | using namespace YY::Media;
87 | } // namespace YY
88 |
89 | #pragma pack(pop)
90 |
--------------------------------------------------------------------------------
/Include/Media/Font.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | namespace YY
5 | {
6 | namespace Media
7 | {
8 | namespace FontWeight
9 | {
10 | constexpr auto Thin = 100;
11 | constexpr auto ExtraLight = 200;
12 | constexpr auto UltraLight = 200;
13 | constexpr auto Light = 300;
14 | constexpr auto SemiLight = 350;
15 | constexpr auto Normal = 400;
16 | constexpr auto Regular = 400;
17 | constexpr auto Medium = 500;
18 | constexpr auto DemiBold = 600;
19 | constexpr auto SemiBold = 600;
20 | constexpr auto Bold = 700;
21 | constexpr auto ExtraBold = 800;
22 | constexpr auto UltraBold = 800;
23 | constexpr auto Black = 900;
24 | constexpr auto Heavy = 900;
25 | constexpr auto ExtraBlack = 950;
26 | constexpr auto UltraBlack = 950;
27 | } // namespace FontWeight
28 |
29 | enum class FontStyle
30 | {
31 | None = 0x00000000,
32 | Italic = 0x00000001,
33 | Underline = 0x00000002,
34 | StrikeOut = 0x00000004,
35 | };
36 |
37 | YY_APPLY_ENUM_CALSS_BIT_OPERATOR(FontStyle);
38 |
39 | // 保存字体的基本信息
40 | struct Font
41 | {
42 | // 字体名称
43 | uString szFace;
44 | // 字体大小
45 | float iSize = 0;
46 | // 字体的粗细,FontWeight
47 | uint32_t uWeight = 0;
48 | // FontStyle 的位组合
49 | FontStyle fStyle = FontStyle::None;
50 | };
51 |
52 | enum class SystemFont : uint32_t
53 | {
54 | CaptionFont,
55 | MenuFont,
56 | MessageFont,
57 | SmCaptionFont,
58 | StatusFont,
59 | IconFont,
60 | SystemFontCount,
61 | };
62 |
63 | HRESULT __YYAPI GetSystemFont(_In_ SystemFont _eSystemFont, _Out_ Font* _pFont);
64 | } // namespace Media
65 |
66 | using namespace YY::Media;
67 | } // namespace YY
68 |
--------------------------------------------------------------------------------
/Include/Media/Pens/Pen.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #pragma pack(push, __YY_PACKING)
5 |
6 | namespace YY
7 | {
8 | namespace Media
9 | {
10 | class Pen : public Resource
11 | {
12 | protected:
13 | constexpr static uint32_t uStaticDeep = Resource::uStaticDeep + 1;
14 |
15 | class SharedData : public Resource::SharedData
16 | {
17 | public:
18 | Brush oBrush;
19 | float iThickness;
20 |
21 | SharedData(Brush _oBrush = Brush(), float _iThickness = 1.0f, const ResourceMetadata* _pMetadata = Pen::GetStaticResourceMetadata())
22 | : Resource::SharedData(_pMetadata)
23 | , oBrush(std::move(_oBrush))
24 | , iThickness(_iThickness)
25 | {
26 | }
27 | };
28 |
29 | inline SharedData* GetSharedData() const
30 | {
31 | return (SharedData*)pSharedData.Get();
32 | }
33 |
34 | public:
35 | Pen(Brush _oBrush, float _iThickness = 1.0f)
36 | {
37 | auto _pSharedData = new SharedData(std::move(_oBrush), _iThickness);
38 | pSharedData.Attach(_pSharedData);
39 | }
40 |
41 | Pen(std::nullptr_t)
42 | {
43 | }
44 | Pen() = default;
45 | Pen(const Pen& _oOther) = default;
46 | Pen(Pen&& _oOther) = default;
47 | inline Pen& operator=(const Pen& _oOther) = default;
48 | inline Pen& operator=(Pen&& _oOther) = default;
49 |
50 | static const ResourceMetadata* __YYAPI GetStaticResourceMetadata()
51 | {
52 | static const ResourceMetadata s_Metadata = {Resource::GetStaticResourceMetadata(), uStaticDeep};
53 | return &s_Metadata;
54 | }
55 |
56 | Brush __YYAPI GetBrush() const
57 | {
58 | auto _pSharedData = GetSharedData();
59 | if (!_pSharedData)
60 | abort();
61 |
62 | return _pSharedData->oBrush;
63 | }
64 |
65 | float __YYAPI GetThickness() const
66 | {
67 | auto _pSharedData = GetSharedData();
68 | if (!_pSharedData)
69 | abort();
70 |
71 | return _pSharedData->iThickness;
72 | }
73 | };
74 | }
75 | } // namespace YY
76 | #pragma pack(pop)
77 |
--------------------------------------------------------------------------------
/Include/Media/Point.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #ifdef _WIN32
3 | #include
4 | #include
5 | #endif
6 |
7 | #include
8 |
9 |
10 | #pragma pack(push, __YY_PACKING)
11 |
12 | namespace YY
13 | {
14 | namespace Media
15 | {
16 | class Point
17 | {
18 | public:
19 | float X;
20 | float Y;
21 |
22 | constexpr Point()
23 | : X(0)
24 | , Y(0)
25 | {
26 | }
27 |
28 | constexpr Point(float _X, float _Y)
29 | : X(_X)
30 | , Y(_Y)
31 | {
32 | }
33 |
34 | constexpr Point(const Point& _Other)
35 | : X(_Other.X)
36 | , Y(_Other.Y)
37 | {
38 | }
39 |
40 | #ifdef _WIN32
41 | inline constexpr Point(POINTS _Other)
42 | : X((float)_Other.x)
43 | , Y((float)_Other.y)
44 | {
45 | }
46 | #endif
47 |
48 | inline bool operator==(Point _Other) const
49 | {
50 | return X == _Other.X && Y == _Other.Y;
51 | }
52 |
53 | inline bool operator!=(Point _Other) const
54 | {
55 | return X != _Other.X || Y != _Other.Y;
56 | }
57 |
58 | inline Point& operator+=(const Point& _Other)
59 | {
60 | X += _Other.X;
61 | Y += _Other.Y;
62 | return *this;
63 | }
64 |
65 | inline Point& operator-=(const Point& _Other)
66 | {
67 | X -= _Other.X;
68 | Y -= _Other.Y;
69 | return *this;
70 | }
71 |
72 | #ifdef _WIN32
73 | __YYAPI operator D2D1_POINT_2F&() const
74 | {
75 | return *(D2D1_POINT_2F*)this;
76 | }
77 | #endif
78 | };
79 | } // namespace Media
80 |
81 | using namespace YY::Media;
82 | } // namespace YY
83 |
84 | #pragma pack(pop)
85 |
--------------------------------------------------------------------------------
/Include/Media/Resource.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 | #include
4 |
5 | #pragma pack(push, __YY_PACKING)
6 |
7 | namespace YY
8 | {
9 | namespace Media
10 | {
11 | struct ResourceMetadata
12 | {
13 | const ResourceMetadata* pBaseMetadata;
14 | // 类的继承深度
15 | const uint32_t uDeep;
16 | };
17 |
18 | class Resource
19 | {
20 | protected:
21 | class SharedData : public RefValue
22 | {
23 | public:
24 | const ResourceMetadata* pMetadata;
25 |
26 | SharedData(const ResourceMetadata* _pMetadata = Resource::GetStaticResourceMetadata())
27 | : pMetadata(_pMetadata)
28 | {
29 | }
30 | };
31 |
32 | RefPtr pSharedData;
33 |
34 | constexpr static uint32_t uStaticDeep = 0;
35 |
36 | public:
37 | Resource(std::nullptr_t)
38 | {
39 | }
40 |
41 | Resource() = default;
42 | Resource(const Resource&) = default;
43 | Resource(Resource&&) = default;
44 |
45 | static const ResourceMetadata* __YYAPI GetStaticResourceMetadata() noexcept
46 | {
47 | static const ResourceMetadata s_Metadata = {nullptr, uStaticDeep};
48 | return &s_Metadata;
49 | }
50 |
51 | const ResourceMetadata* __YYAPI GetResourceMetadata() const noexcept
52 | {
53 | return pSharedData.Get() ? pSharedData.Get()->pMetadata : nullptr;
54 | }
55 |
56 | template
57 | Type __YYAPI TryCast() const noexcept
58 | {
59 | Type _Tmp;
60 | if (auto _pCurrentMetadata = GetResourceMetadata())
61 | {
62 | auto _pTargetMetadata = Type::GetStaticResourceMetadata();
63 | for (; _pCurrentMetadata; _pCurrentMetadata = _pCurrentMetadata->pBaseMetadata)
64 | {
65 | if (_pCurrentMetadata->uDeep < _pTargetMetadata->uDeep)
66 | break;
67 |
68 | if (_pCurrentMetadata->uDeep == _pTargetMetadata->uDeep)
69 | {
70 | if (_pCurrentMetadata == _pTargetMetadata)
71 | {
72 | _Tmp.pSharedData.Attach(pSharedData.Clone());
73 | }
74 | break;
75 | }
76 | }
77 | }
78 |
79 | return _Tmp;
80 | }
81 |
82 | Resource& __YYAPI operator=(std::nullptr_t) noexcept
83 | {
84 | pSharedData = nullptr;
85 | return *this;
86 | }
87 |
88 | Resource& __YYAPI operator=(const Resource& _oOther) noexcept = default;
89 |
90 | Resource& __YYAPI operator=(Resource&& _oOther) noexcept = default;
91 |
92 | #if defined(_HAS_CXX20) && _HAS_CXX20
93 | bool __YYAPI operator==(const Resource& _oOther) const noexcept = default;
94 | #else
95 | bool __YYAPI operator==(const Resource& _oOther) const noexcept
96 | {
97 | return pSharedData == _oOther.pSharedData;
98 | }
99 |
100 | bool __YYAPI operator!=(const Resource& _oOther) const noexcept
101 | {
102 | return pSharedData != _oOther.pSharedData;
103 | }
104 | #endif
105 | bool __YYAPI operator==(const std::nullptr_t) const noexcept
106 | {
107 | return pSharedData == nullptr;
108 | }
109 |
110 | bool __YYAPI operator!=(const std::nullptr_t) const noexcept
111 | {
112 | return pSharedData != nullptr;
113 | }
114 | };
115 |
116 | }
117 | } // namespace YY
118 |
119 | #pragma pack(pop)
120 |
--------------------------------------------------------------------------------
/Include/Media/Size.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #ifdef _WIN32
3 | #include
4 | #include
5 | #include
6 | #endif
7 |
8 | #include
9 |
10 | #pragma pack(push, __YY_PACKING)
11 |
12 | namespace YY
13 | {
14 | namespace Media
15 | {
16 | class Size
17 | {
18 | public:
19 | float Width;
20 | float Height;
21 |
22 | constexpr Size()
23 | : Width(0.0f)
24 | , Height(0.0f)
25 | {
26 | }
27 |
28 | constexpr Size(float _Width, float _Height)
29 | : Width(_Width)
30 | , Height(_Height)
31 | {
32 | }
33 |
34 | #ifdef _WIN32
35 | Size(const SIZE& _Size)
36 | : Width((float)_Size.cx)
37 | , Height((float)_Size.cy)
38 | {
39 | }
40 | #endif
41 |
42 | inline bool __YYAPI IsEmpty() const
43 | {
44 | return Width == 0.0f || Height == 0.0f;
45 | }
46 |
47 | inline bool __YYAPI operator==(Size _Other) const
48 | {
49 | return Width == _Other.Width && Height == _Other.Height;
50 | }
51 |
52 | inline bool __YYAPI operator!=(Size _Other) const
53 | {
54 | return Width != _Other.Width || Height != _Other.Height;
55 | }
56 |
57 | #ifdef _WIN32
58 | __YYAPI operator Gdiplus::SizeF&() const
59 | {
60 | return *(Gdiplus::SizeF*)this;
61 | }
62 |
63 | __YYAPI operator SIZE () const
64 | {
65 | return SIZE{ (long)Width, (long)Height };
66 | }
67 | #endif
68 | };
69 | } // namespace Media
70 |
71 | using namespace YY::Media;
72 | } // namespace YY
73 |
74 | #pragma pack(pop)
75 |
--------------------------------------------------------------------------------
/Include/MegaUI/Base/MegaUITypeInt.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include
4 |
5 |
--------------------------------------------------------------------------------
/Include/MegaUI/Control/Button.h:
--------------------------------------------------------------------------------
1 | #pragma once
2 | #include
3 |
4 | #pragma pack(push, __YY_PACKING)
5 |
6 | namespace YY
7 | {
8 | namespace MegaUI
9 | {
10 | // clang-format off
11 | // 属性名称 属性Flags 属性组FLAGS DefaultValue函数 CustomPropertyHandle pEnumMaps BindCache ValidValueType
12 | #define _MEGA_UI_BUTTON_PROPERTY_TABLE(_APPLY)
13 |
14 | // clang-format on
15 |
16 | class Button : public Element
17 | {
18 | _APPLY_MEGA_UI_STATIC_CONTROL_INFO_EXTERN(Button, Element, ControlInfoImp