1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-10-22 09:27:39 +00:00

Compare commits

..

3 Commits

Author SHA1 Message Date
SquidDev
92567b4d7e Merge branch 'master' into mc-1.14.x 2019-11-29 20:23:56 +00:00
SquidDev
0ae70fed13 Correctly implement mouse movement within read
Note to self: if you're going to modify the rom, make sure you test on a
computer which doesn't overwrite the rom with something else.
2019-11-29 20:15:58 +00:00
SquidDev
3b7300543a Correctly invalidate the ROM mount cache
Before it would remain the same across world reloads, and thus would be
out-of-date after leaving the first world. This architecture technically
allows for running multiple servers at once, though that's not going to
matter that soon.
2019-11-26 18:16:49 +00:00
9 changed files with 88 additions and 52 deletions

View File

@@ -1,5 +1,5 @@
# Mod properties
mod_version=1.85.1
mod_version=1.85.2
# Minecraft properties (update mods.toml when changing)
mc_version=1.14.4

View File

@@ -6,11 +6,9 @@
package dan200.computercraft;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.turtle.event.TurtleAction;
import dan200.computercraft.core.apis.AddressPredicate;
import dan200.computercraft.core.apis.http.websocket.Websocket;
import dan200.computercraft.core.filesystem.ResourceMount;
import dan200.computercraft.shared.Config;
import dan200.computercraft.shared.computer.blocks.BlockComputer;
import dan200.computercraft.shared.computer.core.ClientComputerRegistry;
@@ -194,13 +192,6 @@ public final class ComputerCraft
return "${version}";
}
static IMount createResourceMount( String domain, String subPath )
{
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
ResourceMount mount = new ResourceMount( domain, subPath, manager );
return mount.exists( "" ) ? mount : null;
}
public static InputStream getResourceFile( String domain, String subPath )
{
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();

View File

@@ -6,6 +6,7 @@
package dan200.computercraft;
import com.google.common.collect.MapMaker;
import dan200.computercraft.api.ComputerCraftAPI.IComputerCraftAPI;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.api.filesystem.IWritableMount;
@@ -20,20 +21,26 @@ import dan200.computercraft.api.redstone.IBundledRedstoneProvider;
import dan200.computercraft.api.turtle.ITurtleUpgrade;
import dan200.computercraft.core.apis.ApiFactories;
import dan200.computercraft.core.filesystem.FileMount;
import dan200.computercraft.core.filesystem.ResourceMount;
import dan200.computercraft.shared.*;
import dan200.computercraft.shared.peripheral.modem.wireless.WirelessNetwork;
import dan200.computercraft.shared.util.IDAssigner;
import dan200.computercraft.shared.wired.CapabilityWiredElement;
import dan200.computercraft.shared.wired.WiredNode;
import net.minecraft.resources.IReloadableResourceManager;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.Direction;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.IBlockReader;
import net.minecraft.world.World;
import net.minecraftforge.common.util.LazyOptional;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import javax.annotation.Nonnull;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.Map;
public final class ComputerCraftAPIImpl implements IComputerCraftAPI
{
@@ -43,6 +50,9 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
{
}
private WeakReference<IReloadableResourceManager> currentResources;
private final Map<ResourceLocation, ResourceMount> mountCache = new MapMaker().weakValues().concurrencyLevel( 1 ).makeMap();
@Nonnull
@Override
public String getInstalledVersion()
@@ -72,7 +82,9 @@ public final class ComputerCraftAPIImpl implements IComputerCraftAPI
@Override
public IMount createResourceMount( @Nonnull String domain, @Nonnull String subPath )
{
return ComputerCraft.createResourceMount( domain, subPath );
IReloadableResourceManager manager = ServerLifecycleHooks.getCurrentServer().getResourceManager();
ResourceMount mount = ResourceMount.get( domain, subPath, manager );
return mount.exists( "" ) ? mount : null;
}
@Override

View File

@@ -56,9 +56,6 @@ final class ComputerExecutor
{
private static final int QUEUE_LIMIT = 256;
private static IMount romMount;
private static final Object romMountLock = new Object();
private final Computer computer;
private final List<ILuaAPI> apis = new ArrayList<>();
final TimeoutState timeout = new TimeoutState();
@@ -329,16 +326,10 @@ final class ComputerExecutor
private IMount getRomMount()
{
if( romMount != null ) return romMount;
synchronized( romMountLock )
{
if( romMount != null ) return romMount;
return romMount = computer.getComputerEnvironment().createResourceMount( "computercraft", "lua/rom" );
}
return computer.getComputerEnvironment().createResourceMount( "computercraft", "lua/rom" );
}
IWritableMount getRootMount()
private IWritableMount getRootMount()
{
if( rootMount == null )
{

View File

@@ -8,13 +8,16 @@ package dan200.computercraft.core.filesystem;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.MapMaker;
import com.google.common.io.ByteStreams;
import dan200.computercraft.ComputerCraft;
import dan200.computercraft.api.filesystem.IMount;
import dan200.computercraft.core.apis.handles.ArrayByteChannel;
import net.minecraft.resources.IReloadableResourceManager;
import net.minecraft.resources.IResource;
import net.minecraft.resources.IResourceManager;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.ResourceLocationException;
import net.minecraftforge.resource.IResourceType;
import net.minecraftforge.resource.ISelectiveResourceReloadListener;
@@ -29,7 +32,7 @@ import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
public class ResourceMount implements IMount
public final class ResourceMount implements IMount
{
/**
* Only cache files smaller than 1MiB.
@@ -55,6 +58,13 @@ public class ResourceMount implements IMount
.<FileEntry, byte[]>weigher( ( k, v ) -> v.length )
.build();
private static final MapMaker CACHE_TEMPLATE = new MapMaker().weakValues().concurrencyLevel( 1 );
/**
* Maintain a cache of currently loaded resource mounts. This cache is invalidated when currentManager changes.
*/
private static final Map<IReloadableResourceManager, Map<ResourceLocation, ResourceMount>> MOUNT_CACHE = new WeakHashMap<>( 2 );
private final String namespace;
private final String subPath;
private final IReloadableResourceManager manager;
@@ -62,7 +72,26 @@ public class ResourceMount implements IMount
@Nullable
private FileEntry root;
public ResourceMount( String namespace, String subPath, IReloadableResourceManager manager )
public static ResourceMount get( String namespace, String subPath, IReloadableResourceManager manager )
{
Map<ResourceLocation, ResourceMount> cache;
synchronized( MOUNT_CACHE )
{
cache = MOUNT_CACHE.get( manager );
if( cache == null ) MOUNT_CACHE.put( manager, cache = CACHE_TEMPLATE.makeMap() );
}
ResourceLocation path = new ResourceLocation( namespace, subPath );
synchronized( cache )
{
ResourceMount mount = cache.get( path );
if( mount == null ) cache.put( path, mount = new ResourceMount( namespace, subPath, manager ) );
return mount;
}
}
private ResourceMount( String namespace, String subPath, IReloadableResourceManager manager )
{
this.namespace = namespace;
this.subPath = subPath;
@@ -119,7 +148,17 @@ public class ResourceMount implements IMount
FileEntry nextEntry = lastEntry.children.get( part );
if( nextEntry == null )
{
lastEntry.children.put( part, nextEntry = new FileEntry( new ResourceLocation( namespace, subPath + "/" + path ) ) );
ResourceLocation childPath;
try
{
childPath = new ResourceLocation( namespace, subPath + "/" + path );
}
catch( ResourceLocationException e )
{
ComputerCraft.log.warn( "Cannot create resource location for {} ({})", part, e.getMessage() );
return;
}
lastEntry.children.put( part, nextEntry = new FileEntry( childPath ) );
}
lastEntry = nextEntry;

View File

@@ -291,7 +291,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
sLine = ""
end
local nHistoryPos
local nPos = #sLine
local nPos, nScroll = #sLine, 0
if _sReplaceChar then
_sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
end
@@ -321,16 +321,20 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
local sx = term.getCursorPos()
local function redraw( _bClear )
local nScroll = 0
if sx + nPos >= w then
nScroll = (sx + nPos) - w
local cursor_pos = nPos - nScroll
if sx + cursor_pos >= w then
-- We've moved beyond the RHS, ensure we're on the edge.
nScroll = sx + nPos - w
elseif cursor_pos < 0 then
-- We've moved beyond the LHS, ensure we're on the edge.
nScroll = nPos
end
local _, cy = term.getCursorPos()
term.setCursorPos( sx, cy )
local sReplace = (_bClear and " ") or _sReplaceChar
if sReplace then
term.write( string.rep( sReplace, math.max( string.len(sLine) - nScroll, 0 ) ) )
term.write( string.rep( sReplace, math.max( #sLine - nScroll, 0 ) ) )
else
term.write( string.sub( sLine, nScroll + 1 ) )
end
@@ -345,7 +349,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
term.setBackgroundColor( colors.gray )
end
if sReplace then
term.write( string.rep( sReplace, string.len( sCompletion ) ) )
term.write( string.rep( sReplace, #sCompletion ) )
else
term.write( sCompletion )
end
@@ -373,7 +377,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
-- Find the common prefix of all the other suggestions which start with the same letter as the current one
local sCompletion = tCompletions[ nCompletion ]
sLine = sLine .. sCompletion
nPos = string.len( sLine )
nPos = #sLine
-- Redraw
recomplete()
@@ -381,7 +385,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
end
end
while true do
local sEvent, param = os.pullEvent()
local sEvent, param, param1, param2 = os.pullEvent()
if sEvent == "char" then
-- Typed key
clear()
@@ -394,7 +398,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
-- Pasted text
clear()
sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
nPos = nPos + string.len( param )
nPos = nPos + #param
recomplete()
redraw()
@@ -419,7 +423,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
elseif param == keys.right then
-- Right
if nPos < string.len(sLine) then
if nPos < #sLine then
-- Move right
clear()
nPos = nPos + 1
@@ -470,10 +474,10 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
end
if nHistoryPos then
sLine = _tHistory[nHistoryPos]
nPos = string.len( sLine )
nPos, nScroll = #sLine, 0
else
sLine = ""
nPos = 0
nPos, nScroll = 0, 0
end
uncomplete()
redraw()
@@ -486,6 +490,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
clear()
sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
nPos = nPos - 1
if nScroll > 0 then nScroll = nScroll - 1 end
recomplete()
redraw()
end
@@ -501,7 +506,7 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
elseif param == keys.delete then
-- Delete
if nPos < string.len(sLine) then
if nPos < #sLine then
clear()
sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )
recomplete()
@@ -510,9 +515,9 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
elseif param == keys["end"] then
-- End
if nPos < string.len(sLine ) then
if nPos < #sLine then
clear()
nPos = string.len(sLine)
nPos = #sLine
recomplete()
redraw()
end
@@ -525,9 +530,9 @@ function read( _sReplaceChar, _tHistory, _fnComplete, _sDefault )
elseif sEvent == "mouse_click" or sEvent == "mouse_drag" and param == 1 then
local _, cy = term.getCursorPos()
if param2 >= sx and param2 <= w and param2 == cy then
-- Then ensure we don't scroll beyond the current line
nPos = math.min(math.max(nScroll + x - sx, 0), #sLine)
if param1 >= sx and param1 <= w and param2 == cy then
-- Ensure we don't scroll beyond the current line
nPos = math.min(math.max(nScroll + param1 - sx, 0), #sLine)
redraw()
end

View File

@@ -1,3 +1,7 @@
# New features in CC: Tweaked 1.85.2
* Fix crashes when using the mouse with advanced computers.
# New features in CC: Tweaked 1.85.1
* Add basic mouse support to `read`

View File

@@ -1,11 +1,5 @@
New features in CC: Tweaked 1.85.1
New features in CC: Tweaked 1.85.2
* Add basic mouse support to `read`
And several bug fixes:
* Fix turtles not having breaking particles.
* Correct rendering of monitors when underwater.
* Adjust the position from where turtle performs actions, correcting the behaviour of some interactions.
* Fix several crashes when the turtle performs some action.
* Fix crashes when using the mouse with advanced computers.
Type "help changelog" to see the full version history.

View File

@@ -31,7 +31,7 @@ public class ResourceMountTest
SimpleReloadableResourceManager manager = new SimpleReloadableResourceManager( ResourcePackType.SERVER_DATA, null );
manager.addResourcePack( new FolderPack( new File( "src/main/resources" ) ) );
mount = new ResourceMount( "computercraft", "lua/rom", manager );
mount = ResourceMount.get( "computercraft", "lua/rom", manager );
}
@Test