sfml3-rb 0.0.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +342 -0
- data/README.md +51 -14
- data/TODO.md +199 -0
- data/ext/audio/audio_enums.c +131 -0
- data/ext/audio/audio_enums.h +18 -0
- data/ext/audio/effect_processor.c +233 -0
- data/ext/audio/effect_processor.h +25 -0
- data/ext/audio/listener.c +83 -0
- data/ext/audio/listener.h +8 -0
- data/ext/audio/music.c +174 -0
- data/ext/audio/music.h +14 -0
- data/ext/audio/sound.c +139 -0
- data/ext/audio/sound.h +14 -0
- data/ext/audio/sound_buffer.c +274 -0
- data/ext/audio/sound_buffer.h +18 -0
- data/ext/audio/sound_buffer_recorder.c +109 -0
- data/ext/audio/sound_buffer_recorder.h +14 -0
- data/ext/audio/sound_recorder.c +268 -0
- data/ext/audio/sound_recorder.h +14 -0
- data/ext/audio/sound_source.h +13 -0
- data/ext/audio/sound_source.inc +271 -0
- data/ext/audio/sound_source_cone.c +138 -0
- data/ext/audio/sound_source_cone.h +20 -0
- data/ext/audio/sound_stream.c +294 -0
- data/ext/audio/sound_stream.h +14 -0
- data/ext/{exceptions.c → core/exceptions.c} +10 -8
- data/ext/{ext → core}/exceptions.h +3 -3
- data/ext/core/foreign_thread.c +149 -0
- data/ext/core/foreign_thread.h +31 -0
- data/ext/core/macros.h +8 -0
- data/ext/{ext → core}/sfml.h +5 -3
- data/ext/core/unicode.c +46 -0
- data/ext/core/unicode.h +25 -0
- data/ext/ext.c +125 -14
- data/ext/extconf.rb +51 -6
- data/ext/graphics/blend_mode.c +261 -0
- data/ext/graphics/blend_mode.h +18 -0
- data/ext/graphics/circle.c +319 -0
- data/ext/{ext/klass/drawable → graphics}/circle.h +3 -3
- data/ext/graphics/color.c +318 -0
- data/ext/graphics/color.h +37 -0
- data/ext/{drawable.c → graphics/drawable.c} +11 -11
- data/ext/graphics/drawable.h +10 -0
- data/ext/graphics/enums.c +123 -0
- data/ext/graphics/enums.h +20 -0
- data/ext/graphics/font.c +148 -0
- data/ext/graphics/font.h +14 -0
- data/ext/graphics/glyph.c +60 -0
- data/ext/graphics/glyph.h +14 -0
- data/ext/graphics/image.c +205 -0
- data/ext/graphics/image.h +16 -0
- data/ext/graphics/polygon.c +300 -0
- data/ext/graphics/polygon.h +10 -0
- data/ext/graphics/rect.c +287 -0
- data/ext/graphics/rect.h +30 -0
- data/ext/graphics/rectangle.c +302 -0
- data/ext/graphics/rectangle.h +10 -0
- data/ext/graphics/render_state.c +204 -0
- data/ext/graphics/render_state.h +18 -0
- data/ext/graphics/render_target.inc +181 -0
- data/ext/graphics/render_texture.c +182 -0
- data/ext/graphics/render_texture.h +14 -0
- data/ext/graphics/shader.c +540 -0
- data/ext/graphics/shader.h +14 -0
- data/ext/graphics/shape.c +311 -0
- data/ext/graphics/shape.h +10 -0
- data/ext/graphics/sprite.c +249 -0
- data/ext/graphics/sprite.h +10 -0
- data/ext/graphics/stencil_mode.c +211 -0
- data/ext/graphics/stencil_mode.h +18 -0
- data/ext/graphics/target.c +133 -0
- data/ext/graphics/target.h +40 -0
- data/ext/graphics/text.c +344 -0
- data/ext/graphics/text.h +10 -0
- data/ext/graphics/texture.c +379 -0
- data/ext/graphics/texture.h +16 -0
- data/ext/graphics/transform.c +372 -0
- data/ext/graphics/transform.h +35 -0
- data/ext/{transformable.c → graphics/transformable.c} +168 -144
- data/ext/{ext/klass → graphics}/transformable.h +3 -3
- data/ext/graphics/vertex.c +179 -0
- data/ext/graphics/vertex.h +23 -0
- data/ext/graphics/vertex_array.c +127 -0
- data/ext/graphics/vertex_array.h +10 -0
- data/ext/graphics/vertex_buffer.c +211 -0
- data/ext/graphics/vertex_buffer.h +14 -0
- data/ext/{view.c → graphics/view.c} +168 -169
- data/ext/{ext/klass → graphics}/view.h +3 -3
- data/ext/network/ftp.c +405 -0
- data/ext/network/ftp.h +20 -0
- data/ext/network/http.c +243 -0
- data/ext/network/http.h +18 -0
- data/ext/network/ip_address.c +164 -0
- data/ext/network/ip_address.h +20 -0
- data/ext/network/network_enums.c +298 -0
- data/ext/network/network_enums.h +26 -0
- data/ext/network/packet.c +189 -0
- data/ext/network/packet.h +14 -0
- data/ext/network/socket_selector.c +142 -0
- data/ext/network/socket_selector.h +14 -0
- data/ext/network/tcp_listener.c +115 -0
- data/ext/network/tcp_listener.h +14 -0
- data/ext/network/tcp_socket.c +199 -0
- data/ext/network/tcp_socket.h +17 -0
- data/ext/network/udp_socket.c +190 -0
- data/ext/network/udp_socket.h +14 -0
- data/ext/ports.rb +97 -21
- data/ext/system/buffer.c +77 -0
- data/ext/system/buffer.h +14 -0
- data/ext/system/clock.c +100 -0
- data/ext/{ext/klass → system}/clock.h +3 -3
- data/ext/system/input_stream.c +229 -0
- data/ext/system/input_stream.h +23 -0
- data/ext/system/sleep.c +16 -0
- data/ext/system/sleep.h +8 -0
- data/ext/system/time.c +218 -0
- data/ext/system/time.h +18 -0
- data/ext/system/vec2.c +251 -0
- data/ext/system/vec2.h +55 -0
- data/ext/system/vec3.c +219 -0
- data/ext/system/vec3.h +18 -0
- data/ext/window/clipboard.c +89 -0
- data/ext/window/clipboard.h +8 -0
- data/ext/window/context.c +70 -0
- data/ext/window/context.h +8 -0
- data/ext/window/context_settings.c +220 -0
- data/ext/window/context_settings.h +18 -0
- data/ext/window/cursor.c +56 -0
- data/ext/window/cursor.h +14 -0
- data/ext/window/event.c +216 -0
- data/ext/window/event.h +14 -0
- data/ext/{event_name.c → window/event_name.c} +2 -2
- data/ext/window/event_name.h +8 -0
- data/ext/window/input_enums.c +261 -0
- data/ext/window/input_enums.h +36 -0
- data/ext/window/joystick.c +60 -0
- data/ext/window/joystick.h +8 -0
- data/ext/{keyboard.c → window/keyboard.c} +74 -2
- data/ext/window/keyboard.h +12 -0
- data/ext/window/mouse.c +70 -0
- data/ext/window/mouse.h +8 -0
- data/ext/window/sensor.c +30 -0
- data/ext/window/sensor.h +8 -0
- data/ext/window/touch.c +49 -0
- data/ext/window/touch.h +8 -0
- data/ext/window/video_mode.c +133 -0
- data/ext/window/video_mode.h +14 -0
- data/ext/window/vulkan.c +44 -0
- data/ext/window/vulkan.h +8 -0
- data/ext/window/window.c +414 -0
- data/ext/{ext/klass → window}/window.h +3 -3
- data/lib/sfml/version.rb +4 -2
- data/lib/sfml.rb +2 -0
- metadata +163 -56
- data/ext/circle.c +0 -198
- data/ext/clock.c +0 -65
- data/ext/color.c +0 -43
- data/ext/event.c +0 -148
- data/ext/ext/klass/color.h +0 -26
- data/ext/ext/klass/drawable/image.h +0 -4
- data/ext/ext/klass/drawable/polygon.h +0 -4
- data/ext/ext/klass/drawable/rectangle.h +0 -4
- data/ext/ext/klass/drawable/sprite.h +0 -4
- data/ext/ext/klass/drawable/texture.h +0 -4
- data/ext/ext/klass/event/event_name.h +0 -8
- data/ext/ext/klass/event.h +0 -12
- data/ext/ext/klass/keyboard.h +0 -8
- data/ext/ext/klass/render_state.h +0 -16
- data/ext/ext/klass/target.h +0 -18
- data/ext/ext/klass/transform.h +0 -17
- data/ext/ext/klass/video_mode.h +0 -12
- data/ext/ext/module/drawable/drawable.h +0 -10
- data/ext/ext/module/transform.h +0 -18
- data/ext/ext/module.h +0 -10
- data/ext/ext/rect.h +0 -16
- data/ext/ext/style_name.h +0 -11
- data/ext/ext/vec2.h +0 -38
- data/ext/image.c +0 -5
- data/ext/polygon.c +0 -5
- data/ext/rect.c +0 -26
- data/ext/rectangle.c +0 -5
- data/ext/render_state.c +0 -109
- data/ext/sprite.c +0 -5
- data/ext/style_name.c +0 -15
- data/ext/target.c +0 -106
- data/ext/texture.c +0 -5
- data/ext/transform.c +0 -107
- data/ext/vec2.c +0 -42
- data/ext/video_mode.c +0 -78
- data/ext/window.c +0 -274
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#ifndef SFML_RB_NETWORK_TCP_SOCKET_H
|
|
2
|
+
#define SFML_RB_NETWORK_TCP_SOCKET_H
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#include "core/sfml.h"
|
|
7
|
+
|
|
8
|
+
void Init_TcpSocket(VALUE rb_module);
|
|
9
|
+
|
|
10
|
+
VALUE Get_Klass_TcpSocket(void);
|
|
11
|
+
|
|
12
|
+
void *Get_TcpSocket_Struct(VALUE self);
|
|
13
|
+
|
|
14
|
+
/* Wraps a socket returned by sfTcpListener_accept, taking ownership. */
|
|
15
|
+
VALUE tcp_socket_from_handle(sfTcpSocket *socket);
|
|
16
|
+
|
|
17
|
+
#endif //SFML_RB_NETWORK_TCP_SOCKET_H
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
#include "network/udp_socket.h"
|
|
2
|
+
|
|
3
|
+
#include <ruby.h>
|
|
4
|
+
#include <stdlib.h>
|
|
5
|
+
|
|
6
|
+
#include "core/macros.h"
|
|
7
|
+
#include "network/ip_address.h"
|
|
8
|
+
#include "network/network_enums.h"
|
|
9
|
+
#include "network/packet.h"
|
|
10
|
+
|
|
11
|
+
typedef struct {
|
|
12
|
+
sfUdpSocket *handle;
|
|
13
|
+
} UdpSocket;
|
|
14
|
+
|
|
15
|
+
static VALUE rb_cUdpSocket;
|
|
16
|
+
|
|
17
|
+
static void UdpSocket_free(void *ptr) {
|
|
18
|
+
UdpSocket *socket = ptr;
|
|
19
|
+
|
|
20
|
+
if (socket->handle != NULL) {
|
|
21
|
+
sfUdpSocket_destroy(socket->handle);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
free(socket);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static const rb_data_type_t UdpSocket_data_type = {
|
|
28
|
+
.wrap_struct_name = "SFML::UdpSocket",
|
|
29
|
+
.function = {.dmark = NULL, .dfree = UdpSocket_free, .dsize = NULL},
|
|
30
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
static VALUE UdpSocket_wrap(VALUE klass, sfUdpSocket *handle) {
|
|
34
|
+
UdpSocket *ptr;
|
|
35
|
+
|
|
36
|
+
if (handle == NULL) {
|
|
37
|
+
rb_raise(rb_eRuntimeError, "failed to create UDP socket");
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
ptr = malloc(sizeof(UdpSocket));
|
|
41
|
+
ptr->handle = handle;
|
|
42
|
+
|
|
43
|
+
return TypedData_Wrap_Struct(klass, &UdpSocket_data_type, ptr);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
static VALUE UdpSocket_new(VALUE klass) {
|
|
47
|
+
return UdpSocket_wrap(klass, sfUdpSocket_create());
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static VALUE UdpSocket_any_port(VALUE klass) {
|
|
51
|
+
return UINT2NUM(sfUdpSocket_anyPort());
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
static VALUE UdpSocket_max_datagram_size(VALUE klass) {
|
|
55
|
+
return UINT2NUM(sfUdpSocket_maxDatagramSize());
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
static VALUE UdpSocket_blocking(VALUE self) {
|
|
59
|
+
return BOOL2RB(sfUdpSocket_isBlocking(Get_UdpSocket_Struct(self)));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static VALUE UdpSocket_set_blocking(VALUE self, VALUE rb_value) {
|
|
63
|
+
sfUdpSocket_setBlocking(Get_UdpSocket_Struct(self), RTEST(rb_value));
|
|
64
|
+
return rb_value;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static VALUE UdpSocket_local_port(VALUE self) {
|
|
68
|
+
return UINT2NUM(sfUdpSocket_getLocalPort(Get_UdpSocket_Struct(self)));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static VALUE UdpSocket_bind(int argc, VALUE *argv, VALUE self) {
|
|
72
|
+
VALUE rb_port, rb_address;
|
|
73
|
+
|
|
74
|
+
rb_scan_args(argc, argv, "11", &rb_port, &rb_address);
|
|
75
|
+
|
|
76
|
+
return ID2SYM(rb_intern(socket_status_name(sfUdpSocket_bind(
|
|
77
|
+
Get_UdpSocket_Struct(self), (unsigned short) NUM2INT(rb_port),
|
|
78
|
+
ip_address_from_rb(rb_address, sfIpAddress_Any)))));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
static VALUE UdpSocket_unbind(VALUE self) {
|
|
82
|
+
sfUdpSocket_unbind(Get_UdpSocket_Struct(self));
|
|
83
|
+
return self;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
static VALUE UdpSocket_send(VALUE self, VALUE rb_data, VALUE rb_address, VALUE rb_port) {
|
|
87
|
+
StringValue(rb_data);
|
|
88
|
+
|
|
89
|
+
return ID2SYM(rb_intern(socket_status_name(sfUdpSocket_send(
|
|
90
|
+
Get_UdpSocket_Struct(self), RSTRING_PTR(rb_data), (size_t) RSTRING_LEN(rb_data),
|
|
91
|
+
ip_address_from_rb(rb_address, sfIpAddress_None), (unsigned short) NUM2INT(rb_port)))));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/* Returns [data, IpAddress, port, status]; the address and port are those of
|
|
95
|
+
the sender. */
|
|
96
|
+
static VALUE UdpSocket_receive(int argc, VALUE *argv, VALUE self) {
|
|
97
|
+
VALUE rb_max_length;
|
|
98
|
+
long max_length = 1024;
|
|
99
|
+
char *buffer;
|
|
100
|
+
size_t received = 0;
|
|
101
|
+
sfIpAddress remote_address = sfIpAddress_None;
|
|
102
|
+
unsigned short remote_port = 0;
|
|
103
|
+
sfSocketStatus status;
|
|
104
|
+
VALUE rb_result;
|
|
105
|
+
|
|
106
|
+
rb_scan_args(argc, argv, "01", &rb_max_length);
|
|
107
|
+
|
|
108
|
+
if (!NIL_P(rb_max_length)) {
|
|
109
|
+
max_length = NUM2LONG(rb_max_length);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (max_length <= 0) {
|
|
113
|
+
rb_raise(rb_eArgError, "maximum length must be positive");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
buffer = malloc((size_t) max_length);
|
|
117
|
+
|
|
118
|
+
status = sfUdpSocket_receive(Get_UdpSocket_Struct(self), buffer, (size_t) max_length, &received,
|
|
119
|
+
&remote_address, &remote_port);
|
|
120
|
+
|
|
121
|
+
rb_result = rb_ary_new_capa(4);
|
|
122
|
+
rb_ary_push(rb_result, rb_str_new(buffer, (long) received));
|
|
123
|
+
rb_ary_push(rb_result, ip_address_to_rb(remote_address));
|
|
124
|
+
rb_ary_push(rb_result, UINT2NUM(remote_port));
|
|
125
|
+
rb_ary_push(rb_result, ID2SYM(rb_intern(socket_status_name(status))));
|
|
126
|
+
|
|
127
|
+
free(buffer);
|
|
128
|
+
|
|
129
|
+
return rb_result;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
static VALUE UdpSocket_send_packet(VALUE self, VALUE rb_packet, VALUE rb_address, VALUE rb_port) {
|
|
133
|
+
if (!rb_obj_is_kind_of(rb_packet, Get_Klass_Packet())) {
|
|
134
|
+
rb_raise(rb_eTypeError, "expected an SFML::Packet");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return ID2SYM(rb_intern(socket_status_name(sfUdpSocket_sendPacket(
|
|
138
|
+
Get_UdpSocket_Struct(self), Get_Packet_Struct(rb_packet),
|
|
139
|
+
ip_address_from_rb(rb_address, sfIpAddress_None), (unsigned short) NUM2INT(rb_port)))));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/* Returns [IpAddress, port, status]. */
|
|
143
|
+
static VALUE UdpSocket_receive_packet(VALUE self, VALUE rb_packet) {
|
|
144
|
+
sfIpAddress remote_address = sfIpAddress_None;
|
|
145
|
+
unsigned short remote_port = 0;
|
|
146
|
+
sfSocketStatus status;
|
|
147
|
+
VALUE rb_result;
|
|
148
|
+
|
|
149
|
+
if (!rb_obj_is_kind_of(rb_packet, Get_Klass_Packet())) {
|
|
150
|
+
rb_raise(rb_eTypeError, "expected an SFML::Packet");
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
status = sfUdpSocket_receivePacket(Get_UdpSocket_Struct(self), Get_Packet_Struct(rb_packet),
|
|
154
|
+
&remote_address, &remote_port);
|
|
155
|
+
|
|
156
|
+
rb_result = rb_ary_new_capa(3);
|
|
157
|
+
rb_ary_push(rb_result, ip_address_to_rb(remote_address));
|
|
158
|
+
rb_ary_push(rb_result, UINT2NUM(remote_port));
|
|
159
|
+
rb_ary_push(rb_result, ID2SYM(rb_intern(socket_status_name(status))));
|
|
160
|
+
|
|
161
|
+
return rb_result;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
void Init_UdpSocket(VALUE rb_module) {
|
|
165
|
+
rb_cUdpSocket = rb_define_class_under(rb_module, "UdpSocket", rb_cObject);
|
|
166
|
+
|
|
167
|
+
rb_define_singleton_method(rb_cUdpSocket, "new", UdpSocket_new, 0);
|
|
168
|
+
rb_define_singleton_method(rb_cUdpSocket, "any_port", UdpSocket_any_port, 0);
|
|
169
|
+
rb_define_singleton_method(rb_cUdpSocket, "max_datagram_size", UdpSocket_max_datagram_size, 0);
|
|
170
|
+
|
|
171
|
+
rb_define_method(rb_cUdpSocket, "blocking?", UdpSocket_blocking, 0);
|
|
172
|
+
rb_define_method(rb_cUdpSocket, "blocking=", UdpSocket_set_blocking, 1);
|
|
173
|
+
rb_define_method(rb_cUdpSocket, "local_port", UdpSocket_local_port, 0);
|
|
174
|
+
rb_define_method(rb_cUdpSocket, "bind", UdpSocket_bind, -1);
|
|
175
|
+
rb_define_method(rb_cUdpSocket, "unbind", UdpSocket_unbind, 0);
|
|
176
|
+
rb_define_method(rb_cUdpSocket, "send", UdpSocket_send, 3);
|
|
177
|
+
rb_define_method(rb_cUdpSocket, "receive", UdpSocket_receive, -1);
|
|
178
|
+
rb_define_method(rb_cUdpSocket, "send_packet", UdpSocket_send_packet, 3);
|
|
179
|
+
rb_define_method(rb_cUdpSocket, "receive_packet", UdpSocket_receive_packet, 1);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
VALUE Get_Klass_UdpSocket(void) {
|
|
183
|
+
return rb_cUdpSocket;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
void *Get_UdpSocket_Struct(VALUE self) {
|
|
187
|
+
UdpSocket *ptr;
|
|
188
|
+
TypedData_Get_Struct(self, UdpSocket, &UdpSocket_data_type, ptr);
|
|
189
|
+
return ptr->handle;
|
|
190
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#ifndef SFML_RB_NETWORK_UDP_SOCKET_H
|
|
2
|
+
#define SFML_RB_NETWORK_UDP_SOCKET_H
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#include "core/sfml.h"
|
|
7
|
+
|
|
8
|
+
void Init_UdpSocket(VALUE rb_module);
|
|
9
|
+
|
|
10
|
+
VALUE Get_Klass_UdpSocket(void);
|
|
11
|
+
|
|
12
|
+
void *Get_UdpSocket_Struct(VALUE self);
|
|
13
|
+
|
|
14
|
+
#endif //SFML_RB_NETWORK_UDP_SOCKET_H
|
data/ext/ports.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'digest'
|
|
2
4
|
require 'etc'
|
|
3
5
|
require 'fileutils'
|
|
@@ -23,11 +25,19 @@ module Ports
|
|
|
23
25
|
# Cross targets, keyed by the RubyGems platform name that rake-compiler and
|
|
24
26
|
# rake-compiler-dock use for them. `triple` is the GNU host triple whose
|
|
25
27
|
# toolchain the matching rake-compiler-dock image installs as <triple>-gcc.
|
|
28
|
+
#
|
|
29
|
+
# `multiarch` is the Debian multiarch directory name, which is only sometimes
|
|
30
|
+
# the same string as the triple: i686 compiles with i686-linux-gnu-gcc but its
|
|
31
|
+
# libraries live in /usr/lib/i386-linux-gnu. Only set it where they differ.
|
|
26
32
|
TARGETS = {
|
|
27
33
|
'x86_64-linux-gnu' => { triple: 'x86_64-linux-gnu', os: :linux, cpu: 'x86_64' },
|
|
34
|
+
'x86-linux-gnu' => { triple: 'i686-linux-gnu', multiarch: 'i386-linux-gnu',
|
|
35
|
+
os: :linux, cpu: 'i686' },
|
|
28
36
|
'aarch64-linux-gnu' => { triple: 'aarch64-linux-gnu', os: :linux, cpu: 'aarch64' },
|
|
29
37
|
'x86_64-linux-musl' => { triple: 'x86_64-unknown-linux-musl', os: :linux, cpu: 'x86_64' },
|
|
38
|
+
'x86-linux-musl' => { triple: 'i686-unknown-linux-musl', os: :linux, cpu: 'i686' },
|
|
30
39
|
'x64-mingw-ucrt' => { triple: 'x86_64-w64-mingw32', os: :windows, cpu: 'x86_64' },
|
|
40
|
+
'x86-mingw32' => { triple: 'i686-w64-mingw32', os: :windows, cpu: 'i686' },
|
|
31
41
|
'x86_64-darwin' => { triple: 'x86_64-apple-darwin', os: :darwin, cpu: 'x86_64' },
|
|
32
42
|
'arm64-darwin' => { triple: 'aarch64-apple-darwin', os: :darwin, cpu: 'arm64' }
|
|
33
43
|
}.freeze
|
|
@@ -41,32 +51,88 @@ module Ports
|
|
|
41
51
|
windows: %w[gcc g++]
|
|
42
52
|
}.freeze
|
|
43
53
|
|
|
44
|
-
# What the extension links on top of the static SFML/CSFML/FreeType
|
|
45
|
-
# SFML resolves GL entry points through its own loader, so on Linux
|
|
46
|
-
# only needed for the handful of symbols SFML references directly.
|
|
54
|
+
# What the extension links on top of the static SFML/CSFML/FreeType/codec
|
|
55
|
+
# archives. SFML resolves GL entry points through its own loader, so on Linux
|
|
56
|
+
# libGL is only needed for the handful of symbols SFML references directly.
|
|
57
|
+
# Network links ws2_32 on Windows; audio needs no OpenAL, because SFML 3 uses
|
|
58
|
+
# the vendored miniaudio backend and resolves ALSA/Pulse at run time via dl.
|
|
47
59
|
SYSTEM_LIBS = {
|
|
48
60
|
linux: %w[GL X11 Xrandr Xcursor Xi udev pthread dl rt m],
|
|
49
|
-
windows: %w[opengl32 winmm gdi32 user32 advapi32 ole32],
|
|
61
|
+
windows: %w[opengl32 winmm gdi32 user32 advapi32 ole32 ws2_32],
|
|
50
62
|
darwin: %w[]
|
|
51
63
|
}.freeze
|
|
52
64
|
|
|
53
65
|
# Clang wants -framework, not -l, and SFML's macOS backend is Objective-C++.
|
|
54
|
-
|
|
66
|
+
# Audio reaches CoreAudio/CoreFoundation from miniaudio, and the network
|
|
67
|
+
# stack needs nothing beyond the system libc.
|
|
68
|
+
FRAMEWORKS = {
|
|
69
|
+
darwin: %w[Cocoa OpenGL IOKit Carbon CoreFoundation CoreAudio AudioToolbox],
|
|
70
|
+
linux: [], windows: []
|
|
71
|
+
}.freeze
|
|
55
72
|
|
|
56
|
-
# Order matters.
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
#
|
|
73
|
+
# Order matters. The Ogg/Vorbis/FLAC codecs and FreeType must be installed
|
|
74
|
+
# before SFML configures, because SFML's find_package(Vorbis)/find_package(FLAC)
|
|
75
|
+
# run with SFML_USE_SYSTEM_DEPS=ON and must find our static archives rather
|
|
76
|
+
# than the build host's shared ones. CSFML then does find_package(SFML 3 ...)
|
|
77
|
+
# and does not fetch SFML itself.
|
|
60
78
|
#
|
|
61
79
|
# FreeType is built here rather than left to SFML because SFML's own
|
|
62
80
|
# FetchContent path clones it from git (no checksum, needs git at configure
|
|
63
81
|
# time) and then does not install the resulting archive -- which leaves
|
|
64
82
|
# libsfml-graphics-s.a with an undefined FT_Init_FreeType that only stays
|
|
65
|
-
# latent while nothing binds sf::Font. Pinning it as a port fixes both.
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
#
|
|
83
|
+
# latent while nothing binds sf::Font. Pinning it as a port fixes both. The
|
|
84
|
+
# same reasoning applies to the codecs: vendoring them keeps the binary gems
|
|
85
|
+
# free of libvorbis/libFLAC/libogg runtime dependencies and makes the audio
|
|
86
|
+
# module buildable on the mingw/darwin/musl images, which ship no codec
|
|
87
|
+
# development files at all.
|
|
69
88
|
RECIPES = [
|
|
89
|
+
{
|
|
90
|
+
name: 'libogg',
|
|
91
|
+
version: '1.3.5',
|
|
92
|
+
sha256: '0eb4b4b9420a0f51db142ba3f9c64b333f826532dc0f48c6410ae51f4799b664',
|
|
93
|
+
url: 'https://downloads.xiph.org/releases/ogg/libogg-%<version>s.tar.gz',
|
|
94
|
+
flags: %w[
|
|
95
|
+
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
|
96
|
+
-DBUILD_SHARED_LIBS=OFF
|
|
97
|
+
-DBUILD_TESTING=OFF
|
|
98
|
+
-DINSTALL_DOCS=OFF
|
|
99
|
+
-DINSTALL_CMAKE_PACKAGE_MODULE=ON
|
|
100
|
+
-DINSTALL_PKG_CONFIG_MODULE=OFF
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
name: 'libvorbis',
|
|
105
|
+
version: '1.3.7',
|
|
106
|
+
sha256: '0e982409a9c3fc82ee06e08205b1355e5c6aa4c36bca58146ef399621b0ce5ab',
|
|
107
|
+
url: 'https://downloads.xiph.org/releases/vorbis/libvorbis-%<version>s.tar.gz',
|
|
108
|
+
flags: %w[
|
|
109
|
+
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
|
110
|
+
-DBUILD_SHARED_LIBS=OFF
|
|
111
|
+
-DBUILD_TESTING=OFF
|
|
112
|
+
-DINSTALL_CMAKE_PACKAGE_MODULE=ON
|
|
113
|
+
]
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: 'flac',
|
|
117
|
+
version: '1.4.3',
|
|
118
|
+
sha256: '6c58e69cd22348f441b861092b825e591d0b822e106de6eb0ee4d05d27205b70',
|
|
119
|
+
url: 'https://downloads.xiph.org/releases/flac/flac-%<version>s.tar.xz',
|
|
120
|
+
ext: 'tar.xz',
|
|
121
|
+
flags: %w[
|
|
122
|
+
-DBUILD_SHARED_LIBS=OFF
|
|
123
|
+
-DBUILD_CXXLIBS=OFF
|
|
124
|
+
-DBUILD_PROGRAMS=OFF
|
|
125
|
+
-DBUILD_EXAMPLES=OFF
|
|
126
|
+
-DBUILD_TESTING=OFF
|
|
127
|
+
-DBUILD_DOCS=OFF
|
|
128
|
+
-DWITH_OGG=OFF
|
|
129
|
+
-DWITH_FORTIFY_SOURCE=OFF
|
|
130
|
+
-DWITH_STACK_PROTECTOR=OFF
|
|
131
|
+
-DINSTALL_MANPAGES=OFF
|
|
132
|
+
-DINSTALL_CMAKE_CONFIG_MODULE=ON
|
|
133
|
+
-DINSTALL_PKGCONFIG_MODULES=ON
|
|
134
|
+
]
|
|
135
|
+
},
|
|
70
136
|
{
|
|
71
137
|
name: 'freetype',
|
|
72
138
|
version: '2.13.2',
|
|
@@ -89,8 +155,6 @@ module Ports
|
|
|
89
155
|
sha256: '0034e05f95509e5d3fb81b1625713e06da7b068f210288ce3fd67106f8f46995',
|
|
90
156
|
flags: %w[
|
|
91
157
|
-DSFML_USE_SYSTEM_DEPS=ON
|
|
92
|
-
-DSFML_BUILD_AUDIO=OFF
|
|
93
|
-
-DSFML_BUILD_NETWORK=OFF
|
|
94
158
|
-DSFML_BUILD_EXAMPLES=OFF
|
|
95
159
|
-DSFML_BUILD_DOC=OFF
|
|
96
160
|
-DSFML_BUILD_TEST_SUITE=OFF
|
|
@@ -101,15 +165,13 @@ module Ports
|
|
|
101
165
|
version: '3.0.0',
|
|
102
166
|
sha256: '903cd4a782fb0b233f732dc5b37861b552998e93ae8f268c40bd4ce50b2e88ca',
|
|
103
167
|
flags: %w[
|
|
104
|
-
-DCSFML_BUILD_AUDIO=OFF
|
|
105
|
-
-DCSFML_BUILD_NETWORK=OFF
|
|
106
168
|
-DCSFML_BUILD_EXAMPLES=OFF
|
|
107
169
|
-DCSFML_LINK_SFML_STATICALLY=ON
|
|
108
170
|
]
|
|
109
171
|
}
|
|
110
172
|
].freeze
|
|
111
173
|
|
|
112
|
-
TOOLCHAIN_HINT = <<~HINT
|
|
174
|
+
TOOLCHAIN_HINT = <<~HINT
|
|
113
175
|
Building SFML from source needs CMake >= 3.22, a C++17 compiler, and the
|
|
114
176
|
X11/udev/OpenGL development headers. SFML links those from the system and
|
|
115
177
|
they cannot be bundled.
|
|
@@ -210,8 +272,11 @@ module Ports
|
|
|
210
272
|
end
|
|
211
273
|
end
|
|
212
274
|
|
|
275
|
+
# The local archive keeps a fixed <name>-<version>.<ext> name regardless of
|
|
276
|
+
# what the upstream release calls it, so recipes can point at libogg-1.3.5.tar.gz
|
|
277
|
+
# or flac-1.4.3.tar.xz without the rest of the code caring.
|
|
213
278
|
def tarball(recipe)
|
|
214
|
-
File.join(ARCHIVES, "#{recipe[:name]}-#{recipe[:version]}
|
|
279
|
+
File.join(ARCHIVES, "#{recipe[:name]}-#{recipe[:version]}.#{recipe[:ext] || 'tar.gz'}")
|
|
215
280
|
end
|
|
216
281
|
|
|
217
282
|
def source_dir(recipe)
|
|
@@ -273,6 +338,15 @@ module Ports
|
|
|
273
338
|
-DCMAKE_INSTALL_LIBDIR=lib
|
|
274
339
|
]
|
|
275
340
|
flags << "-DCMAKE_TOOLCHAIN_FILE=#{toolchain_file}" if cross?
|
|
341
|
+
|
|
342
|
+
# SFML 3.0.2 defaults CMAKE_OSX_DEPLOYMENT_TARGET to 13.0 in its own
|
|
343
|
+
# CMakeLists.txt, but the macOS SDK osxcross ships in the
|
|
344
|
+
# rake-compiler-dock image is 11.1, and osxcross refuses a target newer
|
|
345
|
+
# than its SDK ("targeted macOS version must be <= 11.1.0"). Pass it as a
|
|
346
|
+
# -D rather than writing it into the toolchain file because SFML's
|
|
347
|
+
# sfml_set_option() only supplies its default when the variable is not
|
|
348
|
+
# already defined -- a command-line cache entry always is.
|
|
349
|
+
flags << '-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0' if os == :darwin
|
|
276
350
|
flags
|
|
277
351
|
end
|
|
278
352
|
|
|
@@ -328,7 +402,7 @@ module Ports
|
|
|
328
402
|
else
|
|
329
403
|
# Debian multiarch: without this CMake searches /usr/lib, finds the
|
|
330
404
|
# container's own amd64 libraries and hands them to an aarch64 linker.
|
|
331
|
-
lines << "set(CMAKE_LIBRARY_ARCHITECTURE #{spec[:triple]})"
|
|
405
|
+
lines << "set(CMAKE_LIBRARY_ARCHITECTURE #{spec[:multiarch] || spec[:triple]})"
|
|
332
406
|
end
|
|
333
407
|
end
|
|
334
408
|
|
|
@@ -351,7 +425,9 @@ module Ports
|
|
|
351
425
|
|
|
352
426
|
unless Dir.exist?(source)
|
|
353
427
|
FileUtils.mkdir_p(build_root)
|
|
354
|
-
|
|
428
|
+
# Plain `xf`, not `xzf`: GNU tar, bsdtar and mingw's tar all sniff the
|
|
429
|
+
# compression, which is what lets gzip and xz recipes share this path.
|
|
430
|
+
run('tar', 'xf', tarball(recipe), '-C', build_root)
|
|
355
431
|
end
|
|
356
432
|
|
|
357
433
|
puts "Building #{recipe[:name]} #{recipe[:version]} for #{target}"
|
data/ext/system/buffer.c
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#include "system/buffer.h"
|
|
2
|
+
|
|
3
|
+
#include <ruby.h>
|
|
4
|
+
|
|
5
|
+
#include "core/exceptions.h"
|
|
6
|
+
#include "core/macros.h"
|
|
7
|
+
|
|
8
|
+
static VALUE rb_cBuffer;
|
|
9
|
+
|
|
10
|
+
static void Buffer_free(void *ptr) {
|
|
11
|
+
sfBuffer_destroy(ptr);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
static const rb_data_type_t Buffer_data_type = {
|
|
15
|
+
.wrap_struct_name = "SFML::Buffer",
|
|
16
|
+
.function = {.dmark = NULL, .dfree = Buffer_free, .dsize = NULL},
|
|
17
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
static VALUE Buffer_wrap(VALUE klass, sfBuffer *buffer) {
|
|
21
|
+
return TypedData_Wrap_Struct(klass, &Buffer_data_type, buffer);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
static VALUE Buffer_new(VALUE klass) {
|
|
25
|
+
VALUE self;
|
|
26
|
+
sfBuffer *buffer = sfBuffer_create();
|
|
27
|
+
|
|
28
|
+
if (buffer == NULL) {
|
|
29
|
+
rb_raise(rb_eNoMemError, "could not create buffer");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
self = Buffer_wrap(klass, buffer);
|
|
33
|
+
|
|
34
|
+
return self;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
static VALUE Buffer_get_size(VALUE self) {
|
|
38
|
+
return SIZET2NUM(sfBuffer_getSize(Get_Buffer_Struct(self)));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
static VALUE Buffer_get_data(VALUE self) {
|
|
42
|
+
sfBuffer *buffer = Get_Buffer_Struct(self);
|
|
43
|
+
size_t size = sfBuffer_getSize(buffer);
|
|
44
|
+
const uint8_t *data = sfBuffer_getData(buffer);
|
|
45
|
+
|
|
46
|
+
if (data == NULL || size == 0) {
|
|
47
|
+
return rb_str_new("", 0);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return rb_str_new((const char *) data, (long) size);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static VALUE Buffer_is_empty(VALUE self) {
|
|
54
|
+
return BOOL2RB(sfBuffer_getSize(Get_Buffer_Struct(self)) == 0);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
void Init_Buffer(VALUE rb_module) {
|
|
58
|
+
rb_cBuffer = rb_define_class_under(rb_module, "Buffer", rb_cObject);
|
|
59
|
+
|
|
60
|
+
rb_define_singleton_method(rb_cBuffer, "new", Buffer_new, 0);
|
|
61
|
+
|
|
62
|
+
rb_define_method(rb_cBuffer, "size", Buffer_get_size, 0);
|
|
63
|
+
rb_define_method(rb_cBuffer, "length", Buffer_get_size, 0);
|
|
64
|
+
rb_define_method(rb_cBuffer, "data", Buffer_get_data, 0);
|
|
65
|
+
rb_define_method(rb_cBuffer, "to_s", Buffer_get_data, 0);
|
|
66
|
+
rb_define_method(rb_cBuffer, "empty?", Buffer_is_empty, 0);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
VALUE Get_Klass_Buffer(void) {
|
|
70
|
+
return rb_cBuffer;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
void *Get_Buffer_Struct(VALUE self) {
|
|
74
|
+
sfBuffer *ptr;
|
|
75
|
+
TypedData_Get_Struct(self, sfBuffer, &Buffer_data_type, ptr);
|
|
76
|
+
return ptr;
|
|
77
|
+
}
|
data/ext/system/buffer.h
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#ifndef SFML_RB_SYSTEM_BUFFER_H
|
|
2
|
+
#define SFML_RB_SYSTEM_BUFFER_H
|
|
3
|
+
|
|
4
|
+
#include <ruby.h>
|
|
5
|
+
|
|
6
|
+
#include "core/sfml.h"
|
|
7
|
+
|
|
8
|
+
void Init_Buffer(VALUE rb_module);
|
|
9
|
+
|
|
10
|
+
VALUE Get_Klass_Buffer(void);
|
|
11
|
+
|
|
12
|
+
void *Get_Buffer_Struct(VALUE self);
|
|
13
|
+
|
|
14
|
+
#endif //SFML_RB_SYSTEM_BUFFER_H
|
data/ext/system/clock.c
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#include "system/clock.h"
|
|
2
|
+
|
|
3
|
+
#include <stdio.h>
|
|
4
|
+
|
|
5
|
+
#include "system/time.h"
|
|
6
|
+
#include "system/vec2.h"
|
|
7
|
+
#include "core/macros.h"
|
|
8
|
+
#include "core/sfml.h"
|
|
9
|
+
|
|
10
|
+
static VALUE rb_cClock;
|
|
11
|
+
|
|
12
|
+
static sfClock *Clock_create() {
|
|
13
|
+
return sfClock_create();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
static void Clock_free(void *ptr) {
|
|
17
|
+
sfClock_destroy(ptr);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
static const rb_data_type_t Clock_data_type = {
|
|
21
|
+
.wrap_struct_name = "SFML::Clock",
|
|
22
|
+
.function = {.dmark = NULL, .dfree = Clock_free, .dsize = NULL},
|
|
23
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
static VALUE Clock_new_from(VALUE klass, sfClock *clock) {
|
|
27
|
+
VALUE self;
|
|
28
|
+
|
|
29
|
+
self = TypedData_Wrap_Struct(klass, &Clock_data_type, clock);
|
|
30
|
+
|
|
31
|
+
rb_obj_call_init(self, 0, NULL);
|
|
32
|
+
|
|
33
|
+
return self;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static VALUE Clock_new(VALUE klass) {
|
|
37
|
+
return Clock_new_from(klass, Clock_create());
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
static VALUE Clock_init(VALUE self) {
|
|
41
|
+
return self;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static VALUE Clock_get_elapsed_time(VALUE self) {
|
|
45
|
+
return time_to_rb(sfClock_getElapsedTime(Get_Clock_Struct(self)));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
static VALUE Clock_restart(VALUE self) {
|
|
49
|
+
return time_to_rb(sfClock_restart(Get_Clock_Struct(self)));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
static VALUE Clock_reset(VALUE self) {
|
|
53
|
+
return time_to_rb(sfClock_reset(Get_Clock_Struct(self)));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
static VALUE Clock_is_running(VALUE self) {
|
|
57
|
+
return BOOL2RB(sfClock_isRunning(Get_Clock_Struct(self)));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
static VALUE Clock_start(VALUE self) {
|
|
61
|
+
sfClock_start(Get_Clock_Struct(self));
|
|
62
|
+
return self;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
static VALUE Clock_stop(VALUE self) {
|
|
66
|
+
sfClock_stop(Get_Clock_Struct(self));
|
|
67
|
+
return self;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
static VALUE Clock_copy(VALUE self) {
|
|
71
|
+
return Clock_new_from(Get_Klass_Clock(), sfClock_copy(Get_Clock_Struct(self)));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
void Init_Clock(VALUE rb_module) {
|
|
75
|
+
rb_cClock = rb_define_class_under(rb_module, "Clock", rb_cObject);
|
|
76
|
+
|
|
77
|
+
rb_define_singleton_method(rb_cClock, "new", Clock_new, 0);
|
|
78
|
+
|
|
79
|
+
// methods
|
|
80
|
+
rb_define_method(rb_cClock, "initialize", Clock_init, 0);
|
|
81
|
+
rb_define_method(rb_cClock, "restart!", Clock_restart, 0);
|
|
82
|
+
rb_define_method(rb_cClock, "reset!", Clock_reset, 0);
|
|
83
|
+
rb_define_method(rb_cClock, "start!", Clock_start, 0);
|
|
84
|
+
rb_define_method(rb_cClock, "stop!", Clock_stop, 0);
|
|
85
|
+
rb_define_method(rb_cClock, "copy", Clock_copy, 0);
|
|
86
|
+
|
|
87
|
+
// getters
|
|
88
|
+
rb_define_method(rb_cClock, "elapsed_time", Clock_get_elapsed_time, 0);
|
|
89
|
+
rb_define_method(rb_cClock, "running?", Clock_is_running, 0);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
void *Get_Clock_Struct(VALUE self) {
|
|
93
|
+
sfClock *clock;
|
|
94
|
+
TypedData_Get_Struct(self, sfClock, &Clock_data_type, clock);
|
|
95
|
+
return clock;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
VALUE Get_Klass_Clock() {
|
|
99
|
+
return rb_cClock;
|
|
100
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
#ifndef
|
|
2
|
-
#define
|
|
1
|
+
#ifndef SFML_RB_SYSTEM_CLOCK_H
|
|
2
|
+
#define SFML_RB_SYSTEM_CLOCK_H
|
|
3
3
|
|
|
4
4
|
#include <ruby.h>
|
|
5
5
|
|
|
@@ -9,4 +9,4 @@ void *Get_Clock_Struct(VALUE self);
|
|
|
9
9
|
|
|
10
10
|
VALUE Get_Klass_Clock();
|
|
11
11
|
|
|
12
|
-
#endif //
|
|
12
|
+
#endif //SFML_RB_SYSTEM_CLOCK_H
|