==> src/fleet_groups.c <==1/* fleet.rs: new_epoch, group_policy, reform. */
2#include "mesh/fleet_groups.h"
3#include "mesh/mt.h"
4
5void mfg_new_epoch(mfd_group *g, ml_list members) {
6 g->epoch += 1;
7 g->cycle = 0;
8 g->op = (mfd_op){MFD_OP_NONE, 0, 0};
9 ml_free(&g->members);
10 g->members = members;
11 g->state = MFD_RUNNING;
12}
13
14bool mfg_policy(const mfd_group *g, uint32_t up, int64_t paused_ms, mfd_group *out) {
15 bool all = (mfd_group_mask(g) & ~up) == 0;
16 if (g->state == MFD_RUNNING && !all) {
17 *out = mfd_group_clone(g);
18 out->state = MFD_PAUSED;
19 return true;
20 }
21 if (g->state == MFD_PAUSED && all && g->members.n) {
22 *out = mfd_group_clone(g);
23 mfg_new_epoch(out, ml_clone(&g->members));
24 return true;
25 }
26 if (g->state == MFD_PAUSED && g->on_loss == MFD_LOSS_REFORM && g->auto_ms > 0 && paused_ms >= 0 && (uint64_t)paused_ms >= g->auto_ms) {
27 ml_list survivors = {0};
28 for (size_t i = 0; i < g->members.n; i++)
29 if (up >> g->members.v[i] & 1) ml_push(&survivors, g->members.v[i]);
30 if (!survivors.n) return false;
31 *out = mfd_group_clone(g);
32 mfg_new_epoch(out, survivors);
33 return true;
34 }
35 return false;
36}
37
38bool mfg_reform(const mfd_group *g, const ml_list *eligible_up, mfd_group *out, char **err) {
39 if (!eligible_up->n) {
40 *err = mt_fmt("group %s: no member that can run %s is up", g->name, g->program);
41 return false;
42 }
43 *out = mfd_group_clone(g);
44 mfg_new_epoch(out, ml_clone(eligible_up));
45 return true;
46}