ares-scripties/applications/subsys.lsl

147 lines
4.6 KiB
Plaintext

/*
* Subsystem Status Notifications Program
*
* Duplicates a fair amount of _power, not for redistribution.
*/
#define DEBUG
#include <ARES/a>
#define CLIENT_VERSION "0.0.1"
#define CLIENT_VERSION_TAGS "alpha 1"
integer power_on = 1;
integer sys_state = 0xFFFFFFFF;
integer forbidden_state = 0;
integer masked_state = 0;
string power_systems = "{}";
string power_system_names = "{}";
integer C_LIGHTS = NOWHERE;
update_state() {
string s_status = llLinksetDataRead("status");
sys_state = (integer)getjs(s_status, ["state"]);
power_on = (integer)getjs(s_status, ["on"]);
forbidden_state = (integer)getjs(s_status, ["forbidden"]);
masked_state = 0;
if (!power_on) {
// Power off - all subsystems will be off, and light bus will be messaged.
// No need to continue update.
#ifdef DEBUG
echo("Powered off, no subsystems to check");
#endif
return;
}
integer psi = 0;
string ps;
while ((ps = getjs(power_systems, [(string)psi])) != JSON_INVALID) {
integer system_forbidden = (forbidden_state & (1 << psi)) != 0;
integer system_enabled = (sys_state & (1 << psi)) != 0;
if (system_forbidden) {
// System forbidden
if (system_enabled) {
// System forbidden, but status reports enabled.
// Shouldn't happen, sanity check just in case.
sys_state = sys_state & ~(1 << psi);
}
} else if (system_enabled) {
// System enabled
list psreqs = js2list(getjs(ps, ["req"]));
integer psri = count(psreqs);
while (psri--) {
integer psreq = geti(psreqs, psri);
if (!(sys_state & (1 << psreq)) || ((forbidden_state & (1 << psreq)) != 0)) {
// Requirement disabled or forbidden, system masked.
sys_state = sys_state & ~(1 << psi);
masked_state = masked_state | (1 << psi);
jump psribrk;
}
}
@psribrk;
} // else | System disabled
++psi;
}
if (C_LIGHTS == NOWHERE) {
echo("[" + PROGRAM_NAME + "] light bus channel not set");
return;
}
list light_msg = ["subsys", sys_state, masked_state, forbidden_state];
io_tell(NULL_KEY, C_LIGHTS, concat(light_msg, " "));
}
main(integer src, integer n, string m, key outs, key ins, key user) {
#ifdef DEBUG
echo("[" + PROGRAM_NAME + "] signal " + (string)n + ": " + m);
#endif
if (n == SIGNAL_INVOKE) {
list argv = split(m, " ");
integer argc = count(argv);
string cmd = gets(argv, 1);
string output_msg = "";
if (argc == 1 || cmd == "help") {
output_msg = "Syntax: " + PROGRAM_NAME + " <action>";
} else if (cmd == "query") {
// send current status without updating
list light_msg = ["subsys", sys_state, masked_state, forbidden_state];
io_tell(NULL_KEY, C_LIGHTS, concat(light_msg, " "));
} else {
output_msg = "Unknown command \"" + cmd + "\".";
}
if(output_msg != "")
print(outs, user, output_msg);
} else if (n == SIGNAL_NOTIFY) {
list argv = splitnulls(m, " ");
string cmd = gets(argv, 1);
if (cmd == "update") {
update_state();
}
#ifdef DEBUG
else {
echo("[" + PROGRAM_NAME + "] unrecognised notify " + m);
}
#endif
} else if (n == SIGNAL_INIT) {
#ifdef DEBUG
echo("[" + PROGRAM_NAME + "] init event");
#endif
if (llGetAttached()) {
C_LIGHTS = 105 - (integer)("0x" + substr(avatar, 29, 35));
} else {
C_LIGHTS = 105 - (integer)("0x" + substr(KERNEL, 29, 35));
}
string s_power = llLinksetDataRead("power");
power_systems = getjs(s_power, ["system"]);
integer psi = 0;
string ps = "";
while ((ps = getjs(power_systems, [(string)psi])) != JSON_INVALID) {
string psname = getjs(ps, ["name"]);
power_system_names = setjs(power_system_names, [psname], (string)psi);
++psi;
}
#ifdef DEBUG
echo("[" + PROGRAM_NAME + "] (DEBUG) available subsystems: " + (string)psi);
#endif
update_state();
} else if (n == SIGNAL_UNKNOWN_SCRIPT) {
echo("[" + PROGRAM_NAME + "] failed to run '" + m + "' (kernel could not find the program specified)");
} else {
echo("[" + PROGRAM_NAME + "] unimplemented signal " + (string)n + ": " + m);
}
}
#include <ARES/program>