mirror of
https://github.com/janet-lang/janet
synced 2024-06-14 09:26:49 +00:00
Add channel marshalling.
This commit is contained in:
parent
bfcfd58259
commit
76be8006a4
|
@ -2,6 +2,7 @@
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## ??? - Unreleased
|
## ??? - Unreleased
|
||||||
|
- Channels can now be marshalled. Pending state is not saved, only items in the channel.
|
||||||
- Use the new `.length` function pointer on abstract types for lengths. Adding
|
- Use the new `.length` function pointer on abstract types for lengths. Adding
|
||||||
a `length` method will still work as well.
|
a `length` method will still work as well.
|
||||||
- Support byte views on abstract types with the `bytes` function pointer.
|
- Support byte views on abstract types with the `bytes` function pointer.
|
||||||
|
|
|
@ -1175,14 +1175,48 @@ static Janet janet_chanat_next(void *p, Janet key) {
|
||||||
return janet_nextmethod(ev_chanat_methods, key);
|
return janet_nextmethod(ev_chanat_methods, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void janet_chanat_marshal(void *p, JanetMarshalContext *ctx) {
|
||||||
|
JanetChannel *channel = (JanetChannel *)p;
|
||||||
|
janet_marshal_byte(ctx, channel->closed);
|
||||||
|
janet_marshal_int(ctx, channel->limit);
|
||||||
|
int32_t count = janet_q_count(&channel->items);
|
||||||
|
janet_marshal_int(ctx, count);
|
||||||
|
JanetQueue *items = &channel->items;
|
||||||
|
Janet *data = channel->items.data;
|
||||||
|
if (items->head <= items->tail) {
|
||||||
|
for (int32_t i = items->head; i < items->tail; i++)
|
||||||
|
janet_marshal_janet(ctx, data[i]);
|
||||||
|
} else {
|
||||||
|
for (int32_t i = items->head; i < items->capacity; i++)
|
||||||
|
janet_marshal_janet(ctx, data[i]);
|
||||||
|
for (int32_t i = 0; i < items->tail; i++)
|
||||||
|
janet_marshal_janet(ctx, data[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *janet_chanat_unmarshal(JanetMarshalContext *ctx) {
|
||||||
|
JanetChannel *abst = janet_unmarshal_abstract(ctx, sizeof(JanetChannel));
|
||||||
|
uint8_t is_closed = janet_unmarshal_byte(ctx);
|
||||||
|
int32_t limit = janet_unmarshal_int(ctx);
|
||||||
|
int32_t count = janet_unmarshal_int(ctx);
|
||||||
|
if (count < 0) janet_panic("invalid negative channel count");
|
||||||
|
janet_chan_init(abst, limit, 0);
|
||||||
|
abst->closed = !!is_closed;
|
||||||
|
for (int32_t i = 0; i < count; i++) {
|
||||||
|
Janet item = janet_unmarshal_janet(ctx);
|
||||||
|
janet_q_push(&abst->items, &item, sizeof(item));
|
||||||
|
}
|
||||||
|
return abst;
|
||||||
|
}
|
||||||
|
|
||||||
const JanetAbstractType janet_channel_type = {
|
const JanetAbstractType janet_channel_type = {
|
||||||
"core/channel",
|
"core/channel",
|
||||||
janet_chanat_gc,
|
janet_chanat_gc,
|
||||||
janet_chanat_mark,
|
janet_chanat_mark,
|
||||||
janet_chanat_get,
|
janet_chanat_get,
|
||||||
NULL, /* put */
|
NULL, /* put */
|
||||||
NULL, /* marshal */
|
janet_chanat_marshal,
|
||||||
NULL, /* unmarshal */
|
janet_chanat_unmarshal,
|
||||||
NULL, /* tostring */
|
NULL, /* tostring */
|
||||||
NULL, /* compare */
|
NULL, /* compare */
|
||||||
NULL, /* hash */
|
NULL, /* hash */
|
||||||
|
|
|
@ -265,4 +265,15 @@
|
||||||
(ev/do-thread
|
(ev/do-thread
|
||||||
(assert (ev/take ch) "channel packing bug for threaded abstracts on threaded channels."))
|
(assert (ev/take ch) "channel packing bug for threaded abstracts on threaded channels."))
|
||||||
|
|
||||||
|
# marshal channels
|
||||||
|
|
||||||
|
(def ch (ev/chan 10))
|
||||||
|
(ev/give ch "hello")
|
||||||
|
(ev/give ch "world")
|
||||||
|
(def ch2 (-> ch marshal unmarshal))
|
||||||
|
(def item1 (ev/take ch2))
|
||||||
|
(def item2 (ev/take ch2))
|
||||||
|
(assert (= item1 "hello"))
|
||||||
|
(assert (= item2 "world"))
|
||||||
|
|
||||||
(end-suite)
|
(end-suite)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user