RemainInMotion icon indicating copy to clipboard operation
RemainInMotion copied to clipboard

OpenComputers support

Open SashaBorandi opened this issue 11 years ago • 17 comments

You can connect OpenComputers support?

SashaBorandi avatar Apr 15 '14 12:04 SashaBorandi

Sure, I'll work on it.

planetguy32 avatar Apr 16 '14 12:04 planetguy32

Have you tried OpenComponents? It says it supports Computercraft peripherals, and Remain in Motion's carriage controller is a CC peripheral.

planetguy32 avatar Apr 16 '14 15:04 planetguy32

Yes, but the block is not present in the Carriage Controllers list.

SashaBorandi avatar Apr 16 '14 15:04 SashaBorandi

You mean that it isn't listed in its tooltip as compatible with OpenComputers? That's true, but it should be compatible anyway.

planetguy32 avatar Apr 16 '14 16:04 planetguy32

2014-04-17_20 19 17 No Carriage Controllers? Mod ComputerCraft, I do not have...

SashaBorandi avatar Apr 17 '14 14:04 SashaBorandi

Ahh, I see. I can fix that.

planetguy32 avatar Apr 17 '14 19:04 planetguy32

OpenFrames is a fork of RiM that has OC support. I am in talks with their devs to merge our efforts so far into Remain in Motion.

asiekierka avatar Apr 23 '14 19:04 asiekierka

I've refactored CC support in such a way that makes supporting OC without adaptor blocks impossible without lots of tricky ASM. Adapter support should hopefully work, but I'll look into it.

planetguy32 avatar Aug 26 '14 21:08 planetguy32

I just gave this a try, but somehow the controller seems to not even work in CC itself? I see the SPMethod annotation, which seems to be used by your peripheral abstraction code, but that code isn't in the RemIM JAR from what I can tell, and I didn't find an extra "lib" download.

That was with: RemIM 2.1.0, CC1.64pr4, Forge 1208.

Looking at the code, though, it'd probably not work in OC, because of the good old "suspend the computer thread until it moved in the main thread". OC computers can't be saved while performing a call (because the Lua coroutine can't be saved while it's being executed), which they would be if the call were to be made asynchronously (like from CC); leading to a deadlock (server thread waiting for computer thread to finish so it can save the computer, computer thread waiting in the controller callback for the server thread to make the move). And if it were to be made synchronously (i.e. via the server thread, which is actually the default in OC) it'd just stop, because the server thread would basically wait for itself. That's what it was like in RiM anyway, I might be missing something here, just had a quick look.

Long story short, to make OC work, the call has to be decoupled from the actual move, i.e. return from the callback immediately and send an event to the computer after the move/simulation was performed. I might have the time to give this a try next week-end, unless someone else wants to have a go at it.


On a different note, you may want to synchronize the Move and SetupMotion methods, otherwise I think there's a race condition: computer thread calling SetupMotion, setting MoveDirection, and before it can set Simulating the server thread sees that MoveDirection is set and performs an actual move / only performs a simulation (depending on the previous value of Simulating).

fnuecke avatar Aug 30 '14 12:08 fnuecke

Ok, good to know. The CC integration was broken during the 1.7 port, since I didn't have a CC for 1.7 to test it on, and the SPMethod annotation was to connect to a library that I never finished. (Its replacement has been committed, and is tested working with CC.)

planetguy32 avatar Sep 02 '14 18:09 planetguy32

I've taken another stab at implementing the OC API, but if I comment out the CC integration it doesn't show up in the peripherals list. (Try rebuilding dev workspace?)

planetguy32 avatar Nov 03 '14 19:11 planetguy32

While the component itself shows up just fine for me, there's still a trivial and a major issue.

The trivial being that the return (Object[]) m.invoke(this, args.toArray()); needs to be return (Object[]) m.invoke(this, new Object[]{args.toArray()}); because the result of toArray is itself interpreted as varargs otherwise, leading to an invalid argument type error.

The major being the wait(), which potentially leads to a deadlock (if the carriage moves the calling computer). The difficult part here will be to get the result back to OC. As mentioned above, this needs to happen asynchronously (because the computer might be moved by the carriage controller, and it cannot be saved while it is executing). I'm honestly not sure how to best tackle this, in part because I'm not sure about the carriage controller tile entity's life cycle; does the same TE get applied to the "moved" block, or does that get a new one? The latter would mean a delayed response would also have to be saved to NBT by the controller itself...

I'll mull over this some more to see if I can come up with a nicer approach. If you're itching to release the CC support, I hate to say it, but I think it'd be best to actually disable the OC support for now, to avoid said deadlocks, until a non-blocking move callback for OC has been implemented.

fnuecke avatar Nov 06 '14 12:11 fnuecke

It would be a lot easier to maintain the system if it only set up motion, and didn't actually tell you if it worked. Would people mind this change?

planetguy32 avatar Nov 06 '14 21:11 planetguy32

Could you report success/failure as event/signal? this would help fix the issue and work with both OC and CC.

Xfel avatar Nov 07 '14 10:11 Xfel

The main advantage of addressing the controller directly vs. triggering it via redstone is that you can tell whether the command was successful, and if it wasn't why it wasn't, so some way of telling that should remain, I think.

Events could work, it might just be tricky to get the timing right, so the events don't fall between the cracks (i.e. get ignored because the computer has not yet fully rebooted/resumed after the move, for example). If that can work reliably (say, dispatch it with some "considered-to-be-safe" delay) I'm all for that!

Alternatively, there could be a new callback that allows querying the result of the last move() request. That would need a different implementation for CC vs. OC; while OC callbacks can run "synchronized" (i.e. run in the server thread) CC ones always run in an executor thread, so if the move isn't finished the wait() that's in the move right now would need to go there, I guess.

fnuecke avatar Nov 07 '14 11:11 fnuecke

I'd be inclined to require a separate call to query the state of the carriage. It seems easier than having to write and maintain parallel event implementations for OC and CC.

planetguy32 avatar Nov 09 '14 01:11 planetguy32

Maybe just "decouple" the CC and OC callbacks completely (Lua programs would have to be written for each mod specifically anyway), i.e. keep it the way it is for CC where it works just fine, and switch to the async move() + result() callback approach for OC?

While keeping it uniform would be nice, I'm not sure the potential code mess (and CC API break, I guess) would justify it in this case?

fnuecke avatar Nov 10 '14 22:11 fnuecke