diff --git a/src/main/java/com/codemp/intellij/actions/buffer/BufferAttachAction.java b/src/main/java/com/codemp/intellij/actions/buffer/BufferAttachAction.java index 3912a0e..aba5052 100644 --- a/src/main/java/com/codemp/intellij/actions/buffer/BufferAttachAction.java +++ b/src/main/java/com/codemp/intellij/actions/buffer/BufferAttachAction.java @@ -15,8 +15,7 @@ public class BufferAttachAction extends AnAction { public static void attach(AnActionEvent e, String buffer, boolean silent) { BufferHandler bufferHandler = CodeMPHandler.attach(buffer); if(!silent) ActionUtil.notify(e, "Success", - String.format("Successfully attached to buffer to buffer to %s!", buffer) - ); + String.format("Successfully attached to buffer to buffer to %s!", buffer)); CodeMP.LOGGER.debug("Attached to buffer to {}!", buffer); //TODO "get" the Editor corresponding to buffer, for now use the current one diff --git a/src/main/java/com/codemp/intellij/task/BufferEventAwaiterTask.java b/src/main/java/com/codemp/intellij/task/BufferEventAwaiterTask.java index d602b8f..0dc69a3 100644 --- a/src/main/java/com/codemp/intellij/task/BufferEventAwaiterTask.java +++ b/src/main/java/com/codemp/intellij/task/BufferEventAwaiterTask.java @@ -5,6 +5,7 @@ import com.codemp.intellij.exceptions.lib.ChannelException; import com.codemp.intellij.exceptions.lib.DeadlockedException; import com.codemp.intellij.jni.BufferHandler; import com.codemp.intellij.jni.CodeMPHandler; +import com.codemp.intellij.jni.StringVec; import com.codemp.intellij.jni.TextChangeWrapper; import com.codemp.intellij.listeners.BufferEventListener; import com.intellij.openapi.Disposable; @@ -22,6 +23,7 @@ import java.util.concurrent.ConcurrentHashMap; public class BufferEventAwaiterTask extends Task.Backgroundable implements Disposable { private final Map bufferListeners = new ConcurrentHashMap<>(); + private final Set initialisedBuffers = Collections.newSetFromMap(new ConcurrentHashMap<>()); //also tonioware public BufferEventAwaiterTask(@NotNull Project project) { super(project, "Awaiting CodeMP buffer events", false); @@ -41,6 +43,8 @@ public class BufferEventAwaiterTask extends Task.Backgroundable implements Dispo } public void unregisterListener(String name) { + CodeMP.ACTIVE_BUFFERS_REVERSE.remove(CodeMP.ACTIVE_BUFFERS.remove(name)); + this.initialisedBuffers.remove(name); Disposable listener = this.bufferListeners.remove(name); if(listener != null) listener.dispose(); @@ -50,17 +54,25 @@ public class BufferEventAwaiterTask extends Task.Backgroundable implements Dispo public void dispose() {} @Override - @SuppressWarnings({"InfiniteLoopStatement", "UnstableApiUsage"}) + @SuppressWarnings({"InfiniteLoopStatement", "UnstableApiUsage", "BusyWait"}) public void run(@NotNull ProgressIndicator indicator) { - try { - Thread.sleep(100); //tonioware - } catch(InterruptedException ex) { - throw new RuntimeException(ex); - } - try { while(true) { - String buffer = CodeMPHandler.selectBuffer(); + StringVec buffers = new StringVec(); //jni moment + CodeMP.ACTIVE_BUFFERS.keySet().forEach(buffers::push); + + Optional bufferOptional = CodeMPHandler.selectBuffer(buffers, 100L); + if(bufferOptional.isEmpty()) + continue; + String buffer = bufferOptional.get(); + + if(!this.initialisedBuffers.contains(buffer)) { //tonioware + try { + Thread.sleep(100); + } catch(InterruptedException ignored) {} + this.initialisedBuffers.add(buffer); + } + BufferHandler handler = CodeMPHandler.getBuffer(buffer); List changeList = new ArrayList<>(); @@ -81,7 +93,6 @@ public class BufferEventAwaiterTask extends Task.Backgroundable implements Dispo } Editor bufferEditor = CodeMP.ACTIVE_BUFFERS.get(buffer); - ApplicationManager.getApplication().invokeLaterOnWriteThread(() -> ApplicationManager.getApplication().runWriteAction(() -> CommandProcessor.getInstance().executeCommand( diff --git a/src/main/java/com/codemp/intellij/task/CursorEventAwaiterTask.java b/src/main/java/com/codemp/intellij/task/CursorEventAwaiterTask.java index 038d1fe..de6cd3d 100644 --- a/src/main/java/com/codemp/intellij/task/CursorEventAwaiterTask.java +++ b/src/main/java/com/codemp/intellij/task/CursorEventAwaiterTask.java @@ -69,11 +69,7 @@ public class CursorEventAwaiterTask extends Task.Backgroundable implements Dispo return; } - RangeHighlighter highlighter = this.highlighterMap.get(event.getUser()); - if(highlighter != null) - highlighter.dispose(); - - this.highlighterMap.put(event.getUser(), editor + RangeHighlighter previous = this.highlighterMap.put(event.getUser(), editor .getMarkupModel() .addRangeHighlighter( startOffset, @@ -87,6 +83,9 @@ public class CursorEventAwaiterTask extends Task.Backgroundable implements Dispo Font.PLAIN ), HighlighterTargetArea.EXACT_RANGE )); + + if(previous != null) + previous.dispose(); }); } catch(IndexOutOfBoundsException ignored) {} } diff --git a/src/main/rust/glue.in b/src/main/rust/glue.in index 42997f6..a569139 100644 --- a/src/main/rust/glue.in +++ b/src/main/rust/glue.in @@ -35,6 +35,5 @@ foreign_typemap!( //thanks @tasn on GitHub for the idea } }; }; - ($p:f_type, unique_prefix="/*codemp::prelude::CodempResult*/") => "/*codemp::prelude::CodempResult*/swig_f_type!(T)" - "swig_foreign_from_i_type!(T, $p)"; -); + ($p:f_type, unique_prefix="/*err*/") => "/*err*/swig_f_type!(T)" "swig_foreign_from_i_type!(T, $p)"; +); \ No newline at end of file diff --git a/src/main/rust/lib.rs b/src/main/rust/lib.rs index 97d49f7..59a9034 100644 --- a/src/main/rust/lib.rs +++ b/src/main/rust/lib.rs @@ -1,5 +1,7 @@ use std::sync::Arc; +use std::time::Duration; use codemp::prelude::*; +use codemp::tools; use rifgen::rifgen_attr::{generate_access_methods, generate_interface, generate_interface_doc}; pub mod glue { //rifgen generated code @@ -66,8 +68,16 @@ impl CodeMPHandler { } #[generate_interface] - fn select_buffer() -> CodempResult { - CODEMP_INSTANCE.select_buffer() + fn select_buffer(mut buffer_ids: StringVec, timeout: i64) -> CodempResult> { + let mut buffers = Vec::new(); + for id in buffer_ids.v.iter_mut() { + match CODEMP_INSTANCE.get_buffer(id.as_str()) { + Ok(buf) => buffers.push(buf), + Err(_) => continue + } + } + CODEMP_INSTANCE.rt().block_on( + tools::select_buffer_timeout(&buffers, Duration::from_millis(timeout as u64))) } } @@ -92,7 +102,7 @@ struct CursorHandler { impl CursorHandler { #[generate_interface(constructor)] fn new() -> CursorHandler { - panic!("Default constructor for CursorHandler should never be called!") + unimplemented!() } #[generate_interface] @@ -137,7 +147,7 @@ struct BufferHandler { impl BufferHandler { #[generate_interface(constructor)] fn new() -> BufferHandler { - panic!("Default constructor for BufferHandler should never be called!") + unimplemented!() } #[generate_interface] @@ -145,6 +155,11 @@ impl BufferHandler { self.buffer.name.clone() } + #[generate_interface] + fn get_content(&self) -> String { + self.buffer.content() + } + #[generate_interface] fn try_recv(&self) -> CodempResult> { match self.buffer.try_recv() { @@ -175,3 +190,20 @@ impl BufferHandler { self.buffer.send(CodempTextChange { span: start_offset..end_offset, content }) } } + +#[generate_interface_doc] +struct StringVec { //jni moment + v: Vec +} + +impl StringVec { + #[generate_interface(constructor)] + fn new() -> StringVec { + Self { v: Vec::new() } + } + + #[generate_interface] + fn push(&mut self, s: String) { + self.v.push(s); + } +} \ No newline at end of file