2024-08-06 23:30:00 +02:00
|
|
|
package mp.code;
|
|
|
|
|
2024-10-10 12:04:20 +02:00
|
|
|
import mp.code.data.BufferUpdate;
|
2024-08-06 23:30:00 +02:00
|
|
|
import mp.code.data.TextChange;
|
2024-09-05 02:45:33 +02:00
|
|
|
import mp.code.exceptions.ControllerException;
|
2024-08-06 23:30:00 +02:00
|
|
|
|
2024-08-07 10:22:01 +02:00
|
|
|
import java.util.Optional;
|
2024-09-17 23:16:39 +02:00
|
|
|
import java.util.function.Consumer;
|
2024-08-07 10:22:01 +02:00
|
|
|
|
2024-09-17 23:16:39 +02:00
|
|
|
/**
|
|
|
|
* Allows interaction with a CodeMP buffer, which in simple terms is a document
|
|
|
|
* that multiple people can edit concurrently.
|
|
|
|
* <p>
|
|
|
|
* It is generally safer to avoid storing this directly, see the api notes for {@link Workspace}.
|
|
|
|
*/
|
|
|
|
public final class BufferController {
|
2024-08-06 23:30:00 +02:00
|
|
|
private final long ptr;
|
|
|
|
|
|
|
|
BufferController(long ptr) {
|
|
|
|
this.ptr = ptr;
|
2024-09-18 15:36:11 +02:00
|
|
|
Extensions.CLEANER.register(this, () -> free(ptr));
|
2024-08-06 23:30:00 +02:00
|
|
|
}
|
|
|
|
|
2024-08-14 19:09:48 +02:00
|
|
|
private static native String get_name(long self);
|
2024-09-17 23:16:39 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the name (path) of the buffer.
|
|
|
|
* @return the path of the buffer
|
|
|
|
*/
|
2024-08-06 23:30:00 +02:00
|
|
|
public String getName() {
|
|
|
|
return get_name(this.ptr);
|
|
|
|
}
|
|
|
|
|
2024-09-05 02:45:33 +02:00
|
|
|
private static native String get_content(long self) throws ControllerException;
|
2024-09-17 23:16:39 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the contents of the buffer as a flat string.
|
|
|
|
* This may return incomplete results if called immediately after attaching.
|
|
|
|
* @return the contents fo the buffer as a flat string
|
|
|
|
* @throws ControllerException if the controller was stopped
|
|
|
|
*/
|
2024-09-05 02:45:33 +02:00
|
|
|
public String getContent() throws ControllerException {
|
2024-08-06 23:30:00 +02:00
|
|
|
return get_content(this.ptr);
|
|
|
|
}
|
|
|
|
|
2024-10-10 12:04:20 +02:00
|
|
|
private static native BufferUpdate try_recv(long self) throws ControllerException;
|
2024-09-17 23:16:39 +02:00
|
|
|
|
|
|
|
/**
|
2024-10-10 12:04:20 +02:00
|
|
|
* Tries to get a {@link BufferUpdate} from the queue if any were present, and returns
|
2024-09-17 23:16:39 +02:00
|
|
|
* an empty optional otherwise.
|
|
|
|
* @return the first text change in queue, if any are present
|
|
|
|
* @throws ControllerException if the controller was stopped
|
|
|
|
*/
|
2024-10-10 12:04:20 +02:00
|
|
|
public Optional<BufferUpdate> tryRecv() throws ControllerException {
|
2024-08-07 10:22:01 +02:00
|
|
|
return Optional.ofNullable(try_recv(this.ptr));
|
|
|
|
}
|
|
|
|
|
2024-10-10 12:04:20 +02:00
|
|
|
private static native BufferUpdate recv(long self) throws ControllerException;
|
2024-09-17 23:16:39 +02:00
|
|
|
|
|
|
|
/**
|
2024-10-10 12:04:20 +02:00
|
|
|
* Blocks until a {@link BufferUpdate} is available and returns it.
|
2024-09-17 23:16:39 +02:00
|
|
|
* @return the text change update that occurred
|
|
|
|
* @throws ControllerException if the controller was stopped
|
|
|
|
*/
|
2024-10-10 12:04:20 +02:00
|
|
|
public BufferUpdate recv() throws ControllerException {
|
2024-08-07 10:22:01 +02:00
|
|
|
return recv(this.ptr);
|
2024-08-06 23:30:00 +02:00
|
|
|
}
|
|
|
|
|
2024-09-05 02:45:33 +02:00
|
|
|
private static native void send(long self, TextChange change) throws ControllerException;
|
2024-09-17 23:16:39 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Tries to send a {@link TextChange} update.
|
2024-10-15 21:55:23 +02:00
|
|
|
* @param change the update to send
|
2024-09-17 23:16:39 +02:00
|
|
|
* @throws ControllerException if the controller was stopped
|
|
|
|
*/
|
2024-09-05 02:45:33 +02:00
|
|
|
public void send(TextChange change) throws ControllerException {
|
2024-09-17 23:16:39 +02:00
|
|
|
send(this.ptr, change);
|
2024-08-06 23:30:00 +02:00
|
|
|
}
|
|
|
|
|
2024-09-17 23:16:39 +02:00
|
|
|
private static native void callback(long self, Consumer<BufferController> cb);
|
|
|
|
|
|
|
|
/**
|
2024-10-10 12:04:20 +02:00
|
|
|
* Registers a callback to be invoked whenever a {@link BufferUpdate} occurs.
|
2024-09-17 23:16:39 +02:00
|
|
|
* This will not work unless a Java thread has been dedicated to the event loop.
|
2024-10-15 21:55:23 +02:00
|
|
|
* @param cb a {@link Consumer} that receives the controller when the change occurs;
|
|
|
|
* you should probably spawn a new thread in here, to avoid deadlocking
|
2024-09-17 23:16:39 +02:00
|
|
|
* @see Extensions#drive(boolean)
|
|
|
|
*/
|
|
|
|
public void callback(Consumer<BufferController> cb) {
|
|
|
|
callback(this.ptr, cb);
|
2024-09-15 02:00:04 +02:00
|
|
|
}
|
|
|
|
|
2024-09-17 02:40:03 +02:00
|
|
|
private static native void clear_callback(long self);
|
2024-09-17 23:16:39 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Clears the registered callback.
|
|
|
|
* @see #callback(Consumer)
|
|
|
|
*/
|
2024-09-17 02:40:03 +02:00
|
|
|
public void clearCallback() {
|
|
|
|
clear_callback(this.ptr);
|
|
|
|
}
|
|
|
|
|
2024-09-17 23:16:39 +02:00
|
|
|
private static native void poll(long self) throws ControllerException;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Blocks until a {@link TextChange} is available.
|
|
|
|
* @throws ControllerException if the controller was stopped
|
|
|
|
*/
|
|
|
|
public void poll() throws ControllerException {
|
2024-09-17 02:40:03 +02:00
|
|
|
poll(this.ptr);
|
|
|
|
}
|
|
|
|
|
2024-10-10 12:04:20 +02:00
|
|
|
private static native void ack(long self, long[] version);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Acknowledges that a certain CRDT version has been correctly applied.
|
|
|
|
* @param version the version to acknowledge
|
|
|
|
* @see BufferUpdate#version
|
|
|
|
*/
|
|
|
|
public void ack(long[] version) {
|
|
|
|
ack(this.ptr, version);
|
|
|
|
}
|
|
|
|
|
2024-08-06 23:30:00 +02:00
|
|
|
private static native void free(long self);
|
2024-09-17 02:40:03 +02:00
|
|
|
|
|
|
|
static {
|
2024-09-18 14:54:54 +02:00
|
|
|
NativeUtils.loadLibraryIfNeeded();
|
2024-09-17 02:40:03 +02:00
|
|
|
}
|
2024-08-06 23:30:00 +02:00
|
|
|
}
|