Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make eject return the executed command or NULL #125

Merged
merged 1 commit into from
Apr 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 18 additions & 14 deletions AERA/test_mem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ TestMem<O, S>::findObject(std::vector<Code*> *objects, const char* name) {
return NULL;
}

template<class O, class S> void TestMem<O, S>::eject(Code *command) {
template<class O, class S> Code* TestMem<O, S>::eject(Code *command) {
uint16 function = (command->code(CMD_FUNCTION).atom_ >> 8) & 0x000000FF;

if (function == ready_opcode_) {
Expand All @@ -167,43 +167,44 @@ template<class O, class S> void TestMem<O, S>::eject(Code *command) {
if (!(command->code_size() >= 3 && command->code(args_set_index + 2).getDescriptor() == Atom::R_PTR &&
command->references_size() > command->code(args_set_index + 2).asIndex())) {
cout << "WARNING: Cannot get the object for ready \"ball\"" << endl;
return;
return NULL;
}
if (!velocity_y_property_) {
cout << "WARNING: Can't find the velocity_y property" << endl;
return;
return NULL;
}
if (!position_y_property_) {
cout << "WARNING: Can't find the position_y property" << endl;
return;
return NULL;
}

Code* obj = command->get_reference(command->code(args_set_index + 2).asIndex());
if (!position_y_obj_) {
// This is the first call. Remember the object whose position we're reporting.
position_y_obj_ = obj;
startTimeTickThread();
return command;
}
else {
if (position_y_obj_ != obj)
// For now, don't allow tracking multiple objects.
return;
return NULL;
}
}
else {
cout << "WARNING: Ignoring unrecognized ready command identifier: " << identifier << endl;
return;
return NULL;
}
}
}
else if (function == set_velocity_y_opcode_) {
if (!velocity_y_property_) {
cout << "WARNING: Can't find the velocity_y property" << endl;
return;
return NULL;
}
if (!position_y_property_) {
cout << "WARNING: Can't find the position_y property" << endl;
return;
return NULL;
}

auto now = r_exec::Now();
Expand All @@ -220,22 +221,23 @@ template<class O, class S> void TestMem<O, S>::eject(Code *command) {
else {
if (position_y_obj_ != obj)
// For now, don't allow tracking the velocity of multiple objects.
return;
return NULL;
}

velocity_y_ = command->code(args_set_index + 2).asFloat();
// Let onTimeTick inject the new velocity_y.
return command;
}
else if (function == move_y_plus_opcode_ ||
function == move_y_minus_opcode_) {
if (!position_property_) {
cout << "WARNING: Can't find the position property" << endl;
return;
return NULL;
}
for (int i = 0; i <= 9; ++i) {
if (!yEnt_[i]) {
cout << "WARNING: Can't find the entities y0, y1, etc." << endl;
return;
return NULL;
}
}

Expand All @@ -249,17 +251,16 @@ template<class O, class S> void TestMem<O, S>::eject(Code *command) {
discretePositionObj_ = obj;
discretePosition_ = yEnt_[0];
startTimeTickThread();
return;
}
else {
if (discretePositionObj_ != obj)
// For now, don't allow tracking multiple objects.
return;
return NULL;
}

if (nextDiscretePosition_)
// A previous move command is still pending execution.
return;
return NULL;

// nextDiscretePosition_ will become the position at the next sampling period.
lastCommandTime_ = now;
Expand All @@ -277,7 +278,10 @@ template<class O, class S> void TestMem<O, S>::eject(Code *command) {
}
}
// Let onTimeTick inject the new position.
return command;
}

return NULL;
}

template<class O, class S> void TestMem<O, S>::onTimeTick() {
Expand Down
7 changes: 6 additions & 1 deletion AERA/test_mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,13 @@ template<class O, class S> class TestMem :

/**
* Override eject to check for (cmd set_velocity_y ...) and other implemented commands.
* \param command The command from the Replicode (cmd ...).
* \return The given command if it is executed as-is, or a new command object of the command
* that is actually executed. The program controller will make a fact from the command and
* inject it as the efferent copy. However, if the command is not executed, then return NULL
* and the program controller will put an anti-fact of the command in the mk.rdx reduction.
*/
virtual void eject(r_code::Code *command);
virtual r_code::Code* eject(r_code::Code *command);

/**
* This is called when runInDiagnosticTime() updates the tickTime. Just call
Expand Down
3 changes: 2 additions & 1 deletion r_exec/mem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ void _Mem::pushTimeJob(TimeJob *j) {
void _Mem::eject(View *view, uint16 nodeID) {
}

void _Mem::eject(Code *command) {
r_code::Code* _Mem::eject(Code *command) {
// This is only for debugging
/*
uint16 function = (command->code(CMD_FUNCTION).atom_ >> 8) & 0x000000FF;
Expand All @@ -716,6 +716,7 @@ void _Mem::eject(Code *command) {
//command->trace();
}
*/
return NULL;
}

////////////////////////////////////////////////////////////////
Expand Down
13 changes: 10 additions & 3 deletions r_exec/mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -547,9 +547,16 @@ class r_exec_dll _Mem :
// To be redefined by object transport aware subcalsses.
virtual void eject(View *view, uint16 nodeID);

// From rMem to I/O device.
// To be redefined by object transport aware subcalsses.
virtual void eject(r_code::Code *command);
/**
* This is called by the program controller to eject a command from rMem to the
* I/O device. This method should be redefined by object transport-aware subclasses.
* \param command The command from the Replicode (cmd ...).
* \return The given command if it is executed as-is, or a new command object of the command
* that is actually executed. The program controller will make a fact from the command and
* inject it as the efferent copy. However, if the command is not executed, then return NULL
* and the program controller will put an anti-fact of the command in the mk.rdx reduction.
*/
virtual r_code::Code* eject(r_code::Code *command);

virtual r_code::Code *_build_object(Atom head) const = 0;
virtual r_code::Code *build_object(Atom head) const = 0;
Expand Down
28 changes: 17 additions & 11 deletions r_exec/pgm_overlay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,25 +457,31 @@ bool InputLessPGMOverlay::inject_productions() {
}
} else if (cmd[0].asOpcode() == Opcodes::Cmd) { // command to an external device, build a cmd object and send it.

Code *command = _Mem::Get()->build_object(cmd[0]);
cmd.copy(command, 0);
P<Code> command = _Mem::Get()->build_object(cmd[0]);
cmd.copy((Code*)command, 0);

_Mem::Get()->eject(command);
Code* executedCommand = _Mem::Get()->eject(command);

// Build a fact of the command and inject it in stdin. Give the fact an uncertainty range since we don't know when
// it will be executed. Otherwise a fact with zero duration may not overlap a fact, making predictions fail.
// We offset the beginning of the uncertainty range by 2*GetTimeTolerance() (the same as SYNC_HOLD)
// so that CTPX::reduce will not fail due to "cause in sync with the premise".
Code *fact = new Fact(command, now + 2 * Utils::GetTimeTolerance(), now + _Mem::Get()->get_sampling_period(), 1, 1);
View *view = new View(View::SYNC_ONCE, now, 1, 1, _Mem::Get()->get_stdin(), getView()->get_host(), fact); // SYNC_ONCE, sln=1, res=1,
_Mem::Get()->inject(view);
string mk_rdx_info = "";
P<Code> fact;
if (executedCommand) {
fact = new Fact(command, now + 2 * Utils::GetTimeTolerance(), now + _Mem::Get()->get_sampling_period(), 1, 1);
View *view = new View(View::SYNC_ONCE, now, 1, 1, _Mem::Get()->get_stdin(), getView()->get_host(), fact); // SYNC_ONCE, sln=1, res=1,
_Mem::Get()->inject(view);
string mk_rdx_info = "";
#ifdef WITH_DEBUG_OID
if (mk_rdx)
// We don't know the mk.rdx OID yet, so use the debug OID.
mk_rdx_info = " mk.rdx(" + to_string(mk_rdx->get_debug_oid()) + "):";
if (mk_rdx)
// We don't know the mk.rdx OID yet, so use the debug OID.
mk_rdx_info = " mk.rdx(" + to_string(mk_rdx->get_debug_oid()) + "):";
#endif
OUTPUT_LINE(IO_DEVICE_INJ_EJT, Utils::RelativeTime(Now()) << mk_rdx_info << " I/O device eject " << fact->get_oid());
OUTPUT_LINE(IO_DEVICE_INJ_EJT, Utils::RelativeTime(Now()) << mk_rdx_info << " I/O device eject " << fact->get_oid());
}
else
// The command wasn't executed. Set fact to an anti-fact of the original command and record in the mk_rdx.
fact = new AntiFact(command, after, before, 1, 1);

if (mk_rdx) {

Expand Down