Skip to content

Commit 286c632

Browse files
committed
1 parent b297fb5 commit 286c632

File tree

6 files changed

+111
-1
lines changed

6 files changed

+111
-1
lines changed

Macros/ECSMacros/ECSComponentMacro.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import SwiftSyntax
99
import SwiftSyntaxBuilder
1010
import SwiftSyntaxMacros
1111

12-
public enum ComponentMacroError: Error, CustomStringConvertible {
12+
public enum ComponentMacroError: Swift.Error, CustomStringConvertible {
1313
case notStructOrClass
1414
case mustBeFinalClass
1515

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/*
2+
* Copyright © 2025 Dustin Collins (Strega's Gate)
3+
* All Rights Reserved.
4+
*
5+
* http://stregasgate.com
6+
*/
7+
8+
import SwiftSyntax
9+
import SwiftSyntaxBuilder
10+
import SwiftSyntaxMacros
11+
12+
public enum RenderingSystemMacroError: Swift.Error, CustomStringConvertible {
13+
case notClass
14+
case invalidPhase
15+
16+
public var description: String {
17+
switch self {
18+
case .notClass:
19+
"@RenderingSystem(phase) can only be attached to a class."
20+
case .invalidPhase:
21+
"The provided phase is not a valid RenderingSystem.Phase."
22+
}
23+
}
24+
}
25+
26+
public struct ECSRenderingSystemMacro: MemberMacro, ExtensionMacro {
27+
public static func expansion(
28+
of node: AttributeSyntax,
29+
providingMembersOf declaration: some DeclGroupSyntax,
30+
conformingTo protocols: [TypeSyntax],
31+
in context: some MacroExpansionContext
32+
) throws -> [DeclSyntax] {
33+
34+
guard let classDecl = declaration.as(ClassDeclSyntax.self) else {
35+
throw RenderingSystemMacroError.notClass
36+
}
37+
38+
func getRenderingSystemPhase() throws -> TokenSyntax {
39+
switch node.arguments {
40+
case .argumentList(let labeledExprListSyntax):
41+
if let token = labeledExprListSyntax.lastToken(viewMode: .sourceAccurate) {
42+
return "\(token.formatted())"
43+
}
44+
default:
45+
break
46+
}
47+
throw RenderingSystemMacroError.invalidPhase
48+
}
49+
50+
let argument: String = try getRenderingSystemPhase().formatted().description
51+
52+
var syntax = "override class var phase: RenderingSystem.Phase { .\(argument)}"
53+
54+
if let access = classDecl.modifiers.first(where: {
55+
let syntax = $0.trimmed.description
56+
return syntax == "public" || syntax == "open" || syntax == "package"
57+
}) {
58+
syntax = access.trimmedDescription + " " + syntax
59+
}
60+
61+
return [DeclSyntax(stringLiteral: syntax)]
62+
}
63+
64+
public static func expansion(
65+
of node: SwiftSyntax.AttributeSyntax,
66+
attachedTo declaration: some SwiftSyntax.DeclGroupSyntax,
67+
providingExtensionsOf type: some SwiftSyntax.TypeSyntaxProtocol,
68+
conformingTo protocols: [SwiftSyntax.TypeSyntax],
69+
in context: some SwiftSyntaxMacros.MacroExpansionContext
70+
) throws -> [SwiftSyntax.ExtensionDeclSyntax] {
71+
guard protocols.contains(where: {$0 == "GateEngine.RenderingSystem"}) == false else { return [] }
72+
73+
guard let /*classDecl*/_ = declaration.as(ClassDeclSyntax.self) else {
74+
throw SystemMacroError.notClass
75+
}
76+
77+
// let className = classDecl.name.trimmed
78+
79+
// var protocols: [ExtensionDeclSyntax] = [try ProtocolDeclSyntax("GateEngine.RenderingSystem")] + protocols
80+
// return protocols
81+
return [
82+
try ExtensionDeclSyntax(SyntaxNodeString("GateEngine.RenderingSystem"))
83+
]
84+
}
85+
86+
// public static func expansion(
87+
// of node: SwiftSyntax.AttributeSyntax,
88+
// providingPeersOf declaration: some SwiftSyntax.DeclSyntaxProtocol,
89+
// in context: some SwiftSyntaxMacros.MacroExpansionContext
90+
// ) throws -> [SwiftSyntax.DeclSyntax] {
91+
// guard let classDecl = declaration.as(ClassDeclSyntax.self) else {
92+
// throw SystemMacroError.notClass
93+
// }
94+
// let className = classDecl.name.trimmed
95+
// return [DeclSyntax(
96+
//"""
97+
//@_cdecl(\"eventHandler\")
98+
//fileprivate func _eventHandler(pointer: UnsafeMutableRawPointer!, event: System.Event, arg: CUnsignedInt) -> CInt {
99+
// return \(className)._eventHandler(pointer: pointer, event: event, arg: arg)
100+
//}
101+
//"""
102+
// )]
103+
// }
104+
}

Macros/ECSMacros/Plugin.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import SwiftSyntaxMacros
1212
struct ECSMacros: CompilerPlugin {
1313
var providingMacros: [Macro.Type] = [
1414
ECSSystemMacro.self,
15+
ECSRenderingSystemMacro.self,
1516
ECSComponentMacro.self
1617
]
1718
}

Sources/GateEngine/ECS/PerformanceRenderingSystem.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* http://stregasgate.com
66
*/
77

8+
@RenderingSystem(drawing: .afterGameView)
89
public final class PerformanceRenderingSystem: RenderingSystem {
910
let improveLegibility: Bool
1011

Sources/GateEngine/ECS/StandardRenderingSystem.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import GameMath
99

10+
@RenderingSystem(drawing: .afterGameView)
1011
public final class StandardRenderingSystem: RenderingSystem {
1112
internal var verticalResolution: Float? = nil
1213
internal lazy var renderTarget: RenderTarget = RenderTarget()

Sources/GateEngine/GateEngine.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import Foundation
1919
@attached(member, names: named(phase), named(macroPhase))
2020
public macro System(_ macroPhase: GateEngine.System.Phase) = #externalMacro(module: "ECSMacros", type: "ECSSystemMacro")
2121

22+
@attached(member, names: named(phase), named(macroPhase))
23+
public macro RenderingSystem(drawing macroPhase: GateEngine.RenderingSystem.Phase) = #externalMacro(module: "ECSMacros", type: "ECSRenderingSystemMacro")
24+
2225
@attached(extension, conformances: Component, names: named(componentID), named(init))
2326
public macro Component() = #externalMacro(module: "ECSMacros", type: "ECSComponentMacro")
2427

0 commit comments

Comments
 (0)