anonl / nvlist
Showing 14 of 55 files from the diff.
Other files ignored by Codecov
api/build.gradle has changed.

@@ -69,7 +69,7 @@
Loading
69 69
70 70
        // Load main script and call main function
71 71
        try {
72 -
            LuaScriptUtil.loadScript(mainContext, getScriptEnv().getScriptLoader(), FilePath.of("main"));
72 +
            LuaScriptUtil.loadScript(mainContext, FilePath.of("main"));
73 73
            LuaScriptUtil.callFunction(mainContext, mainFunctionName);
74 74
        } catch (Exception e) {
75 75
            LOG.warn("Error executing main function: \"{}\"", mainFunctionName, e);

@@ -123,7 +123,8 @@
Loading
123 123
            if (stepMode != null) {
124 124
                switch (stepMode) {
125 125
                case IN:
126 -
                    if (event == LuaDebugEvent.CALL) {
126 +
                    if (event == LuaDebugEvent.CALL || event == LuaDebugEvent.LINE || event == LuaDebugEvent.RETURN
127 +
                            || event == LuaDebugEvent.TAIL_RETURN) {
127 128
                        stepHit();
128 129
                    }
129 130
                    break;
@@ -137,7 +138,7 @@
Loading
137 138
                    // Ignore line events in nested function calls
138 139
                    if (event == LuaDebugEvent.CALL) {
139 140
                        depth++;
140 -
                    } else if (event == LuaDebugEvent.RETURN) {
141 +
                    } else if (event == LuaDebugEvent.RETURN || event == LuaDebugEvent.TAIL_RETURN) {
141 142
                        depth--;
142 143
                    }
143 144

@@ -274,9 +274,6 @@
Loading
274 274
        IImageModule imageModule = env.getImageModule();
275 275
276 276
        ITexture tex = imageModule.getColorTexture(argb);
277 -
        if (tex == null) {
278 -
            return LuaNil.NIL;
279 -
        }
280 277
        return LuajavaLib.toUserdata(tex, ITexture.class);
281 278
    }
282 279

@@ -26,7 +26,6 @@
Loading
26 26
import nl.weeaboo.vn.scene.IScreen;
27 27
import nl.weeaboo.vn.script.IScriptContext;
28 28
import nl.weeaboo.vn.script.IScriptFunction;
29 -
import nl.weeaboo.vn.script.IScriptLoader;
30 29
import nl.weeaboo.vn.script.IScriptThread;
31 30
import nl.weeaboo.vn.script.ScriptException;
32 31
@@ -92,19 +91,23 @@
Loading
92 91
     */
93 92
    public static ResourceLoadInfo createLoadInfo(MediaType mediaType, FilePath filename) {
94 93
        List<String> callStack = ImmutableList.of();
95 -
        try {
96 -
            IScriptContext scriptContext = getCurrentScriptContext();
97 -
98 -
            /*
99 -
             * By taking the stack trace of the main thread, we can correlate image loads with the current
100 -
             * line in the .lvn file. This assumes that the main thread is used to run the .lvn files, but that should
101 -
             * pretty much always be the case.
102 -
             */
103 -
            callStack = scriptContext.getMainThread().getStackTrace();
104 -
        } catch (ScriptException e) {
105 -
            LOG.warn("No script context is current: unable to determine callStack", e);
94 +
        IContext context = ContextUtil.getCurrentContext();
95 +
        if (context == null) {
96 +
            LOG.debug("No context is current: unable to determine callStack: {}", filename);
97 +
        } else {
98 +
            try {
99 +
                IScriptContext scriptContext = getCurrentScriptContext();
100 +
101 +
                /*
102 +
                 * By taking the stack trace of the main thread, we can correlate image loads with the current
103 +
                 * line in the .lvn file. This assumes that the main thread is used to run the .lvn files, but that should
104 +
                 * pretty much always be the case.
105 +
                 */
106 +
                callStack = scriptContext.getMainThread().getStackTrace();
107 +
            } catch (ScriptException e) {
108 +
                LOG.warn("No script context is current: unable to determine callStack: {}", filename, e);
109 +
            }
106 110
        }
107 -
108 111
        return new ResourceLoadInfo(mediaType, filename, callStack);
109 112
    }
110 113
@@ -117,9 +120,8 @@
Loading
117 120
     *
118 121
     * @throws IOException If the script file can't be read.
119 122
     * @throws ScriptException If the script throws an exception.
120 -
     * @see IScriptLoader#loadScript(IScriptThread, FilePath)
121 123
     */
122 -
    public static void loadScript(IContext mainContext, IScriptLoader scriptLoader, FilePath scriptFilename)
124 +
    public static void loadScript(IContext mainContext, FilePath scriptFilename)
123 125
            throws IOException, ScriptException {
124 126
125 127
        LuaScriptContext scriptContext = getScriptContext(mainContext);
@@ -127,7 +129,7 @@
Loading
127 129
128 130
        IContext oldContext = ContextUtil.setCurrentContext(mainContext);
129 131
        try {
130 -
            scriptLoader.loadScript(mainThread, scriptFilename);
132 +
            mainThread.call(scriptContext.loadScriptAsClosure(scriptFilename));
131 133
        } finally {
132 134
            ContextUtil.setCurrentContext(oldContext);
133 135
        }
@@ -153,7 +155,6 @@
Loading
153 155
     * Calls a function in the main thread of the given context.
154 156
     *
155 157
     * @throws ScriptException If the Lua function throws an exception when called.
156 -
     * @see IScriptLoader#loadScript(IScriptThread, FilePath)
157 158
     */
158 159
    public static void callFunction(IContext mainContext, IScriptFunction func) throws ScriptException {
159 160
        LuaScriptContext scriptContext = getScriptContext(mainContext);
@@ -169,7 +170,6 @@
Loading
169 170
     * Runs arbitrary Lua code in the main thread of the given context.
170 171
     *
171 172
     * @throws ScriptException If the Lua code can't be parsed, or throws an exception.
172 -
     * @see IScriptLoader#loadScript(IScriptThread, FilePath)
173 173
     */
174 174
    public static String eval(IContext context, String luaCode) throws ScriptException {
175 175
        Varargs result;
@@ -186,7 +186,6 @@
Loading
186 186
     * Runs arbitrary Lua code in the given thread.
187 187
     *
188 188
     * @throws ScriptException If the Lua code can't be parsed, or throws an exception.
189 -
     * @see IScriptLoader#loadScript(IScriptThread, FilePath)
190 189
     */
191 190
    public static String eval(IContextManager contextManager, ILuaScriptThread thread, String luaCode)
192 191
            throws ScriptException {

@@ -8,7 +8,9 @@
Loading
8 8
import org.slf4j.LoggerFactory;
9 9
10 10
import nl.weeaboo.common.Checks;
11 +
import nl.weeaboo.filesystem.FilePath;
11 12
import nl.weeaboo.lua2.LuaRunState;
13 +
import nl.weeaboo.lua2.compiler.ScriptLoader;
12 14
import nl.weeaboo.lua2.vm.LuaClosure;
13 15
import nl.weeaboo.lua2.vm.LuaConstants;
14 16
import nl.weeaboo.lua2.vm.LuaTable;
@@ -62,6 +64,19 @@
Loading
62 64
        return mainThread.isDestroyed();
63 65
    }
64 66
67 +
    @Override
68 +
    public IScriptThread loadScriptInNewThread(FilePath path) throws ScriptException {
69 +
        return createThread(loadScriptAsClosure(path));
70 +
    }
71 +
72 +
    LuaClosure loadScriptAsClosure(FilePath path) throws ScriptException {
73 +
        Varargs loadResult = ScriptLoader.loadFile(path.toString());
74 +
        if (!loadResult.arg1().isclosure()) {
75 +
            throw new ScriptException("Error loading script, " + path + ": " + loadResult.arg(2));
76 +
        }
77 +
        return loadResult.checkclosure(1);
78 +
    }
79 +
65 80
    /**
66 81
     * Calls a no-arg function in a new thread.
67 82
     * @throws ScriptException If the function can't be called, or the thread can't be created.

@@ -1,19 +1,15 @@
Loading
1 1
package nl.weeaboo.vn.desktop.debug;
2 2
3 -
import java.io.File;
4 -
import java.io.IOException;
5 3
import java.net.URI;
6 -
7 -
import org.slf4j.Logger;
8 -
import org.slf4j.LoggerFactory;
4 +
import java.nio.file.Path;
5 +
import java.nio.file.Paths;
9 6
10 7
/**
11 8
 * Performs file path conversions.
12 9
 */
13 10
final class NameMapping {
14 11
15 -
    private static final Logger LOG = LoggerFactory.getLogger(DebugBreakpoint.class);
16 -
    private static final File SCRIPT_FOLDER = new File("res/script");
12 +
    private static final Path SCRIPT_FOLDER = Paths.get("res/script").toAbsolutePath();
17 13
18 14
    /**
19 15
     * Turns an absolute path to a file in the res/script folder into a relative path.
@@ -25,12 +21,12 @@
Loading
25 21
            return absolutePath;
26 22
        }
27 23
28 -
        try {
29 -
            URI scriptFolderUri = SCRIPT_FOLDER.getCanonicalFile().toURI();
30 -
            URI absoluteUri = new File(absolutePath).getCanonicalFile().toURI();
31 -
            return scriptFolderUri.relativize(absoluteUri).getPath();
32 -
        } catch (IOException ioe) {
33 -
            LOG.warn("Unable to determine relative path for {}", absolutePath, ioe);
24 +
        URI scriptFolderUri = SCRIPT_FOLDER.toUri();
25 +
        URI uri = Paths.get(absolutePath).toAbsolutePath().toUri();
26 +
        if (uri.getPath().startsWith(scriptFolderUri.getPath())) {
27 +
            return scriptFolderUri.relativize(uri).getPath();
28 +
        } else {
29 +
            // Path isn't relative to the script folder
34 30
            return absolutePath;
35 31
        }
36 32
    }
@@ -45,12 +41,7 @@
Loading
45 41
            return relativePath;
46 42
        }
47 43
48 -
        try {
49 -
            return new File(SCRIPT_FOLDER, relativePath).getCanonicalPath();
50 -
        } catch (IOException ioe) {
51 -
            LOG.warn("Unable to determine absolute path for {}", relativePath, ioe);
52 -
            return relativePath;
53 -
        }
44 +
        return SCRIPT_FOLDER.resolve(relativePath).toAbsolutePath().toString();
54 45
    }
55 46
56 47
}

@@ -14,7 +14,7 @@
Loading
14 14
    }
15 15
16 16
    public boolean isJustPressed() {
17 -
        return pressed && isJustPressed && !consumed;
17 +
        return isJustPressed && !consumed;
18 18
    }
19 19
20 20
    public void clearJustPressed() {
@@ -47,7 +47,6 @@
Loading
47 47
48 48
    public void onReleased(long timestampMs) {
49 49
        consumed = false;
50 -
        isJustPressed = false;
51 50
        pressed = false;
52 51
        pressedStateSinceMs = timestampMs;
53 52
    }

@@ -67,18 +67,26 @@
Loading
67 67
    /**
68 68
     * Sets the diagonals of the multiplication part (RGBA order).
69 69
     */
70 -
    public void setDiagonals(double[] rgba) {
71 -
        mul[RR] = rgba[0];
72 -
        mul[GG] = rgba[1];
73 -
        mul[BB] = rgba[2];
74 -
        mul[AA] = rgba[3];
70 +
    public void setDiagonals(double... rgba) {
71 +
        if (rgba.length > 0) {
72 +
            mul[RR] = rgba[0];
73 +
        }
74 +
        if (rgba.length > 1) {
75 +
            mul[GG] = rgba[1];
76 +
        }
77 +
        if (rgba.length > 2) {
78 +
            mul[BB] = rgba[2];
79 +
        }
80 +
        if (rgba.length > 3) {
81 +
            mul[AA] = rgba[3];
82 +
        }
75 83
    }
76 84
77 85
    /**
78 86
     * Sets the multiplication factors (RGBA order) for the red output.
79 87
     */
80 -
    public void setRedFactors(double[] factorsRGBA) {
81 -
        for (int n = 0; n < 4; n++) {
88 +
    public void setRedFactors(double... factorsRGBA) {
89 +
        for (int n = 0; n < factorsRGBA.length; n++) {
82 90
            mul[0 + n] = factorsRGBA[n];
83 91
        }
84 92
    }
@@ -86,8 +94,8 @@
Loading
86 94
    /**
87 95
     * Sets the multiplication factors (RGBA order) for the green output.
88 96
     */
89 -
    public void setGreenFactors(double[] factorsRGBA) {
90 -
        for (int n = 0; n < 4; n++) {
97 +
    public void setGreenFactors(double... factorsRGBA) {
98 +
        for (int n = 0; n < factorsRGBA.length; n++) {
91 99
            mul[4 + n] = factorsRGBA[n];
92 100
        }
93 101
    }
@@ -95,8 +103,8 @@
Loading
95 103
    /**
96 104
     * Sets the multiplication factors (RGBA order) for the blue output.
97 105
     */
98 -
    public void setBlueFactors(double[] factorsRGBA) {
99 -
        for (int n = 0; n < 4; n++) {
106 +
    public void setBlueFactors(double... factorsRGBA) {
107 +
        for (int n = 0; n < factorsRGBA.length; n++) {
100 108
            mul[8 + n] = factorsRGBA[n];
101 109
        }
102 110
    }
@@ -104,8 +112,8 @@
Loading
104 112
    /**
105 113
     * Sets the multiplication factors (RGBA order) for the alpha output.
106 114
     */
107 -
    public void setAlphaFactors(double[] factorsRGBA) {
108 -
        for (int n = 0; n < 4; n++) {
115 +
    public void setAlphaFactors(double... factorsRGBA) {
116 +
        for (int n = 0; n < factorsRGBA.length; n++) {
109 117
            mul[12 + n] = factorsRGBA[n];
110 118
        }
111 119
    }
@@ -119,8 +127,8 @@
Loading
119 127
     * a' = a + aoff
120 128
     * </pre>
121 129
     */
122 -
    public void setOffsets(double[] offsets) {
123 -
        for (int n = 0; n < 4; n++) {
130 +
    public void setOffsets(double... offsets) {
131 +
        for (int n = 0; n < offsets.length; n++) {
124 132
            off[n] = offsets[n];
125 133
        }
126 134
    }

@@ -71,6 +71,9 @@
Loading
71 71
                    threadEvent.setThreadId(debugThread.getThreadId());
72 72
                    threadEvent.setReason(ThreadEventArgumentsReason.STARTED);
73 73
                    peer.thread(threadEvent);
74 +
                } else {
75 +
                    // TODO: Remove temporary workaround for bug in LuaJPP2 that clears the debug hook
76 +
                    debugThread.installHook(breakpoints);
74 77
                }
75 78
76 79
                if (context == primaryContext && thread == scriptContext.getMainThread()) {

@@ -3,6 +3,7 @@
Loading
3 3
import java.io.Closeable;
4 4
import java.io.IOException;
5 5
import java.io.InputStream;
6 +
import java.io.OutputStream;
6 7
import java.net.Socket;
7 8
import java.util.ArrayList;
8 9
import java.util.List;
@@ -47,18 +48,19 @@
Loading
47 48
import org.slf4j.Logger;
48 49
import org.slf4j.LoggerFactory;
49 50
51 +
import com.google.common.annotations.VisibleForTesting;
50 52
import com.google.common.base.Preconditions;
51 53
import com.google.common.util.concurrent.ThreadFactoryBuilder;
52 54
53 55
import nl.weeaboo.common.StringUtil;
56 +
import nl.weeaboo.filesystem.FilePath;
54 57
import nl.weeaboo.io.StreamUtil;
55 -
import nl.weeaboo.lua2.LuaRunState;
56 58
import nl.weeaboo.lua2.LuaUtil;
57 -
import nl.weeaboo.lua2.lib.LuaResource;
58 59
import nl.weeaboo.vn.core.IContextManager;
59 60
import nl.weeaboo.vn.core.INovel;
60 61
import nl.weeaboo.vn.impl.core.StaticEnvironment;
61 62
import nl.weeaboo.vn.impl.script.lua.LuaScriptUtil;
63 +
import nl.weeaboo.vn.script.IScriptLoader;
62 64
import nl.weeaboo.vn.script.ScriptException;
63 65
64 66
/**
@@ -76,7 +78,7 @@
Loading
76 78
    private Future<?> periodicUpdateTask = CompletableFuture.completedFuture(null);
77 79
78 80
    private IDebugProtocolClient peer;
79 -
    private Socket socket;
81 +
    private IConnection connection;
80 82
    private Future<Void> messageHandler;
81 83
82 84
    private NvlistDebugServer(INvlistTaskRunner taskRunner) {
@@ -101,13 +103,14 @@
Loading
101 103
        periodicUpdateTask.cancel(true);
102 104
        messageHandler.cancel(true);
103 105
        try {
104 -
            socket.close();
106 +
            connection.close();
105 107
        } catch (IOException e) {
106 108
            LOG.warn("I/O exception trying to close debug server", e);
107 109
        }
108 110
    }
109 111
110 -
    private void update() {
112 +
    @VisibleForTesting
113 +
    void update() {
111 114
        INovel novel = getNovel();
112 115
        if (novel != null) {
113 116
            activeThreads.update(novel.getEnv().getContextManager(), peer);
@@ -118,10 +121,14 @@
Loading
118 121
    public CompletableFuture<Void> disconnect(DisconnectArguments args) {
119 122
        LOG.debug("[debug-server] Received disconnect request {}", args);
120 123
121 -
        close();
122 -
        System.exit(0);
123 -
124 -
        return CompletableFuture.completedFuture(null);
124 +
        return taskRunner.runOnNvlistThread(() -> {
125 +
            close();
126 +
            try {
127 +
                System.exit(0);
128 +
            } catch (SecurityException e) {
129 +
                LOG.warn("System.exit() isn't allowed");
130 +
            }
131 +
        });
125 132
    }
126 133
127 134
    @Override
@@ -131,11 +138,12 @@
Loading
131 138
132 139
            INovel novel = getNovel();
133 140
            DebugThread primaryThread = activeThreads.getPrimaryThread();
134 -
            String program = NameMapping.toRelativeScriptPath((String)args.get("program"));
141 +
            String program = (String)args.get("program");
135 142
            if (novel == null || primaryThread == null || program == null) {
136 143
                return;
137 144
            }
138 145
146 +
            program = NameMapping.toRelativeScriptPath(program);
139 147
            String expr = StringUtil.formatRoot("jump(\"%s\")", LuaUtil.escape(program));
140 148
            try {
141 149
                LuaScriptUtil.eval(novel.getEnv().getContextManager(), primaryThread.getThread(), expr);
@@ -148,7 +156,7 @@
Loading
148 156
    @Override
149 157
    public CompletableFuture<Void> pause(PauseArguments args) {
150 158
        return taskRunner.runOnNvlistThread(() -> {
151 -
            LOG.debug("[debug-server] Received pause request {}", args.getThreadId());
159 +
            LOG.debug("[debug-server] Received pause request for thread #{}", args.getThreadId());
152 160
153 161
            DebugThread thread = activeThreads.findById(args.getThreadId());
154 162
            if (thread != null) {
@@ -165,7 +173,7 @@
Loading
165 173
    @Override
166 174
    public CompletableFuture<ContinueResponse> continue_(ContinueArguments args) {
167 175
        return taskRunner.supplyOnNvlistThread(() -> {
168 -
            LOG.debug("[debug-server] Received continue request {}", args.getThreadId());
176 +
            LOG.debug("[debug-server] Received continue request for thread #{}", args.getThreadId());
169 177
170 178
            DebugThread thread = activeThreads.findById(args.getThreadId());
171 179
            if (thread != null) {
@@ -300,19 +308,17 @@
Loading
300 308
        return taskRunner.supplyOnNvlistThread(() -> {
301 309
            LOG.debug("[debug-server] Received source request: source={}", args.getSource());
302 310
303 -
            LuaRunState lrs = LuaRunState.getCurrent();
304 -
            Preconditions.checkNotNull(lrs, "NVList isn't active");
311 +
            INovel novel = getNovel();
312 +
            Preconditions.checkNotNull(novel, "NVList isn't active");
305 313
306 314
            String relPath = NameMapping.toRelativeScriptPath(args.getSource().getPath());
315 +
            IScriptLoader scriptLoader = novel.getEnv().getScriptEnv().getScriptLoader();
307 316
308 317
            SourceResponse response = new SourceResponse();
309 -
            LuaResource resource = lrs.findResource(relPath);
310 -
            if (resource != null) {
311 -
                try (InputStream in = resource.open()) {
312 -
                    response.setContent(StringUtil.fromUTF8(StreamUtil.readBytes(in)));
313 -
                } catch (IOException e) {
314 -
                    LOG.warn("Error reading source file: " + relPath, e);
315 -
                }
318 +
            try (InputStream in = scriptLoader.openScript(FilePath.of(relPath))) {
319 +
                response.setContent(StringUtil.fromUTF8(StreamUtil.readBytes(in)));
320 +
            } catch (IOException e) {
321 +
                throw new IllegalStateException("Error reading source file: " + relPath, e);
316 322
            }
317 323
            return response;
318 324
        });
@@ -325,6 +331,11 @@
Loading
325 331
326 332
    public static NvlistDebugServer start(INvlistTaskRunner taskRunner, @WillCloseWhenClosed Socket socket,
327 333
            ExecutorService executorService) throws IOException {
334 +
        return start(taskRunner, new SocketConnection(socket), executorService);
335 +
    }
336 +
337 +
    static NvlistDebugServer start(INvlistTaskRunner taskRunner, @WillCloseWhenClosed IConnection socket,
338 +
            ExecutorService executorService) throws IOException {
328 339
329 340
        NvlistDebugServer debugServer = new NvlistDebugServer(taskRunner);
330 341
        Launcher<IDebugProtocolClient> launcher = new DebugLauncher.Builder<IDebugProtocolClient>()
@@ -335,9 +346,42 @@
Loading
335 346
                .setExecutorService(executorService)
336 347
                .create();
337 348
        debugServer.peer = launcher.getRemoteProxy();
338 -
        debugServer.socket = socket;
349 +
        debugServer.connection = socket;
339 350
        debugServer.messageHandler = launcher.startListening();
340 351
        return debugServer;
341 352
    }
342 353
354 +
    interface IConnection extends Closeable {
355 +
356 +
        InputStream getInputStream() throws IOException;
357 +
358 +
        OutputStream getOutputStream() throws IOException;
359 +
360 +
    }
361 +
362 +
    static final class SocketConnection implements IConnection {
363 +
364 +
        private final Socket socket;
365 +
366 +
        SocketConnection(@WillCloseWhenClosed Socket socket) {
367 +
            this.socket = socket;
368 +
        }
369 +
370 +
        @Override
371 +
        public void close() throws IOException {
372 +
            socket.close();
373 +
        }
374 +
375 +
        @Override
376 +
        public InputStream getInputStream() throws IOException {
377 +
            return socket.getInputStream();
378 +
        }
379 +
380 +
        @Override
381 +
        public OutputStream getOutputStream() throws IOException {
382 +
            return socket.getOutputStream();
383 +
        }
384 +
385 +
    }
386 +
343 387
}

@@ -16,6 +16,7 @@
Loading
16 16
17 17
import nl.weeaboo.common.Checks;
18 18
import nl.weeaboo.common.StringUtil;
19 +
import nl.weeaboo.filesystem.FileCollectOptions;
19 20
import nl.weeaboo.filesystem.FilePath;
20 21
import nl.weeaboo.io.Filenames;
21 22
import nl.weeaboo.styledtext.EFontStyle;
@@ -56,13 +57,23 @@
Loading
56 57
        cache = new FontCache(new ResourceStoreCacheConfig<>());
57 58
    }
58 59
59 -
    private void loadBuiltInFont() {
60 +
    private void loadInitialFonts() {
60 61
        try {
61 62
            loadFont(Gdx.files.classpath("builtin/font/default.ttf"),
62 63
                    new TextStyle(TextUtil.DEFAULT_FONT_NAME, 16));
63 64
        } catch (IOException e) {
64 65
            LOG.warn("Error loading built-in font", e);
65 66
        }
67 +
68 +
        for (FilePath fontPath : resourceFileSystem.getFiles(FileCollectOptions.files(FilePath.of("font")))) {
69 +
            try {
70 +
                MutableTextStyle mts = new MutableTextStyle();
71 +
                mts.setFontName(Filenames.stripExtension(fontPath.getName()));
72 +
                loadFont(fontPath, mts.immutableCopy());
73 +
            } catch (IOException e) {
74 +
                LOG.warn("Error loading in font: {}", fontPath, e);
75 +
            }
76 +
        }
66 77
    }
67 78
68 79
    @Override
@@ -94,6 +105,9 @@
Loading
94 105
95 106
    private List<FilePath> getStyleSpecificPaths(FilePath path, EFontStyle fontStyle) {
96 107
        FilePath parent = path.getParent();
108 +
        if (parent == null) {
109 +
            parent = FilePath.empty();
110 +
        }
97 111
        String baseName = Filenames.stripExtension(path.getName());
98 112
        String ext = Filenames.getExtension(path.getName());
99 113
@@ -121,9 +135,8 @@
Loading
121 135
     * may be returned instead.
122 136
     */
123 137
    public IFontMetrics getFontMetrics(FilePath absoluteFontPath, TextStyle styleArg) {
124 -
        // Add the default font if we didn't do that yet
125 138
        if (backing.getFonts().isEmpty()) {
126 -
            loadBuiltInFont();
139 +
            loadInitialFonts();
127 140
        }
128 141
129 142
        // Workaround for a bug in gdx-styledtext -- a null font name causes problems

@@ -66,8 +66,8 @@
Loading
66 66
    }
67 67
68 68
    @Override
69 -
    public ITextureData getPixels() {
70 -
        if (!isLoaded) {
69 +
    public @Nullable ITextureData getPixels() {
70 +
        if (!isLoaded && data != null) {
71 71
            tryLoad(data);
72 72
            isLoaded = true;
73 73
        }

@@ -4,6 +4,8 @@
Loading
4 4
import java.io.ObjectInputStream;
5 5
import java.io.ObjectOutputStream;
6 6
7 +
import javax.annotation.Nullable;
8 +
7 9
import nl.weeaboo.common.Checks;
8 10
import nl.weeaboo.common.Dim;
9 11
import nl.weeaboo.io.CustomSerializable;
@@ -86,7 +88,7 @@
Loading
86 88
    }
87 89
88 90
    @Override
89 -
    public ITextureData getPixels() {
91 +
    public @Nullable ITextureData getPixels() {
90 92
        return pixels;
91 93
    }
92 94

@@ -206,22 +206,22 @@
Loading
206 206
        ColorMatrix matrix = new ColorMatrix();
207 207
        double[] offsets = new double[4];
208 208
        if (args.arg(2).istable()) {
209 -
            double[] arr = toDoubleArray(args.arg(2), 5);
209 +
            double[] arr = toDoubleArray(args.arg(2), 4);
210 210
            matrix.setRedFactors(arr);
211 211
            offsets[0] = arr[0];
212 212
        }
213 213
        if (args.arg(3).istable()) {
214 -
            double[] arr = toDoubleArray(args.arg(3), 5);
214 +
            double[] arr = toDoubleArray(args.arg(3), 4);
215 215
            matrix.setGreenFactors(arr);
216 216
            offsets[1] = arr[1];
217 217
        }
218 218
        if (args.arg(4).istable()) {
219 -
            double[] arr = toDoubleArray(args.arg(4), 5);
219 +
            double[] arr = toDoubleArray(args.arg(4), 4);
220 220
            matrix.setBlueFactors(arr);
221 221
            offsets[2] = arr[2];
222 222
        }
223 223
        if (args.arg(5).istable()) {
224 -
            double[] arr = toDoubleArray(args.arg(5), 5);
224 +
            double[] arr = toDoubleArray(args.arg(5), 4);
225 225
            matrix.setAlphaFactors(arr);
226 226
            offsets[3] = arr[3];
227 227
        }
Files Complexity Coverage
api/src/main/java/nl/weeaboo/vn 91.53% 96.76%
buildtools/src/main/java/nl/weeaboo/vn/buildtools 81.13% 87.46%
core/src/main/java/nl/weeaboo/vn 83.34% 87.78%
desktop/src/main/java/nl/weeaboo/vn/desktop 75.71% 82.24%
Project Totals (384 files) 83.67% 88.24%
1
codecov:
2
  status:
3
    project: yes
4
    patch: no
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading