mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-14 16:26:07 +01:00
We do a little thieving
- Reimplement stealInstance.
This commit is contained in:
parent
8221616eff
commit
c8590629a1
3 changed files with 55 additions and 4 deletions
|
@ -24,6 +24,19 @@ public interface Instancer<I extends Instance> {
|
|||
*/
|
||||
I createInstance();
|
||||
|
||||
/**
|
||||
* Steal an instance from another instancer.
|
||||
* <br>
|
||||
* This has the effect of swapping the instance's model in-place.
|
||||
* <br><br>
|
||||
* If the given instance is already owned by this instancer, this method does nothing.
|
||||
* <br>
|
||||
* If the given instance was created by a different backend, the behavior of this method is undefined.
|
||||
*
|
||||
* @param instance The instance to steal.
|
||||
*/
|
||||
void stealInstance(I instance);
|
||||
|
||||
/**
|
||||
* Populate arr with new instances of this model.
|
||||
*
|
||||
|
|
|
@ -29,13 +29,51 @@ public abstract class AbstractInstancer<I extends Instance> implements Instancer
|
|||
var handle = new InstanceHandleImpl(this, i);
|
||||
I instance = type.create(handle);
|
||||
|
||||
instances.add(instance);
|
||||
handles.add(handle);
|
||||
changed.set(i);
|
||||
addLocked(instance, handle);
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stealInstance(I instance) {
|
||||
var instanceHandle = instance.handle();
|
||||
|
||||
if (!(instanceHandle instanceof InstanceHandleImpl handle)) {
|
||||
// UB: do nothing
|
||||
return;
|
||||
}
|
||||
|
||||
if (handle.instancer == this) {
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME: in theory there could be a race condition here if the instance
|
||||
// is somehow being stolen by 2 different instancers between threads.
|
||||
// That seems kinda impossible so I'm fine leaving it as is for now.
|
||||
|
||||
// Remove the instance from its old instancer.
|
||||
// This won't have any unwanted effect when the old instancer
|
||||
// is filtering deleted instances later, so is safe.
|
||||
handle.setDeleted();
|
||||
|
||||
// Only lock now that we'll be mutating our state.
|
||||
synchronized (lock) {
|
||||
// Add the instance to this instancer.
|
||||
handle.instancer = this;
|
||||
handle.index = instances.size();
|
||||
addLocked(instance, handle);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls must be synchronized on {@link #lock}.
|
||||
*/
|
||||
private void addLocked(I instance, InstanceHandleImpl handle) {
|
||||
instances.add(instance);
|
||||
handles.add(handle);
|
||||
changed.set(handle.index);
|
||||
}
|
||||
|
||||
public int getInstanceCount() {
|
||||
return instances.size();
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.jozufozu.flywheel.backend.engine;
|
|||
import com.jozufozu.flywheel.api.instance.InstanceHandle;
|
||||
|
||||
public class InstanceHandleImpl implements InstanceHandle {
|
||||
public final AbstractInstancer<?> instancer;
|
||||
public AbstractInstancer<?> instancer;
|
||||
public int index;
|
||||
|
||||
public InstanceHandleImpl(AbstractInstancer<?> instancer, int index) {
|
||||
|
|
Loading…
Reference in a new issue