mirror of
https://github.com/hexedtech/codemp.git
synced 2024-12-25 14:24:54 +01:00
docs(java): written javadocs, removed unused class
This commit is contained in:
parent
54db029ecc
commit
27b56cbd03
20 changed files with 555 additions and 108 deletions
79
dist/java/src/mp/code/BufferController.java
vendored
79
dist/java/src/mp/code/BufferController.java
vendored
|
@ -1,14 +1,18 @@
|
|||
package mp.code;
|
||||
|
||||
import mp.code.data.Callback;
|
||||
import mp.code.data.Cursor;
|
||||
import mp.code.data.TextChange;
|
||||
import mp.code.exceptions.ControllerException;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class BufferController {
|
||||
/**
|
||||
* 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 {
|
||||
private final long ptr;
|
||||
|
||||
BufferController(long ptr) {
|
||||
|
@ -16,46 +20,97 @@ public class BufferController {
|
|||
}
|
||||
|
||||
private static native String get_name(long self);
|
||||
|
||||
/**
|
||||
* Gets the name (path) of the buffer.
|
||||
* @return the path of the buffer
|
||||
*/
|
||||
public String getName() {
|
||||
return get_name(this.ptr);
|
||||
}
|
||||
|
||||
private static native String get_content(long self) throws ControllerException;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
public String getContent() throws ControllerException {
|
||||
return get_content(this.ptr);
|
||||
}
|
||||
|
||||
private static native TextChange try_recv(long self) throws ControllerException;
|
||||
|
||||
/**
|
||||
* Tries to get a {@link TextChange} from the queue if any were present, and returns
|
||||
* an empty optional otherwise.
|
||||
* @return the first text change in queue, if any are present
|
||||
* @throws ControllerException if the controller was stopped
|
||||
*/
|
||||
public Optional<TextChange> tryRecv() throws ControllerException {
|
||||
return Optional.ofNullable(try_recv(this.ptr));
|
||||
}
|
||||
|
||||
private static native Cursor recv(long self) throws ControllerException;
|
||||
public Cursor recv() throws ControllerException {
|
||||
private static native TextChange recv(long self) throws ControllerException;
|
||||
|
||||
/**
|
||||
* Blocks until a {@link TextChange} is available and returns it.
|
||||
* @return the text change update that occurred
|
||||
* @throws ControllerException if the controller was stopped
|
||||
*/
|
||||
public TextChange recv() throws ControllerException {
|
||||
return recv(this.ptr);
|
||||
}
|
||||
|
||||
private static native void send(long self, TextChange change) throws ControllerException;
|
||||
|
||||
/**
|
||||
* Tries to send a {@link TextChange} update.
|
||||
* @throws ControllerException if the controller was stopped
|
||||
*/
|
||||
public void send(TextChange change) throws ControllerException {
|
||||
send(this.ptr, Objects.requireNonNull(change));
|
||||
send(this.ptr, change);
|
||||
}
|
||||
|
||||
private static native void callback(long self, Callback<BufferController> cb);
|
||||
public void callback(Callback<BufferController> cb) {
|
||||
callback(this.ptr, Objects.requireNonNull(cb));
|
||||
private static native void callback(long self, Consumer<BufferController> cb);
|
||||
|
||||
/**
|
||||
* Registers a callback to be invoked whenever a {@link TextChange} occurs.
|
||||
* This will not work unless a Java thread has been dedicated to the event loop.
|
||||
* @see Extensions#drive(boolean)
|
||||
*/
|
||||
public void callback(Consumer<BufferController> cb) {
|
||||
callback(this.ptr, cb);
|
||||
}
|
||||
|
||||
private static native void clear_callback(long self);
|
||||
|
||||
/**
|
||||
* Clears the registered callback.
|
||||
* @see #callback(Consumer)
|
||||
*/
|
||||
public void clearCallback() {
|
||||
clear_callback(this.ptr);
|
||||
}
|
||||
|
||||
private static native void poll(long self);
|
||||
public void poll() {
|
||||
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 {
|
||||
poll(this.ptr);
|
||||
}
|
||||
|
||||
private static native boolean stop(long self);
|
||||
|
||||
/**
|
||||
* Stops the controller. Any further calls to it will fail.
|
||||
* @return true if it was stopped successfully
|
||||
*/
|
||||
public boolean stop() {
|
||||
return stop(this.ptr);
|
||||
}
|
||||
|
|
118
dist/java/src/mp/code/Client.java
vendored
118
dist/java/src/mp/code/Client.java
vendored
|
@ -1,72 +1,150 @@
|
|||
package mp.code;
|
||||
|
||||
import lombok.Getter;
|
||||
import mp.code.data.Config;
|
||||
import mp.code.data.User;
|
||||
import mp.code.exceptions.ConnectionException;
|
||||
import mp.code.exceptions.ConnectionRemoteException;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class Client {
|
||||
/**
|
||||
* The main entrypoint of the library.
|
||||
* This is the only object you are expected to hold yourself; unlike all the others,
|
||||
* there are no copies of it managed exclusively by the library. When this is garbage
|
||||
* collected, it will free the underlying memory.
|
||||
* A Client is used to join and manage workspaces, and to obtain information about
|
||||
* the current session.
|
||||
*/
|
||||
@Getter
|
||||
public final class Client {
|
||||
private final long ptr;
|
||||
|
||||
public static native Client connect(Config config) throws ConnectionException;
|
||||
|
||||
Client(long ptr) {
|
||||
this.ptr = ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects to a remote CodeMP server and creates a {@link Client} instance
|
||||
* for interacting with it.
|
||||
* @param config a {@link Config} object containing the connection settings
|
||||
* @return a holder for the Client's pointer
|
||||
* @throws ConnectionException if an error occurs in communicating with the server
|
||||
*/
|
||||
public static native Client connect(Config config) throws ConnectionException;
|
||||
|
||||
private static native User get_user(long self);
|
||||
|
||||
/**
|
||||
* Gets information about the current user.
|
||||
* @return a {@link User} object representing the user
|
||||
*/
|
||||
public User getUser() {
|
||||
return get_user(this.ptr);
|
||||
}
|
||||
|
||||
private static native Workspace join_workspace(long self, String id) throws ConnectionException;
|
||||
public Workspace joinWorkspace(String id) throws ConnectionException {
|
||||
return join_workspace(this.ptr, Objects.requireNonNull(id));
|
||||
private static native Workspace join_workspace(long self, String workspaceId) throws ConnectionException;
|
||||
|
||||
/**
|
||||
* Joins a {@link Workspace} and returns it.
|
||||
* @param workspaceId the id of the workspace to connect to
|
||||
* @return the relevant {@link Workspace}
|
||||
* @throws ConnectionException if an error occurs in communicating with the server
|
||||
*/
|
||||
public Workspace joinWorkspace(String workspaceId) throws ConnectionException {
|
||||
return join_workspace(this.ptr, workspaceId);
|
||||
}
|
||||
|
||||
private static native void create_workspace(long self, String id) throws ConnectionRemoteException;
|
||||
public void createWorkspace(String id) throws ConnectionRemoteException {
|
||||
create_workspace(this.ptr, Objects.requireNonNull(id));
|
||||
private static native void create_workspace(long self, String workspaceId) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Creates a workspace. You need to call {@link #joinWorkspace(String)} to actually join
|
||||
* and interact with it.
|
||||
* @param workspaceId the id of the new workspace
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public void createWorkspace(String workspaceId) throws ConnectionRemoteException {
|
||||
create_workspace(this.ptr, workspaceId);
|
||||
}
|
||||
|
||||
private static native void delete_workspace(long self, String id) throws ConnectionRemoteException;
|
||||
public void deleteWorkspace(String id) throws ConnectionRemoteException {
|
||||
delete_workspace(this.ptr, Objects.requireNonNull(id));
|
||||
private static native void delete_workspace(long self, String workspaceId) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Deletes a workspace.
|
||||
* @param workspaceId the id of the workspace to delete
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public void deleteWorkspace(String workspaceId) throws ConnectionRemoteException {
|
||||
delete_workspace(this.ptr, workspaceId);
|
||||
}
|
||||
|
||||
private static native void invite_to_workspace(long self, String workspaceId, String user) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Invites a user to a workspace.
|
||||
* @param workspaceId the id of the new workspace
|
||||
* @param user the name of the user to invite
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public void inviteToWorkspace(String workspaceId, String user) throws ConnectionRemoteException {
|
||||
invite_to_workspace(this.ptr, Objects.requireNonNull(workspaceId), Objects.requireNonNull(user));
|
||||
invite_to_workspace(this.ptr, workspaceId, user);
|
||||
}
|
||||
|
||||
private static native String[] list_workspaces(long self, boolean owned, boolean invited) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Lists available workspaces according to certain filters.
|
||||
* @param owned if owned workspaces should be included
|
||||
* @param invited if workspaces the user is invited to should be included
|
||||
* @return an array of workspace IDs
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public String[] listWorkspaces(boolean owned, boolean invited) throws ConnectionRemoteException {
|
||||
return list_workspaces(this.ptr, owned, invited);
|
||||
}
|
||||
|
||||
private static native String[] active_workspaces(long self);
|
||||
|
||||
/**
|
||||
* Lists the currently active workspaces (the ones the user has currently joined).
|
||||
* @return an array of workspace IDs
|
||||
*/
|
||||
public String[] activeWorkspaces() {
|
||||
return active_workspaces(this.ptr);
|
||||
}
|
||||
|
||||
private static native boolean leave_workspace(long self, String id);
|
||||
public boolean leaveWorkspace(String id) {
|
||||
return leave_workspace(this.ptr, Objects.requireNonNull(id));
|
||||
private static native boolean leave_workspace(long self, String workspaceId);
|
||||
|
||||
/**
|
||||
* Leaves a workspace.
|
||||
* @param workspaceId the id of the workspaces to leave
|
||||
* @return true if it succeeded (usually fails if the workspace wasn't active)
|
||||
*/
|
||||
public boolean leaveWorkspace(String workspaceId) {
|
||||
return leave_workspace(this.ptr, workspaceId);
|
||||
}
|
||||
|
||||
private static native Workspace get_workspace(long self, String workspace);
|
||||
public Optional<Workspace> getWorkspace(String workspace) {
|
||||
return Optional.ofNullable(get_workspace(this.ptr, Objects.requireNonNull(workspace)));
|
||||
|
||||
/**
|
||||
* Gets an active workspace.
|
||||
* @param workspaceId the id of the workspaces to get
|
||||
* @return a {@link Workspace} with that name, if it was present and active
|
||||
*/
|
||||
public Optional<Workspace> getWorkspace(String workspaceId) {
|
||||
return Optional.ofNullable(get_workspace(this.ptr, workspaceId));
|
||||
}
|
||||
|
||||
private static native void refresh(long self) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Refreshes the current access token.
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public void refresh() throws ConnectionRemoteException {
|
||||
refresh(this.ptr);
|
||||
}
|
||||
|
||||
|
||||
private static native void free(long self);
|
||||
@Override
|
||||
protected void finalize() {
|
||||
|
|
61
dist/java/src/mp/code/CursorController.java
vendored
61
dist/java/src/mp/code/CursorController.java
vendored
|
@ -1,13 +1,17 @@
|
|||
package mp.code;
|
||||
|
||||
import mp.code.data.Callback;
|
||||
import mp.code.data.Cursor;
|
||||
import mp.code.exceptions.ControllerException;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class CursorController {
|
||||
/**
|
||||
* Allows interaction with the CodeMP cursor position tracking system.
|
||||
* <p>
|
||||
* It is generally safer to avoid storing this directly, see the api notes for {@link Workspace}.
|
||||
*/
|
||||
public final class CursorController {
|
||||
private final long ptr;
|
||||
|
||||
CursorController(long ptr) {
|
||||
|
@ -15,36 +19,75 @@ public class CursorController {
|
|||
}
|
||||
|
||||
private static native Cursor try_recv(long self) throws ControllerException;
|
||||
|
||||
/**
|
||||
* Tries to get a {@link Cursor} update from the queue if any were present, and returns
|
||||
* an empty optional otherwise.
|
||||
* @return the first cursor event in queue, if any are present
|
||||
* @throws ControllerException if the controller was stopped
|
||||
*/
|
||||
public Optional<Cursor> tryRecv() throws ControllerException {
|
||||
return Optional.ofNullable(try_recv(this.ptr));
|
||||
}
|
||||
|
||||
private static native Cursor recv(long self) throws ControllerException;
|
||||
|
||||
/**
|
||||
* Blocks until a {@link Cursor} update is available and returns it.
|
||||
* @return the cursor update that occurred
|
||||
* @throws ControllerException if the controller was stopped
|
||||
*/
|
||||
public Cursor recv() throws ControllerException {
|
||||
return recv(this.ptr);
|
||||
}
|
||||
|
||||
private static native void send(long self, Cursor cursor) throws ControllerException;
|
||||
|
||||
/**
|
||||
* Tries to send a {@link Cursor} update.
|
||||
* @throws ControllerException if the controller was stopped
|
||||
*/
|
||||
public void send(Cursor cursor) throws ControllerException {
|
||||
send(this.ptr, Objects.requireNonNull(cursor));
|
||||
send(this.ptr, cursor);
|
||||
}
|
||||
|
||||
private static native void callback(long self, Callback<CursorController> cb);
|
||||
public void callback(Callback<CursorController> cb) {
|
||||
callback(this.ptr, Objects.requireNonNull(cb));
|
||||
private static native void callback(long self, Consumer<CursorController> cb);
|
||||
|
||||
/**
|
||||
* Registers a callback to be invoked whenever a {@link Cursor} update occurs.
|
||||
* This will not work unless a Java thread has been dedicated to the event loop.
|
||||
* @see Extensions#drive(boolean)
|
||||
*/
|
||||
public void callback(Consumer<CursorController> cb) {
|
||||
callback(this.ptr, cb);
|
||||
}
|
||||
|
||||
private static native void clear_callback(long self);
|
||||
|
||||
/**
|
||||
* Clears the registered callback.
|
||||
* @see #callback(Consumer)
|
||||
*/
|
||||
public void clearCallback() {
|
||||
clear_callback(this.ptr);
|
||||
}
|
||||
|
||||
private static native void poll(long self);
|
||||
public void poll() {
|
||||
private static native void poll(long self) throws ControllerException;
|
||||
|
||||
/**
|
||||
* Blocks until a {@link Cursor} update is available.
|
||||
* @throws ControllerException if the controller was stopped
|
||||
*/
|
||||
public void poll() throws ControllerException {
|
||||
poll(this.ptr);
|
||||
}
|
||||
|
||||
private static native boolean stop(long self);
|
||||
|
||||
/**
|
||||
* Stops the controller. Any further calls to it will fail.
|
||||
* @return true if it was stopped successfully
|
||||
*/
|
||||
public boolean stop() {
|
||||
return stop(this.ptr);
|
||||
}
|
||||
|
|
57
dist/java/src/mp/code/Extensions.java
vendored
57
dist/java/src/mp/code/Extensions.java
vendored
|
@ -2,7 +2,41 @@ package mp.code;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
public class Extensions {
|
||||
/**
|
||||
* A class holding utility functions, as well as functions which are specific
|
||||
* to this language's glue and don't necessarily have a counterpart in the
|
||||
* broader CodeMP API.
|
||||
*/
|
||||
public final class Extensions {
|
||||
/**
|
||||
* Hashes the given {@link String} using CodeMP's hashing algorithm (xxh3).
|
||||
* @param input the string to hash
|
||||
* @return the hash
|
||||
*/
|
||||
public static native long hash(String input);
|
||||
|
||||
/**
|
||||
* Drive the underlying library's asynchronous event loop. In other words, tells
|
||||
* it what thread to use. You usually want to call this during initialisation.
|
||||
* <p>
|
||||
* Passing false will have the native library manage threads, but it may fail to
|
||||
* work with some more advanced features.
|
||||
* <p>
|
||||
* You may alternatively call this with true, in a separate and dedicated Java thread;
|
||||
* it will remain active in the background and act as event loop. Assign it like this:
|
||||
* <p><code>new Thread(() -> Extensions.drive(true)).start();</code></p>
|
||||
* @param block true if it should use the current thread
|
||||
*/
|
||||
public static native void drive(boolean block);
|
||||
|
||||
/**
|
||||
* Configures the tracing subscriber for the native logs.
|
||||
* Do not call this unless you want to see the native library's logs.
|
||||
* @param path where to output this, null to use stdout
|
||||
* @param debug whether to run it in debug mode
|
||||
*/
|
||||
public static native void setupTracing(String path, boolean debug);
|
||||
|
||||
private static boolean loaded = false;
|
||||
static synchronized void loadLibraryIfNotPresent() {
|
||||
if(loaded) return;
|
||||
|
@ -17,27 +51,6 @@ public class Extensions {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashes the given {@link String} using CodeMP's hashing algorithm (xxh3).
|
||||
* @param input the string to hash
|
||||
* @return the hash
|
||||
*/
|
||||
public static native long hash(String input);
|
||||
|
||||
/**
|
||||
* Drive the underlying library's asynchronous event loop.
|
||||
* @param block true if it should use the current thread, false if it should
|
||||
* spawn a separate one
|
||||
*/
|
||||
public static native void drive(boolean block);
|
||||
|
||||
/**
|
||||
* Configures the tracing subscriber for the native logs.
|
||||
* @param path where to output this, null to use stdout
|
||||
* @param debug whether to run it in debug mode
|
||||
*/
|
||||
public static native void setupTracing(String path, boolean debug);
|
||||
|
||||
static {
|
||||
Extensions.loadLibraryIfNotPresent();
|
||||
}
|
||||
|
|
126
dist/java/src/mp/code/Workspace.java
vendored
126
dist/java/src/mp/code/Workspace.java
vendored
|
@ -1,6 +1,5 @@
|
|||
package mp.code;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -9,7 +8,16 @@ import mp.code.exceptions.ConnectionException;
|
|||
import mp.code.exceptions.ConnectionRemoteException;
|
||||
import mp.code.exceptions.ControllerException;
|
||||
|
||||
public class Workspace {
|
||||
/**
|
||||
* Represents a CodeMP workspace, which broadly speaking is a collection
|
||||
* of buffers across which edits and cursor movements are tracked.
|
||||
* @apiNote Generally, it is safer to avoid storing this directly.
|
||||
* Instead, users should let the native library manage as
|
||||
* much as possible for them.
|
||||
* They should store the workspace ID and retrieve the object
|
||||
* whenever needed with {@link Client#getWorkspace(String)}.
|
||||
*/
|
||||
public final class Workspace {
|
||||
private final long ptr;
|
||||
|
||||
Workspace(long ptr) {
|
||||
|
@ -17,66 +25,147 @@ public class Workspace {
|
|||
}
|
||||
|
||||
private static native String get_workspace_id(long self);
|
||||
|
||||
/**
|
||||
* Gets the unique identifier of the current workspace.
|
||||
* @return the identifier
|
||||
*/
|
||||
public String getWorkspaceId() {
|
||||
return get_workspace_id(this.ptr);
|
||||
}
|
||||
|
||||
private static native CursorController get_cursor(long self);
|
||||
|
||||
/**
|
||||
* Gets the {@link CursorController} for the current workspace.
|
||||
* @return the {@link CursorController}
|
||||
*/
|
||||
public CursorController getCursor() {
|
||||
return get_cursor(this.ptr);
|
||||
}
|
||||
|
||||
private static native BufferController get_buffer(long self, String path);
|
||||
|
||||
/**
|
||||
* Looks for a {@link BufferController} with the given path within the
|
||||
* current workspace and returns it if it exists.
|
||||
* @param path the current path
|
||||
* @return the {@link BufferController} with the given path, if it exists
|
||||
*/
|
||||
public Optional<BufferController> getBuffer(String path) {
|
||||
return Optional.ofNullable(get_buffer(this.ptr, Objects.requireNonNull(path)));
|
||||
return Optional.ofNullable(get_buffer(this.ptr, path));
|
||||
}
|
||||
|
||||
private static native String[] get_file_tree(long self, String filter, boolean strict);
|
||||
|
||||
/**
|
||||
* Gets the file tree for this workspace, optionally filtering it.
|
||||
* @param filter applies an optional filter to the outputs
|
||||
* @param strict whether it should be a strict match (equals) or not (startsWith)
|
||||
* @return an array containing file tree as flat paths
|
||||
*/
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
public String[] getFileTree(Optional<String> filter, boolean strict) {
|
||||
return get_file_tree(this.ptr, filter.orElse(null), strict);
|
||||
}
|
||||
|
||||
private static native String[] active_buffers(long self);
|
||||
|
||||
/**
|
||||
* Returns the currently active buffers (the ones the user is currently
|
||||
* attached to).
|
||||
* @return an array containing the paths of the active buffers
|
||||
*/
|
||||
public String[] activeBuffers() {
|
||||
return active_buffers(this.ptr);
|
||||
}
|
||||
|
||||
private static native void create_buffer(long self, String path) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Creates a buffer with the given path.
|
||||
* @param path the new buffer's path
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public void createBuffer(String path) throws ConnectionRemoteException {
|
||||
create_buffer(this.ptr, Objects.requireNonNull(path));
|
||||
create_buffer(this.ptr, path);
|
||||
}
|
||||
|
||||
private static native BufferController attach_to_buffer(long self, String path) throws ConnectionException;
|
||||
|
||||
/**
|
||||
* Attaches to an existing buffer with the given path, if present.
|
||||
* @param path the path of the buffer to attach to
|
||||
* @return the {@link BufferController} associated with that path
|
||||
* @throws ConnectionException if an error occurs in communicating with the server, or if the buffer did not exist
|
||||
*/
|
||||
public BufferController attachToBuffer(String path) throws ConnectionException {
|
||||
return attach_to_buffer(ptr, Objects.requireNonNull(path));
|
||||
return attach_to_buffer(ptr, path);
|
||||
}
|
||||
|
||||
private static native DetachResult detach_from_buffer(long self, String path);
|
||||
|
||||
/**
|
||||
* Detaches from a given buffer.
|
||||
* @param path the path of the buffer to detach from
|
||||
* @return a {@link DetachResult} representing the outcome of the operation
|
||||
*/
|
||||
public DetachResult detachFromBuffer(String path) {
|
||||
return detach_from_buffer(this.ptr, Objects.requireNonNull(path));
|
||||
return detach_from_buffer(this.ptr, path);
|
||||
}
|
||||
|
||||
private static native void fetch_buffers(long self) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Updates the local list of buffers.
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public void fetchBuffers() throws ConnectionRemoteException {
|
||||
fetch_buffers(this.ptr);
|
||||
}
|
||||
|
||||
private static native void fetch_users(long self) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Updates the local list of users.
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public void fetchUsers() throws ConnectionRemoteException {
|
||||
fetch_buffers(this.ptr);
|
||||
}
|
||||
|
||||
private static native UUID[] list_buffer_users(long self, String path) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Lists the user attached to a certain buffer.
|
||||
* The user must be attached to the buffer to perform this operation.
|
||||
* @param path the path of the buffer to search
|
||||
* @return an array of user {@link UUID UUIDs}
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server, or the user wasn't attached
|
||||
*/
|
||||
public UUID[] listBufferUsers(String path) throws ConnectionRemoteException {
|
||||
return list_buffer_users(this.ptr, Objects.requireNonNull(path));
|
||||
return list_buffer_users(this.ptr, path);
|
||||
}
|
||||
|
||||
private static native void delete_buffer(long self, String path) throws ConnectionRemoteException;
|
||||
|
||||
/**
|
||||
* Deletes the buffer with the given path.
|
||||
* @param path the path of the buffer to delete
|
||||
* @throws ConnectionRemoteException if an error occurs in communicating with the server
|
||||
*/
|
||||
public void deleteBuffer(String path) throws ConnectionRemoteException {
|
||||
delete_buffer(this.ptr, Objects.requireNonNull(path));
|
||||
delete_buffer(this.ptr, path);
|
||||
}
|
||||
|
||||
private static native Event event(long self) throws ControllerException;
|
||||
|
||||
/**
|
||||
* Blocks until a workspace event occurs.
|
||||
* You shouldn't call this, unless it's on a dedicated thread.
|
||||
* @return the {@link Event} that has occurred
|
||||
* @throws ControllerException if the event arrived while the underlying controller was already closed
|
||||
*/
|
||||
public Event event() throws ControllerException {
|
||||
return event(this.ptr);
|
||||
}
|
||||
|
@ -90,8 +179,11 @@ public class Workspace {
|
|||
static {
|
||||
Extensions.loadLibraryIfNotPresent();
|
||||
}
|
||||
|
||||
public static class Event {
|
||||
|
||||
/**
|
||||
* Represents a workspace-wide event.
|
||||
*/
|
||||
public static final class Event {
|
||||
private final Type type;
|
||||
private final String argument;
|
||||
|
||||
|
@ -100,19 +192,31 @@ public class Workspace {
|
|||
this.argument = argument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user who joined, if any did.
|
||||
* @return the user who joined, if any did
|
||||
*/
|
||||
public Optional<String> getUserJoined() {
|
||||
if(this.type == Type.USER_JOIN) {
|
||||
return Optional.of(this.argument);
|
||||
} else return Optional.empty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the user who left, if any did.
|
||||
* @return the user who left, if any did
|
||||
*/
|
||||
public Optional<String> getUserLeft() {
|
||||
if(this.type == Type.USER_LEAVE) {
|
||||
return Optional.of(this.argument);
|
||||
} else return Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<String> getTargetBuffer() {
|
||||
/**
|
||||
* Gets the path of buffer that changed, if any did.
|
||||
* @return the path of buffer that changed, if any did
|
||||
*/
|
||||
public Optional<String> getChangedBuffer() {
|
||||
if(this.type == Type.FILE_TREE_UPDATED) {
|
||||
return Optional.of(this.argument);
|
||||
} else return Optional.empty();
|
||||
|
|
6
dist/java/src/mp/code/data/Callback.java
vendored
6
dist/java/src/mp/code/data/Callback.java
vendored
|
@ -1,6 +0,0 @@
|
|||
package mp.code.data;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface Callback<T> {
|
||||
void invoke(T controller);
|
||||
}
|
31
dist/java/src/mp/code/data/Config.java
vendored
31
dist/java/src/mp/code/data/Config.java
vendored
|
@ -8,17 +8,30 @@ import lombok.ToString;
|
|||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
|
||||
/**
|
||||
* A data class representing the connection configuration.
|
||||
*/
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
public class Config {
|
||||
private final String username;
|
||||
private final String password;
|
||||
private final Optional<String> host;
|
||||
private final OptionalInt port;
|
||||
private final Optional<Boolean> tls;
|
||||
/** The username to connect with. */
|
||||
public final String username;
|
||||
/** The password to connect with. */
|
||||
public final String password;
|
||||
/** The host to connect to, if custom. */
|
||||
public final Optional<String> host;
|
||||
/** The port to connect to, if custom. */
|
||||
public final OptionalInt port;
|
||||
/** Whether to use TLS, if custom. */
|
||||
public final Optional<Boolean> tls;
|
||||
|
||||
/**
|
||||
* Provides the given username and password on the default server.
|
||||
* @param username the username
|
||||
* @param password the password
|
||||
*/
|
||||
public Config(String username, String password) {
|
||||
this(
|
||||
username,
|
||||
|
@ -29,6 +42,14 @@ public class Config {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the given username and password as well as a custom server.
|
||||
* @param username the username
|
||||
* @param password the password
|
||||
* @param host the host server
|
||||
* @param port the port CodeMP is running on, must be between 0 and 65535
|
||||
* @param tls whether to use TLS
|
||||
*/
|
||||
public Config(String username, String password, String host, int port, boolean tls) {
|
||||
this(
|
||||
username,
|
||||
|
|
35
dist/java/src/mp/code/data/Cursor.java
vendored
35
dist/java/src/mp/code/data/Cursor.java
vendored
|
@ -4,11 +4,44 @@ import lombok.EqualsAndHashCode;
|
|||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* A data class holding information about a cursor event.
|
||||
*/
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@RequiredArgsConstructor
|
||||
public class Cursor {
|
||||
public final int startRow, startCol, endRow, endCol;
|
||||
/**
|
||||
* The starting row of the cursor position.
|
||||
* If negative, it is clamped to 0.
|
||||
*/
|
||||
public final int startRow;
|
||||
|
||||
/**
|
||||
* The starting column of the cursor position.
|
||||
* If negative, it is clamped to 0.
|
||||
*/
|
||||
public final int startCol;
|
||||
|
||||
/**
|
||||
* The ending row of the cursor position.
|
||||
* If negative, it is clamped to 0.
|
||||
*/
|
||||
public final int endRow;
|
||||
|
||||
/**
|
||||
* The ending column of the cursor position.
|
||||
* If negative, it is clamped to 0.
|
||||
*/
|
||||
public final int endCol;
|
||||
|
||||
/**
|
||||
* The buffer the cursor is located on.
|
||||
*/
|
||||
public final String buffer;
|
||||
|
||||
/**
|
||||
* The user who controls the cursor.
|
||||
*/
|
||||
public final String user;
|
||||
}
|
||||
|
|
8
dist/java/src/mp/code/data/DetachResult.java
vendored
8
dist/java/src/mp/code/data/DetachResult.java
vendored
|
@ -1,7 +1,15 @@
|
|||
package mp.code.data;
|
||||
|
||||
import mp.code.Workspace;
|
||||
|
||||
/**
|
||||
* The result of a {@link Workspace#detachFromBuffer(String)} operation.
|
||||
*/
|
||||
public enum DetachResult {
|
||||
/** The user was not attached to this buffer. */
|
||||
NOT_ATTACHED,
|
||||
/** The user detached from the buffer and stopped it. */
|
||||
DETACHING,
|
||||
/** The user was attached, but the buffer was already stopped. */
|
||||
ALREADY_DETACHED
|
||||
}
|
||||
|
|
60
dist/java/src/mp/code/data/TextChange.java
vendored
60
dist/java/src/mp/code/data/TextChange.java
vendored
|
@ -3,30 +3,86 @@ package mp.code.data;
|
|||
import lombok.EqualsAndHashCode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import mp.code.Extensions;
|
||||
|
||||
import java.util.OptionalLong;
|
||||
|
||||
/**
|
||||
* A data class holding information about a text change.
|
||||
*/
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@RequiredArgsConstructor
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
public class TextChange {
|
||||
/**
|
||||
* The starting position of the change.
|
||||
* If negative, it is clamped to 0.
|
||||
*/
|
||||
public final int start;
|
||||
|
||||
/**
|
||||
* The endomg position of the change.
|
||||
* If negative, it is clamped to 0.
|
||||
*/
|
||||
public final int end;
|
||||
|
||||
/**
|
||||
* The content of the change.
|
||||
* It should never be null; if you need to represent absence of content, use an empty string.
|
||||
*/
|
||||
public final String content;
|
||||
|
||||
/**
|
||||
* The hash of the content after applying it (calculated with {@link Extensions#hash(String)}).
|
||||
* It is generally meaningless to send, but when received it is an invitation to check the hash
|
||||
* and forcefully re-sync if necessary.
|
||||
*/
|
||||
public final OptionalLong hash; // xxh3 hash
|
||||
|
||||
/**
|
||||
* Checks if the change represents a deletion.
|
||||
* It does if the starting index is lower than the ending index.
|
||||
* It is NOT mutually exclusive with {@link #isInsert()}.
|
||||
* @return true if this change represents a deletion
|
||||
*/
|
||||
public boolean isDelete() {
|
||||
return this.start != this.end;
|
||||
return this.start < this.end;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the change represents an insertion.
|
||||
* It does if the content is not empty
|
||||
* It is NOT mutually exclusive with {@link #isDelete()}.
|
||||
* @return true if this change represents an insertion
|
||||
*/
|
||||
public boolean isInsert() {
|
||||
return !this.content.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether this change is a no-op.
|
||||
* @return true if this change is a no-op
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return !this.isDelete() && !this.isInsert();
|
||||
}
|
||||
|
||||
//TODO: apply()
|
||||
/**
|
||||
* Applies the change to an input string and returns the result.
|
||||
* @param input the input string
|
||||
* @return the mutated string
|
||||
*/
|
||||
public String apply(String input) {
|
||||
int preIndex = Math.min(this.start, input.length());
|
||||
String pre = "";
|
||||
try {
|
||||
pre = input.substring(0, preIndex);
|
||||
} catch(IndexOutOfBoundsException ignored) {}
|
||||
String post = "";
|
||||
try {
|
||||
post = input.substring(this.end);
|
||||
} catch(IndexOutOfBoundsException ignored) {}
|
||||
return pre + this.content + post;
|
||||
}
|
||||
}
|
||||
|
|
10
dist/java/src/mp/code/data/User.java
vendored
10
dist/java/src/mp/code/data/User.java
vendored
|
@ -6,10 +6,20 @@ import lombok.ToString;
|
|||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A data class holding information about a user.
|
||||
*/
|
||||
@ToString
|
||||
@EqualsAndHashCode
|
||||
@RequiredArgsConstructor
|
||||
public class User {
|
||||
/**
|
||||
* The {@link UUID} of the user.
|
||||
*/
|
||||
public final UUID id;
|
||||
|
||||
/**
|
||||
* The human-readable name of the user.
|
||||
*/
|
||||
public final String name;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,12 @@ package mp.code.exceptions;
|
|||
* An exception that may occur when processing network requests.
|
||||
*/
|
||||
public abstract class ConnectionException extends Exception {
|
||||
protected ConnectionException(String msg) {
|
||||
super(msg);
|
||||
|
||||
/**
|
||||
* Creates a new exception with the given message.
|
||||
* @param message the message
|
||||
*/
|
||||
protected ConnectionException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,12 @@ package mp.code.exceptions;
|
|||
* An exception returned by the server as a response.
|
||||
*/
|
||||
public abstract class ConnectionRemoteException extends ConnectionException {
|
||||
protected ConnectionRemoteException(String msg) {
|
||||
super(msg);
|
||||
|
||||
/**
|
||||
* Creates a new exception with the given message.
|
||||
* @param message the message
|
||||
*/
|
||||
public ConnectionRemoteException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,12 @@ package mp.code.exceptions;
|
|||
* An exception that occurred from the underlying tonic layer.
|
||||
*/
|
||||
public abstract class ConnectionTransportException extends Exception {
|
||||
protected ConnectionTransportException(String msg) {
|
||||
super(msg);
|
||||
|
||||
/**
|
||||
* Creates a new exception with the given message.
|
||||
* @param message the message
|
||||
*/
|
||||
public ConnectionTransportException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,11 +3,15 @@ package mp.code.exceptions;
|
|||
/**
|
||||
* An exception that may occur when a {@link mp.code.BufferController} or
|
||||
* a {@link mp.code.CursorController} perform an illegal operation.
|
||||
* It may also occur as a result of {@link mp.code.Workspace#event()} and
|
||||
* {@link mp.code.Workspace#selectBuffer(long)}.
|
||||
* It may also occur as a result of {@link mp.code.Workspace#event()}.
|
||||
*/
|
||||
public abstract class ControllerException extends Exception {
|
||||
protected ControllerException(String msg) {
|
||||
super(msg);
|
||||
|
||||
/**
|
||||
* Creates a new exception with the given message.
|
||||
* @param message the message
|
||||
*/
|
||||
protected ControllerException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,12 @@ package mp.code.exceptions;
|
|||
* the worker has already stopped.
|
||||
*/
|
||||
public class ControllerStoppedException extends ControllerException {
|
||||
protected ControllerStoppedException(String msg) {
|
||||
super(msg);
|
||||
|
||||
/**
|
||||
* Creates a new exception with the given message.
|
||||
* @param message the message
|
||||
*/
|
||||
public ControllerStoppedException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,12 @@ package mp.code.exceptions;
|
|||
* fulfilling the request, without rejecting it first.
|
||||
*/
|
||||
public class ControllerUnfulfilledException extends ControllerException {
|
||||
protected ControllerUnfulfilledException(String msg) {
|
||||
super(msg);
|
||||
|
||||
/**
|
||||
* Creates a new exception with the given message.
|
||||
* @param message the message
|
||||
*/
|
||||
public ControllerUnfulfilledException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,11 @@ package mp.code.exceptions;
|
|||
* Only catch this if you are aware of the implications.
|
||||
*/
|
||||
public class JNIException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Creates a new exception with the given message.
|
||||
* @param message the message
|
||||
*/
|
||||
public JNIException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
|
|
@ -103,11 +103,10 @@ pub extern "system" fn Java_mp_code_BufferController_callback<'local>(
|
|||
if let Err(e) = env.with_local_frame(5, |env| {
|
||||
use crate::ffi::java::JObjectify;
|
||||
let jcontroller = controller.jobjectify(env)?;
|
||||
let sig = format!("(L{};)V", "java/lang/Object");
|
||||
if let Err(e) = env.call_method(
|
||||
&cb_ref,
|
||||
"invoke",
|
||||
&sig,
|
||||
"accept",
|
||||
"(Ljava/lang/Object;)V",
|
||||
&[jni::objects::JValueGen::Object(&jcontroller)]
|
||||
) {
|
||||
tracing::error!("error invoking callback: {e:?}");
|
||||
|
|
|
@ -74,11 +74,10 @@ pub extern "system" fn Java_mp_code_CursorController_callback<'local>(
|
|||
if let Err(e) = env.with_local_frame(5, |env| {
|
||||
use crate::ffi::java::JObjectify;
|
||||
let jcontroller = controller.jobjectify(env)?;
|
||||
let sig = format!("(L{};)V", "java/lang/Object");
|
||||
if let Err(e) = env.call_method(
|
||||
&cb_ref,
|
||||
"invoke",
|
||||
&sig,
|
||||
"accept",
|
||||
"(Ljava/lang/Object;)V",
|
||||
&[jni::objects::JValueGen::Object(&jcontroller)]
|
||||
) {
|
||||
tracing::error!("error invoking callback: {e:?}");
|
||||
|
|
Loading…
Reference in a new issue