Formatted source, added/updated copyright headers

- Also added formatting settings for Eclipse IDE
This commit is contained in:
OLEGSHA 2021-01-13 14:36:18 +03:00
parent 8f3009300f
commit c2d91726a7
No known key found for this signature in database
GPG Key ID: 4D67C3031B4D85E0
438 changed files with 35918 additions and 28764 deletions

View File

@ -1,5 +1,23 @@
#!/bin/bash #!/bin/bash
#
# Progressia
# Copyright (C) 2020-2021 Wind Corporation and contributors
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
echoerr() { echo "$@" 1>&2; } echoerr() { echo "$@" 1>&2; }
buildDebianPackage() { buildDebianPackage() {

View File

@ -100,6 +100,18 @@ Alternatively, specify another location outside of the project's root directory.
Step 5 is required to specify that the game must run in some directory other than the project root, Step 5 is required to specify that the game must run in some directory other than the project root,
which is the default in Eclipse. which is the default in Eclipse.
### Applying formatting templates
Windcorp's Progressia repository is formatted with a style defined for Eclipse IDE in
`templates_and_presets/eclipse_ide`.
Please apply these templates to the project to automatically format the source in a similar fashion.
1. In project context menu, click 'Properties'.
2. In 'Java Code Style' > 'Code Templates', check 'Enable project specific settings', then click 'Import' and select
`templates_and_presets/eclipse_ide/CodeTemplates.xml`.
3. In 'Java Code Style' > 'Formatter', check 'Enable project specific settings', then click 'Import' and select
`templates_and_presets/eclipse_ide/FormatterProfile.xml`.
## Common problems ## Common problems
### Buildship plugin fails with a cryptic message ### Buildship plugin fails with a cryptic message
@ -110,4 +122,4 @@ searches for Java installations in system path regardless and may fail independe
__Solution:__ the simplest solution is to reinstall JDK making sure that system path is affected. __Solution:__ the simplest solution is to reinstall JDK making sure that system path is affected.
See [Build Guide](BuildGuide.md) for details. Another course of action is to manually append the See [Build Guide](BuildGuide.md) for details. Another course of action is to manually append the
Java installation directory (specifically its `bin` folder) to the system `PATH` variable. Java installation directory (specifically its `bin` folder) to the system `PATH` variable.

View File

@ -3,9 +3,11 @@ package kdotjpg.opensimplex2.areagen;
* This file has been modified in the following ways: * This file has been modified in the following ways:
* - added a package declaration at line 1; * - added a package declaration at line 1;
* - added missing @Override annotations; * - added missing @Override annotations;
* - commented out line 965 due to unused variables. * - commented out line 967 due to unused variables.
* The original version of this file can be found at * The original version of this file can be found at
* https://raw.githubusercontent.com/KdotJPG/OpenSimplex2/master/java/areagen/OpenSimplex2S.java * https://raw.githubusercontent.com/KdotJPG/OpenSimplex2/master/java/areagen/OpenSimplex2S.java
*
* @formatter:off
*/ */
/** /**
@ -983,16 +985,3 @@ public class OpenSimplex2S {
} }
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,20 +1,21 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil; package ru.windcorp.jputil;
import java.io.OutputStream; import java.io.OutputStream;
@ -22,53 +23,53 @@ import java.io.PrintWriter;
import java.io.Writer; import java.io.Writer;
public class CSVWriter { public class CSVWriter {
private String columnSeparator = ";"; private String columnSeparator = ";";
private String rowSeparator = "\n"; private String rowSeparator = "\n";
private boolean shouldAddSeparator = false; private boolean shouldAddSeparator = false;
private final PrintWriter parent; private final PrintWriter parent;
public CSVWriter(PrintWriter output) { public CSVWriter(PrintWriter output) {
this.parent = output; this.parent = output;
} }
public CSVWriter(Writer output) { public CSVWriter(Writer output) {
this(new PrintWriter(output)); this(new PrintWriter(output));
} }
public CSVWriter(OutputStream output) { public CSVWriter(OutputStream output) {
this(new PrintWriter(output)); this(new PrintWriter(output));
} }
public PrintWriter getParent() { public PrintWriter getParent() {
return parent; return parent;
} }
public String getColumnSeparator() { public String getColumnSeparator() {
return columnSeparator; return columnSeparator;
} }
public CSVWriter setColumnSeparator(String columnSeparator) { public CSVWriter setColumnSeparator(String columnSeparator) {
this.columnSeparator = columnSeparator; this.columnSeparator = columnSeparator;
return this; return this;
} }
public String getRowSeparator() { public String getRowSeparator() {
return rowSeparator; return rowSeparator;
} }
public CSVWriter setRowSeparator(String rowSeparator) { public CSVWriter setRowSeparator(String rowSeparator) {
this.rowSeparator = rowSeparator; this.rowSeparator = rowSeparator;
return this; return this;
} }
public void print(Object object) { public void print(Object object) {
skip(); skip();
getParent().print(String.valueOf(object)); getParent().print(String.valueOf(object));
} }
public void skip() { public void skip() {
if (shouldAddSeparator) { if (shouldAddSeparator) {
getParent().print(getColumnSeparator()); getParent().print(getColumnSeparator());
@ -76,27 +77,27 @@ public class CSVWriter {
shouldAddSeparator = true; shouldAddSeparator = true;
} }
} }
public void skip(int amount) { public void skip(int amount) {
for (int i = 0; i < amount; ++i) { for (int i = 0; i < amount; ++i) {
skip(); skip();
} }
} }
public void endRow() { public void endRow() {
getParent().print(getRowSeparator()); getParent().print(getRowSeparator());
shouldAddSeparator = false; shouldAddSeparator = false;
} }
public void endRow(Object object) { public void endRow(Object object) {
print(object); print(object);
endRow(); endRow();
} }
public void flush() { public void flush() {
getParent().flush(); getParent().flush();
} }
public void close() { public void close() {
getParent().close(); getParent().close();
} }

View File

@ -1,6 +1,6 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -14,47 +14,57 @@
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil; package ru.windcorp.jputil;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
public class PrimitiveUtil { public class PrimitiveUtil {
private PrimitiveUtil() {} private PrimitiveUtil() {
}
private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_BOXED = new HashMap<>(); private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_BOXED = new HashMap<>();
private static final Map<Class<?>, Object> PRIMITIVE_TO_NULL = new HashMap<>(); private static final Map<Class<?>, Object> PRIMITIVE_TO_NULL = new HashMap<>();
static { static {
for (Class<?> boxed : new Class<?>[] { for (
Boolean.class, Byte.class, Short.class, Character.class, Class<?> boxed : new Class<?>[] {
Integer.class, Long.class, Float.class, Double.class Boolean.class,
}) { Byte.class,
Short.class,
Character.class,
Integer.class,
Long.class,
Float.class,
Double.class
}
) {
try { try {
PRIMITIVE_TO_BOXED.put((Class<?>) boxed.getField("TYPE").get(null), boxed); PRIMITIVE_TO_BOXED.put((Class<?>) boxed.getField("TYPE").get(null), boxed);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
PRIMITIVE_TO_NULL.put(Boolean.TYPE, Boolean.FALSE); PRIMITIVE_TO_NULL.put(Boolean.TYPE, Boolean.FALSE);
PRIMITIVE_TO_NULL.put(Byte.TYPE, Byte.valueOf((byte) 0)); PRIMITIVE_TO_NULL.put(Byte.TYPE, Byte.valueOf((byte) 0));
PRIMITIVE_TO_NULL.put(Short.TYPE, Short.valueOf((short) 0)); PRIMITIVE_TO_NULL.put(Short.TYPE, Short.valueOf((short) 0));
PRIMITIVE_TO_NULL.put(Integer.TYPE, Integer.valueOf(0)); PRIMITIVE_TO_NULL.put(Integer.TYPE, Integer.valueOf(0));
PRIMITIVE_TO_NULL.put(Long.TYPE, Long.valueOf(0)); PRIMITIVE_TO_NULL.put(Long.TYPE, Long.valueOf(0));
PRIMITIVE_TO_NULL.put(Float.TYPE, Float.valueOf(Float.NaN)); PRIMITIVE_TO_NULL.put(Float.TYPE, Float.valueOf(Float.NaN));
PRIMITIVE_TO_NULL.put(Double.TYPE, Double.valueOf(Double.NaN)); PRIMITIVE_TO_NULL.put(Double.TYPE, Double.valueOf(Double.NaN));
PRIMITIVE_TO_NULL.put(Character.TYPE, Character.valueOf('\u0000')); PRIMITIVE_TO_NULL.put(Character.TYPE, Character.valueOf('\u0000'));
} }
public static Class<?> getBoxedClass(Class<?> primitiveClass) { public static Class<?> getBoxedClass(Class<?> primitiveClass) {
return PRIMITIVE_TO_BOXED.getOrDefault(primitiveClass, primitiveClass); return PRIMITIVE_TO_BOXED.getOrDefault(primitiveClass, primitiveClass);
} }
public static Object getPrimitiveNull(Class<?> primitiveClass) { public static Object getPrimitiveNull(Class<?> primitiveClass) {
return PRIMITIVE_TO_NULL.get(primitiveClass); return PRIMITIVE_TO_NULL.get(primitiveClass);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +1,45 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil;
package ru.windcorp.jputil;
public class SyntaxException extends Exception {
public class SyntaxException extends Exception {
private static final long serialVersionUID = -4052144233640072750L;
private static final long serialVersionUID = -4052144233640072750L;
public SyntaxException() {
public SyntaxException() {
}
}
public SyntaxException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace); public SyntaxException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
} super(message, cause, enableSuppression, writableStackTrace);
}
public SyntaxException(String message, Throwable cause) {
super(message, cause); public SyntaxException(String message, Throwable cause) {
} super(message, cause);
}
public SyntaxException(String message) {
super(message); public SyntaxException(String message) {
} super(message);
}
public SyntaxException(Throwable cause) {
super(cause); public SyntaxException(Throwable cause) {
} super(cause);
}
}
}

View File

@ -1,128 +1,132 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars;
package ru.windcorp.jputil.chars;
import java.text.CharacterIterator;
import java.text.CharacterIterator;
public class CharArrayIterator implements CharacterIterator {
public class CharArrayIterator implements CharacterIterator {
private final char[] array;
private int pos; private final char[] array;
private int pos;
public CharArrayIterator(char[] array) {
this.array = array; public CharArrayIterator(char[] array) {
} this.array = array;
}
public CharArrayIterator(String src) {
this(src.toCharArray()); public CharArrayIterator(String src) {
} this(src.toCharArray());
}
@Override
public char first() { @Override
pos = 0; public char first() {
if (array.length != 0) { pos = 0;
return array[pos]; if (array.length != 0) {
} return array[pos];
return DONE; }
} return DONE;
}
@Override
public char last() { @Override
pos = array.length; public char last() {
if (array.length != 0) { pos = array.length;
pos -= 1; if (array.length != 0) {
return array[pos]; pos -= 1;
} return array[pos];
return DONE; }
} return DONE;
}
@Override
public char current() { @Override
if (array.length != 0 && pos < array.length) { public char current() {
return array[pos]; if (array.length != 0 && pos < array.length) {
} return array[pos];
return DONE; }
} return DONE;
}
@Override
public char next() { @Override
pos += 1; public char next() {
if (pos >= array.length) { pos += 1;
pos = array.length; if (pos >= array.length) {
return DONE; pos = array.length;
} return DONE;
return current(); }
} return current();
}
@Override
public char previous() { @Override
if (pos == 0) { public char previous() {
return DONE; if (pos == 0) {
} return DONE;
pos -= 1; }
return current(); pos -= 1;
} return current();
}
@Override
public char setIndex(int position) { @Override
if (position < 0 || position > array.length) { public char setIndex(int position) {
throw new IllegalArgumentException("bad position: " + position); if (position < 0 || position > array.length) {
} throw new IllegalArgumentException("bad position: " + position);
}
pos = position;
pos = position;
if (pos != array.length && array.length != 0) {
return array[pos]; if (pos != array.length && array.length != 0) {
} return array[pos];
return DONE; }
} return DONE;
}
@Override
public int getBeginIndex() { @Override
return 0; public int getBeginIndex() {
} return 0;
}
@Override
public int getEndIndex() { @Override
return array.length; public int getEndIndex() {
} return array.length;
}
@Override
public int getIndex() { @Override
return pos; public int getIndex() {
} return pos;
}
// @SuppressWarnings("all") Just STFU, this _is_ terrific
// @SuppressWarnings("all") Just STFU, this _is_ terrific
// SonarLint: "clone" should not be overridden (java:S2975)
// And I wouldn't have done that if only CharacterIterator had not required exception safety. // SonarLint: "clone" should not be overridden (java:S2975)
// SonarLint: "toString()" and "clone()" methods should not return null (java:S2225) // And I wouldn't have done that if only CharacterIterator had not required
// The clause is unreachable: CharacterArrayIterator implements Cloneable and superclass is Object. // exception safety.
@SuppressWarnings({"squid:S2975", "squid:S2225"}) // SonarLint: "toString()" and "clone()" methods should not return null
// (java:S2225)
@Override // The clause is unreachable: CharacterArrayIterator implements Cloneable
public CharArrayIterator clone() { // and superclass is Object.
try { @SuppressWarnings({ "squid:S2975", "squid:S2225" })
return (CharArrayIterator) super.clone();
} catch (CloneNotSupportedException cnse) { @Override
// Impossible public CharArrayIterator clone() {
return null; try {
} return (CharArrayIterator) super.clone();
} } catch (CloneNotSupportedException cnse) {
// Impossible
} return null;
}
}
}

View File

@ -1,42 +1,43 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars;
package ru.windcorp.jputil.chars;
import java.util.function.IntConsumer;
import java.util.function.IntConsumer;
@FunctionalInterface
public interface CharConsumer { @FunctionalInterface
public interface CharConsumer {
void accept(char c);
void accept(char c);
public static CharConsumer andThen(CharConsumer first, CharConsumer second) {
return c -> { public static CharConsumer andThen(CharConsumer first, CharConsumer second) {
first.accept(c); return c -> {
second.accept(c); first.accept(c);
}; second.accept(c);
} };
}
public static IntConsumer toInt(CharConsumer consumer) {
return i -> consumer.accept((char) i); public static IntConsumer toInt(CharConsumer consumer) {
} return i -> consumer.accept((char) i);
}
public static CharConsumer toChar(IntConsumer consumer) {
return consumer::accept; public static CharConsumer toChar(IntConsumer consumer) {
} return consumer::accept;
}
}
}

View File

@ -1,69 +1,70 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars;
package ru.windcorp.jputil.chars;
import java.util.Objects;
import java.util.Objects;
import ru.windcorp.jputil.ArrayUtil;
import ru.windcorp.jputil.ArrayUtil;
/**
* @author Javapony /**
* * @author Javapony
*/ */
public class CharConsumers { public class CharConsumers {
private CharConsumers() {} private CharConsumers() {
}
public static CharConsumer fillArray(char[] array, int offset, int length) {
return new ArrayFiller(array, offset, length); public static CharConsumer fillArray(char[] array, int offset, int length) {
} return new ArrayFiller(array, offset, length);
}
public static CharConsumer fillArray(char[] array) {
return fillArray(array, 0, -1); public static CharConsumer fillArray(char[] array) {
} return fillArray(array, 0, -1);
}
private static class ArrayFiller implements CharConsumer {
private static class ArrayFiller implements CharConsumer {
final char[] array;
int i; final char[] array;
final int end; int i;
final int end;
/**
* @param array /**
* @param offset * @param array
* @param length * @param offset
*/ * @param length
ArrayFiller(char[] array, int offset, int length) { */
this.array = Objects.requireNonNull(array, "array"); ArrayFiller(char[] array, int offset, int length) {
this.end = ArrayUtil.checkArrayStartEnd(array, offset, offset + length); this.array = Objects.requireNonNull(array, "array");
this.i = offset; this.end = ArrayUtil.checkArrayStartEnd(array, offset, offset + length);
} this.i = offset;
}
/**
* @see ru.windcorp.jputil.chars.CharConsumer#accept(char) /**
*/ * @see ru.windcorp.jputil.chars.CharConsumer#accept(char)
@Override */
public void accept(char c) { @Override
if (i == end) public void accept(char c) {
throw new ArrayIndexOutOfBoundsException(end); if (i == end)
array[i++] = c; throw new ArrayIndexOutOfBoundsException(end);
} array[i++] = c;
}
}
}
}
}

View File

@ -1,84 +1,85 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars;
package ru.windcorp.jputil.chars;
import java.util.Arrays;
import java.util.function.IntPredicate; import java.util.Arrays;
import java.util.function.IntPredicate;
import ru.windcorp.jputil.ArrayUtil;
import ru.windcorp.jputil.ArrayUtil;
@FunctionalInterface
public interface CharPredicate { @FunctionalInterface
public interface CharPredicate {
boolean test(char c);
boolean test(char c);
public static CharPredicate and(CharPredicate first, CharPredicate second) {
return c -> first.test(c) && second.test(c); public static CharPredicate and(CharPredicate first, CharPredicate second) {
} return c -> first.test(c) && second.test(c);
}
public static CharPredicate or(CharPredicate first, CharPredicate second) {
return c -> first.test(c) || second.test(c); public static CharPredicate or(CharPredicate first, CharPredicate second) {
} return c -> first.test(c) || second.test(c);
}
public static CharPredicate negate(CharPredicate predicate) {
return c -> !predicate.test(c); public static CharPredicate negate(CharPredicate predicate) {
} return c -> !predicate.test(c);
}
public static IntPredicate toInt(CharPredicate predicate) {
return i -> predicate.test((char) i); public static IntPredicate toInt(CharPredicate predicate) {
} return i -> predicate.test((char) i);
}
public static CharPredicate toChar(IntPredicate predicate) {
return predicate::test; public static CharPredicate toChar(IntPredicate predicate) {
} return predicate::test;
}
public static CharPredicate forArray(char... chars) {
if (chars.length == 0) { public static CharPredicate forArray(char... chars) {
return c -> false; if (chars.length == 0) {
} return c -> false;
}
if (chars.length == 1) {
return forChar(chars[0]); if (chars.length == 1) {
} return forChar(chars[0]);
}
if (chars.length < 16) {
return c -> ArrayUtil.firstIndexOf(chars, c) >= 0; if (chars.length < 16) {
} else { return c -> ArrayUtil.firstIndexOf(chars, c) >= 0;
final char[] sorted = Arrays.copyOf(chars, chars.length); } else {
Arrays.sort(sorted); final char[] sorted = Arrays.copyOf(chars, chars.length);
return c -> Arrays.binarySearch(chars, c) >= 0; Arrays.sort(sorted);
} return c -> Arrays.binarySearch(chars, c) >= 0;
} }
}
public static CharPredicate forChar(final char c) {
return given -> given == c; public static CharPredicate forChar(final char c) {
} return given -> given == c;
}
public static CharPredicate forRange(final char minInclusive, final char maxExclusive) {
if (minInclusive > maxExclusive) { public static CharPredicate forRange(final char minInclusive, final char maxExclusive) {
throw new IllegalArgumentException("min > max: " + minInclusive + " > " + maxExclusive); if (minInclusive > maxExclusive) {
} throw new IllegalArgumentException("min > max: " + minInclusive + " > " + maxExclusive);
}
if (minInclusive == maxExclusive) {
return c -> false; if (minInclusive == maxExclusive) {
} return c -> false;
}
return c -> c >= minInclusive && c < maxExclusive;
} return c -> c >= minInclusive && c < maxExclusive;
}
}
}

View File

@ -1,35 +1,36 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars;
package ru.windcorp.jputil.chars;
import java.util.function.IntSupplier;
import java.util.function.IntSupplier;
@FunctionalInterface
public interface CharSupplier { @FunctionalInterface
public interface CharSupplier {
char getAsChar();
char getAsChar();
public static IntSupplier toInt(CharSupplier consumer) {
return consumer::getAsChar; public static IntSupplier toInt(CharSupplier consumer) {
} return consumer::getAsChar;
}
public static CharSupplier toChar(IntSupplier consumer) {
return () -> (char) consumer.getAsInt(); public static CharSupplier toChar(IntSupplier consumer) {
} return () -> (char) consumer.getAsInt();
}
}
}

View File

@ -1,44 +1,45 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars;
package ru.windcorp.jputil.chars;
public class EscapeException extends Exception {
public class EscapeException extends Exception {
private static final long serialVersionUID = -3647188859290365053L;
private static final long serialVersionUID = -3647188859290365053L;
public EscapeException() {
super(); public EscapeException() {
} super();
}
public EscapeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace); public EscapeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
} super(message, cause, enableSuppression, writableStackTrace);
}
public EscapeException(String message, Throwable cause) {
super(message, cause); public EscapeException(String message, Throwable cause) {
} super(message, cause);
}
public EscapeException(String message) {
super(message); public EscapeException(String message) {
} super(message);
}
public EscapeException(Throwable cause) {
super(cause); public EscapeException(Throwable cause) {
} super(cause);
}
}
}

View File

@ -1,474 +1,514 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars;
package ru.windcorp.jputil.chars;
import java.text.CharacterIterator;
import java.text.CharacterIterator;
import ru.windcorp.jputil.ArrayUtil;
import ru.windcorp.jputil.chars.reader.CharReader; import ru.windcorp.jputil.ArrayUtil;
import ru.windcorp.jputil.chars.reader.CharReaders; import ru.windcorp.jputil.chars.reader.CharReader;
import ru.windcorp.jputil.chars.reader.CharReaders;
public class Escaper {
public class Escaper {
public static class EscaperBuilder {
private char escapeChar = '\\'; public static class EscaperBuilder {
private char unicodeEscapeChar = 'u'; private char escapeChar = '\\';
private char[] safes = null; private char unicodeEscapeChar = 'u';
private char[] unsafes = null; private char[] safes = null;
private char[] unsafes = null;
private boolean preferUnicode = false;
private boolean strict = true; private boolean preferUnicode = false;
private boolean strict = true;
public EscaperBuilder withEscapeChar(char escapeChar) {
this.escapeChar = escapeChar; public EscaperBuilder withEscapeChar(char escapeChar) {
return this; this.escapeChar = escapeChar;
} return this;
}
public EscaperBuilder withUnicodeEscapeChar(char unicodeEscapeChar) {
this.unicodeEscapeChar = unicodeEscapeChar; public EscaperBuilder withUnicodeEscapeChar(char unicodeEscapeChar) {
return this; this.unicodeEscapeChar = unicodeEscapeChar;
} return this;
}
public EscaperBuilder withChars(char[] safes, char[] unsafes) {
this.safes = safes; public EscaperBuilder withChars(char[] safes, char[] unsafes) {
this.unsafes = unsafes; this.safes = safes;
return this; this.unsafes = unsafes;
} return this;
}
public EscaperBuilder withChars(String safes, String unsafes) {
this.safes = safes.toCharArray(); public EscaperBuilder withChars(String safes, String unsafes) {
this.unsafes = unsafes.toCharArray(); this.safes = safes.toCharArray();
return this; this.unsafes = unsafes.toCharArray();
} return this;
}
public EscaperBuilder withChars(char[] chars) {
this.safes = this.unsafes = chars; public EscaperBuilder withChars(char[] chars) {
return this; this.safes = this.unsafes = chars;
} return this;
}
public EscaperBuilder withChars(String chars) {
this.safes = this.unsafes = chars.toCharArray(); public EscaperBuilder withChars(String chars) {
return this; this.safes = this.unsafes = chars.toCharArray();
} return this;
}
public EscaperBuilder withSafes(char[] safes) {
this.safes = safes; public EscaperBuilder withSafes(char[] safes) {
return this; this.safes = safes;
} return this;
}
public EscaperBuilder withSafes(String safes) {
this.safes = safes.toCharArray(); public EscaperBuilder withSafes(String safes) {
return this; this.safes = safes.toCharArray();
} return this;
}
public EscaperBuilder withUnsafes(char[] unsafes) {
this.unsafes = unsafes; public EscaperBuilder withUnsafes(char[] unsafes) {
return this; this.unsafes = unsafes;
} return this;
}
public EscaperBuilder withUnsafes(String unsafes) {
this.unsafes = unsafes.toCharArray(); public EscaperBuilder withUnsafes(String unsafes) {
return this; this.unsafes = unsafes.toCharArray();
} return this;
}
public EscaperBuilder preferUnicode(boolean preferUnicode) {
this.preferUnicode = preferUnicode; public EscaperBuilder preferUnicode(boolean preferUnicode) {
return this; this.preferUnicode = preferUnicode;
} return this;
}
public EscaperBuilder strict(boolean strict) {
this.strict = strict; public EscaperBuilder strict(boolean strict) {
return this; this.strict = strict;
} return this;
}
public Escaper build() {
return new Escaper(escapeChar, unicodeEscapeChar, safes, unsafes, preferUnicode, strict); public Escaper build() {
} return new Escaper(escapeChar, unicodeEscapeChar, safes, unsafes, preferUnicode, strict);
}
}
}
public static final Escaper JAVA = new Escaper('\\', 'u', "tbnrf'\"".toCharArray(), "\t\b\n\r\f\'\"".toCharArray(), true, true);
public static final Escaper JAVA = new Escaper(
private final char escapeChar; '\\',
private final char unicodeEscapeChar; 'u',
private final char[] safes; "tbnrf'\"".toCharArray(),
private final char[] unsafes; "\t\b\n\r\f\'\"".toCharArray(),
true,
private final boolean preferUnicode; true
private final boolean strict; );
protected Escaper( private final char escapeChar;
char escapeChar, char unicodeEscapeChar, private final char unicodeEscapeChar;
char[] safes, char[] unsafes, private final char[] safes;
boolean preferUnicode, boolean strict) { private final char[] unsafes;
this.escapeChar = escapeChar;
this.unicodeEscapeChar = unicodeEscapeChar; private final boolean preferUnicode;
this.safes = safes; private final boolean strict;
this.unsafes = unsafes;
this.preferUnicode = preferUnicode; protected Escaper(
this.strict = strict; char escapeChar,
char unicodeEscapeChar,
int duplicate; char[] safes,
if ((duplicate = ArrayUtil.hasDuplicates(safes)) != -1) char[] unsafes,
throw new IllegalArgumentException("Duplicate safe character '" + safes[duplicate] + "'"); boolean preferUnicode,
boolean strict
if ((duplicate = ArrayUtil.hasDuplicates(unsafes)) != -1) ) {
throw new IllegalArgumentException("Duplicate unsafe character '" + unsafes[duplicate] + "'"); this.escapeChar = escapeChar;
this.unicodeEscapeChar = unicodeEscapeChar;
for (char c : safes) { this.safes = safes;
if (c == escapeChar) throw new IllegalArgumentException("Safe characters contain escape chatacter"); this.unsafes = unsafes;
if (c == unicodeEscapeChar) throw new IllegalArgumentException("Safe characters contain Unicode escape chatacter"); this.preferUnicode = preferUnicode;
} this.strict = strict;
for (char c : unsafes) { int duplicate;
if (c == escapeChar) throw new IllegalArgumentException("Unsafe characters contain escape chatacter (escape character is escaped automatically)"); if ((duplicate = ArrayUtil.hasDuplicates(safes)) != -1)
if (c == unicodeEscapeChar) throw new IllegalArgumentException("Unsafe characters contain Unicode escape chatacter"); throw new IllegalArgumentException("Duplicate safe character '" + safes[duplicate] + "'");
}
} if ((duplicate = ArrayUtil.hasDuplicates(unsafes)) != -1)
throw new IllegalArgumentException("Duplicate unsafe character '" + unsafes[duplicate] + "'");
public static EscaperBuilder create() {
return new EscaperBuilder(); for (char c : safes) {
} if (c == escapeChar)
throw new IllegalArgumentException("Safe characters contain escape chatacter");
/* if (c == unicodeEscapeChar)
* Logic - escape throw new IllegalArgumentException("Safe characters contain Unicode escape chatacter");
*/ }
public void escape(CharReader src, int length, CharPredicate until, CharConsumer output) { for (char c : unsafes) {
int end; if (c == escapeChar)
if (length < 0) end = Integer.MAX_VALUE; throw new IllegalArgumentException(
else end = src.getPosition() + length; "Unsafe characters contain escape chatacter (escape character is escaped automatically)"
while (src.has() && );
src.getPosition() < end && if (c == unicodeEscapeChar)
(until == null || !until.test(src.current()))) throw new IllegalArgumentException("Unsafe characters contain Unicode escape chatacter");
escape(src.consume(), output); }
} }
public void escape(char c, CharConsumer output) { public static EscaperBuilder create() {
if (c == escapeChar) { return new EscaperBuilder();
output.accept(escapeChar); }
output.accept(escapeChar);
return; /*
} * Logic - escape
*/
int index = ArrayUtil.firstIndexOf(unsafes, c);
public void escape(CharReader src, int length, CharPredicate until, CharConsumer output) {
if (index >= 0) { int end;
output.accept(escapeChar); if (length < 0)
output.accept(safes[index]); end = Integer.MAX_VALUE;
} else { else
if (preferUnicode && !isRegular(c)) { end = src.getPosition() + length;
escapeAsHex(c, output); while (
} else { src.has() &&
output.accept(c); src.getPosition() < end &&
} (until == null || !until.test(src.current()))
} )
} escape(src.consume(), output);
}
// SonarLint: Assignments should not be made from within sub-expressions (java:S1121)
// Seems self-evident enough public void escape(char c, CharConsumer output) {
@SuppressWarnings("squid:S1121") if (c == escapeChar) {
output.accept(escapeChar);
private void escapeAsHex(char c, CharConsumer output) { output.accept(escapeChar);
output.accept(escapeChar); return;
output.accept(unicodeEscapeChar); }
output.accept(StringUtil.hexDigit(c >>= (4 * 3)));
output.accept(StringUtil.hexDigit(c >>= (4 * 2))); int index = ArrayUtil.firstIndexOf(unsafes, c);
output.accept(StringUtil.hexDigit(c >>= (4 * 1)));
output.accept(StringUtil.hexDigit(c >> (4 * 0))); if (index >= 0) {
} output.accept(escapeChar);
output.accept(safes[index]);
public int getEscapedLength(CharReader src, int length, CharPredicate until) { } else {
int end; if (preferUnicode && !isRegular(c)) {
if (length < 0) end = Integer.MAX_VALUE; escapeAsHex(c, output);
else end = src.getPosition() + length; } else {
output.accept(c);
int result = 0; }
}
while (src.has() && }
src.getPosition() < end &&
(until == null || !until.test(src.current()))) { // SonarLint: Assignments should not be made from within sub-expressions
result += getEscapedLength(src.consume()); // (java:S1121)
} // Seems self-evident enough
@SuppressWarnings("squid:S1121")
return result;
} private void escapeAsHex(char c, CharConsumer output) {
output.accept(escapeChar);
public int getEscapedLength(char c) { output.accept(unicodeEscapeChar);
if (c == escapeChar || ArrayUtil.firstIndexOf(unsafes, c) >= 0) output.accept(StringUtil.hexDigit(c >>= (4 * 3)));
return 2; output.accept(StringUtil.hexDigit(c >>= (4 * 2)));
else { output.accept(StringUtil.hexDigit(c >>= (4 * 1)));
if (preferUnicode && !isRegular(c)) output.accept(StringUtil.hexDigit(c >> (4 * 0)));
return 6; }
else
return 1; public int getEscapedLength(CharReader src, int length, CharPredicate until) {
} int end;
} if (length < 0)
end = Integer.MAX_VALUE;
/* else
* Logic - unescape end = src.getPosition() + length;
*/
int result = 0;
public void unescape(CharReader src, int length, CharPredicate until, CharConsumer output) throws EscapeException {
int end; while (
if (length < 0) end = Integer.MAX_VALUE; src.has() &&
else end = src.getPosition() + length; src.getPosition() < end &&
while (src.has() && (until == null || !until.test(src.current()))
src.getPosition() < end && ) {
(until == null || !until.test(src.current()))) { result += getEscapedLength(src.consume());
output.accept(unescapeOneSequence(src)); }
}
} return result;
}
public char unescapeOneSequence(CharReader src) throws EscapeException {
int resetPos = src.getPosition(); public int getEscapedLength(char c) {
try { if (c == escapeChar || ArrayUtil.firstIndexOf(unsafes, c) >= 0)
if (src.current() == escapeChar) { return 2;
src.next(); else {
if (preferUnicode && !isRegular(c))
if (src.isEnd()) return 6;
throw new EscapeException("Incomplete escape sequence at the end"); else
return 1;
if (src.current() == escapeChar) { }
src.next(); }
return escapeChar;
} /*
* Logic - unescape
if (src.current() == unicodeEscapeChar) { */
src.next();
return (char) ( public void unescape(CharReader src, int length, CharPredicate until, CharConsumer output) throws EscapeException {
hexValue(src.consume()) << (4 * 3) | int end;
hexValue(src.consume()) << (4 * 2) | if (length < 0)
hexValue(src.consume()) << (4 * 1) | end = Integer.MAX_VALUE;
hexValue(src.consume()) << (4 * 0) else
); end = src.getPosition() + length;
} while (
src.has() &&
int index = ArrayUtil.firstIndexOf(safes, src.current()); src.getPosition() < end &&
if (index >= 0) { (until == null || !until.test(src.current()))
src.next(); ) {
return unsafes[index]; output.accept(unescapeOneSequence(src));
} }
}
if (strict)
throw new EscapeException("Unknown escape sequence \"" + escapeChar + src.current() + "\""); public char unescapeOneSequence(CharReader src) throws EscapeException {
else int resetPos = src.getPosition();
return src.consume(); try {
} else if (src.current() == escapeChar) {
return src.consume(); src.next();
} catch (EscapeException | RuntimeException e) {
src.setPosition(resetPos); if (src.isEnd())
throw e; throw new EscapeException("Incomplete escape sequence at the end");
}
} if (src.current() == escapeChar) {
src.next();
public int getUnescapedLength(CharReader src, int length, CharPredicate until) { return escapeChar;
int end; }
if (length < 0) end = Integer.MAX_VALUE;
else end = src.getPosition() + length; if (src.current() == unicodeEscapeChar) {
src.next();
int result = 0; return (char) (hexValue(src.consume()) << (4 * 3) |
hexValue(src.consume()) << (4 * 2) |
while (src.has() && hexValue(src.consume()) << (4 * 1) |
src.getPosition() < end && hexValue(src.consume()) << (4 * 0));
(until == null || !until.test(src.current()))) { }
skipOneSequence(src);
result++; int index = ArrayUtil.firstIndexOf(safes, src.current());
} if (index >= 0) {
src.next();
return result; return unsafes[index];
} }
public void skipOneSequence(CharReader src) { if (strict)
if ( throw new EscapeException("Unknown escape sequence \"" + escapeChar + src.current() + "\"");
src.current() == escapeChar else
&& return src.consume();
src.next() == unicodeEscapeChar } else
) { return src.consume();
src.advance(4); } catch (EscapeException | RuntimeException e) {
} src.setPosition(resetPos);
src.next(); throw e;
} }
}
/*
* Utility public int getUnescapedLength(CharReader src, int length, CharPredicate until) {
*/ int end;
if (length < 0)
public void escape(CharReader src, int length, CharConsumer output) { end = Integer.MAX_VALUE;
escape(src, length, null, output); else
} end = src.getPosition() + length;
public void escape(CharReader src, CharPredicate until, CharConsumer output) { int result = 0;
escape(src, -1, until, output);
} while (
src.has() &&
public void escape(CharReader src, CharConsumer output) { src.getPosition() < end &&
escape(src, -1, null, output); (until == null || !until.test(src.current()))
} ) {
skipOneSequence(src);
public int getEscapedLength(CharReader src, int length) { result++;
return getEscapedLength(src, length, null); }
}
return result;
public int getEscapedLength(CharReader src, CharPredicate until) { }
return getEscapedLength(src, -1, until);
} public void skipOneSequence(CharReader src) {
if (
public int getEscapedLength(CharReader src) { src.current() == escapeChar
return getEscapedLength(src, -1, null); &&
} src.next() == unicodeEscapeChar
) {
public char[] escape(CharReader src, int length, CharPredicate until) { src.advance(4);
src.mark(); }
char[] result = new char[getEscapedLength(src, length, until)]; src.next();
src.reset(); }
escape(src, length, until, CharConsumers.fillArray(result));
return result; /*
} * Utility
*/
public char[] escape(CharReader src, int length) {
return escape(src, length, (CharPredicate) null); public void escape(CharReader src, int length, CharConsumer output) {
} escape(src, length, null, output);
}
public char[] escape(CharReader src, CharPredicate until) {
return escape(src, -1, until); public void escape(CharReader src, CharPredicate until, CharConsumer output) {
} escape(src, -1, until, output);
}
public char[] escape(CharReader src) {
return escape(src, -1, (CharPredicate) null); public void escape(CharReader src, CharConsumer output) {
} escape(src, -1, null, output);
}
public void unescape(CharReader src, int length, CharConsumer output) throws EscapeException {
unescape(src, length, null, output); public int getEscapedLength(CharReader src, int length) {
} return getEscapedLength(src, length, null);
}
public void unescape(CharReader src, CharPredicate until, CharConsumer output) throws EscapeException {
unescape(src, -1, until, output); public int getEscapedLength(CharReader src, CharPredicate until) {
} return getEscapedLength(src, -1, until);
}
public void unescape(CharReader src, CharConsumer output) throws EscapeException {
unescape(src, -1, null, output); public int getEscapedLength(CharReader src) {
} return getEscapedLength(src, -1, null);
}
public int getUnescapedLength(CharReader src, int length) {
return getUnescapedLength(src, length, null); public char[] escape(CharReader src, int length, CharPredicate until) {
} src.mark();
char[] result = new char[getEscapedLength(src, length, until)];
public int getUnescapedLength(CharReader src, CharPredicate until) { src.reset();
return getUnescapedLength(src, -1, until); escape(src, length, until, CharConsumers.fillArray(result));
} return result;
}
public int getUnescapedLength(CharReader src) {
return getUnescapedLength(src, -1, null); public char[] escape(CharReader src, int length) {
} return escape(src, length, (CharPredicate) null);
}
public char[] unescape(CharReader src, int length, CharPredicate until) throws EscapeException {
src.mark(); public char[] escape(CharReader src, CharPredicate until) {
char[] result = new char[getUnescapedLength(src, length, until)]; return escape(src, -1, until);
src.reset(); }
unescape(src, length, until, CharConsumers.fillArray(result));
return result; public char[] escape(CharReader src) {
} return escape(src, -1, (CharPredicate) null);
}
public char[] unescape(CharReader src, int length) throws EscapeException {
return unescape(src, length, (CharPredicate) null); public void unescape(CharReader src, int length, CharConsumer output) throws EscapeException {
} unescape(src, length, null, output);
}
public char[] unescape(CharReader src, CharPredicate until) throws EscapeException {
return unescape(src, -1, until); public void unescape(CharReader src, CharPredicate until, CharConsumer output) throws EscapeException {
} unescape(src, -1, until, output);
}
public char[] unescape(CharReader src) throws EscapeException {
return unescape(src, -1, (CharPredicate) null); public void unescape(CharReader src, CharConsumer output) throws EscapeException {
} unescape(src, -1, null, output);
}
@Deprecated()
public char[] unescape(CharacterIterator src, char until) throws EscapeException { public int getUnescapedLength(CharReader src, int length) {
int index = src.getIndex(); return getUnescapedLength(src, length, null);
CharReader reader = CharReaders.wrap(src); }
char[] result = unescape(reader, -1, CharPredicate.forChar(until)); public int getUnescapedLength(CharReader src, CharPredicate until) {
return getUnescapedLength(src, -1, until);
src.setIndex(index + reader.getPosition()); }
return result;
} public int getUnescapedLength(CharReader src) {
return getUnescapedLength(src, -1, null);
public String escape(String src) { }
StringBuilder result = new StringBuilder(src.length());
escape(CharReaders.wrap(src), (CharConsumer) result::append); public char[] unescape(CharReader src, int length, CharPredicate until) throws EscapeException {
return result.toString(); src.mark();
} char[] result = new char[getUnescapedLength(src, length, until)];
src.reset();
public String unescape(String src) throws EscapeException { unescape(src, length, until, CharConsumers.fillArray(result));
StringBuilder result = new StringBuilder(src.length()); return result;
unescape(CharReaders.wrap(src), (CharConsumer) result::append); }
return result.toString();
} public char[] unescape(CharReader src, int length) throws EscapeException {
return unescape(src, length, (CharPredicate) null);
/* }
* Misc
*/ public char[] unescape(CharReader src, CharPredicate until) throws EscapeException {
return unescape(src, -1, until);
private static int hexValue(char c) throws EscapeException { }
if (c < '0') throw thisIsNotAHexDigit(c);
if (c <= '9') return c - '0'; public char[] unescape(CharReader src) throws EscapeException {
if (c < 'A') throw thisIsNotAHexDigit(c); return unescape(src, -1, (CharPredicate) null);
if (c <= 'F') return c - 'A'; }
if (c < 'a') throw thisIsNotAHexDigit(c);
if (c <= 'f') return c - 'a'; @Deprecated()
if (c == CharReader.DONE) throw new EscapeException("Incomplete Unicode escape sequence at the end"); public char[] unescape(CharacterIterator src, char until) throws EscapeException {
throw thisIsNotAHexDigit(c); int index = src.getIndex();
} CharReader reader = CharReaders.wrap(src);
private static EscapeException thisIsNotAHexDigit(char c) { char[] result = unescape(reader, -1, CharPredicate.forChar(until));
return new EscapeException("Invalid hex digit '" + c + "', expected [0-9A-Fa-f]");
} src.setIndex(index + reader.getPosition());
return result;
protected static boolean isRegular(char c) { }
return c >= ' ' && c <= '~';
} public String escape(String src) {
StringBuilder result = new StringBuilder(src.length());
/* escape(CharReaders.wrap(src), (CharConsumer) result::append);
* Getters / setters return result.toString();
*/ }
public char getEscapeChar() { public String unescape(String src) throws EscapeException {
return escapeChar; StringBuilder result = new StringBuilder(src.length());
} unescape(CharReaders.wrap(src), (CharConsumer) result::append);
return result.toString();
public char getUnicodeEscapeChar() { }
return unicodeEscapeChar;
} /*
* Misc
public char[] getSafes() { */
return safes;
} private static int hexValue(char c) throws EscapeException {
if (c < '0')
public char[] getUnsafes() { throw thisIsNotAHexDigit(c);
return unsafes; if (c <= '9')
} return c - '0';
if (c < 'A')
public boolean isPreferUnicode() { throw thisIsNotAHexDigit(c);
return preferUnicode; if (c <= 'F')
} return c - 'A';
if (c < 'a')
public boolean isStrict() { throw thisIsNotAHexDigit(c);
return strict; if (c <= 'f')
} return c - 'a';
if (c == CharReader.DONE)
} throw new EscapeException("Incomplete Unicode escape sequence at the end");
throw thisIsNotAHexDigit(c);
}
private static EscapeException thisIsNotAHexDigit(char c) {
return new EscapeException("Invalid hex digit '" + c + "', expected [0-9A-Fa-f]");
}
protected static boolean isRegular(char c) {
return c >= ' ' && c <= '~';
}
/*
* Getters / setters
*/
public char getEscapeChar() {
return escapeChar;
}
public char getUnicodeEscapeChar() {
return unicodeEscapeChar;
}
public char[] getSafes() {
return safes;
}
public char[] getUnsafes() {
return unsafes;
}
public boolean isPreferUnicode() {
return preferUnicode;
}
public boolean isStrict() {
return strict;
}
}

View File

@ -1,17 +1,21 @@
/* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package ru.windcorp.jputil.chars; package ru.windcorp.jputil.chars;
import java.text.CharacterIterator; import java.text.CharacterIterator;
@ -26,77 +30,81 @@ public class FancyCharacterIterator implements CharacterIterator {
this.data = data; this.data = data;
} }
@Override @Override
public char first() { public char first() {
return obj.first(); return obj.first();
} }
@Override @Override
public char last() { public char last() {
return obj.last(); return obj.last();
} }
@Override @Override
public char setIndex(int p) { public char setIndex(int p) {
return obj.setIndex(p); return obj.setIndex(p);
} }
@Override @Override
public char current() { public char current() {
return obj.current(); return obj.current();
} }
@Override @Override
public char next() { public char next() {
return obj.next(); return obj.next();
} }
@Override @Override
public char previous() { public char previous() {
return obj.previous(); return obj.previous();
} }
@Override @Override
public int getBeginIndex() { public int getBeginIndex() {
return obj.getBeginIndex(); return obj.getBeginIndex();
} }
@Override @Override
public int getEndIndex() { public int getEndIndex() {
return obj.getEndIndex(); return obj.getEndIndex();
} }
@Override @Override
public int getIndex() { public int getIndex() {
return obj.getIndex(); return obj.getIndex();
} }
@Override @Override
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder("\""); StringBuilder sb = new StringBuilder("\"");
sb.append(data); sb.append(data);
sb.append("\"\n "); sb.append("\"\n ");
for (int i = 0; i < obj.getIndex(); ++i) sb.append(' '); for (int i = 0; i < obj.getIndex(); ++i)
sb.append(' ');
sb.append("^ Here."); sb.append("^ Here.");
return sb.toString(); return sb.toString();
} }
// @SuppressWarnings("all") Just STFU, this _is_ terrific
// SonarLint: "clone" should not be overridden (java:S2975)
// And I wouldn't have done that if only CharacterIterator had not required exception safety.
// SonarLint: "toString()" and "clone()" methods should not return null (java:S2225)
// The clause is unreachable: CharacterArrayIterator implements Cloneable and superclass is Object.
@SuppressWarnings({"squid:S2975", "squid:S2225"})
@Override
public FancyCharacterIterator clone() {
try {
return (FancyCharacterIterator) super.clone();
} catch (CloneNotSupportedException cnse) {
// Impossible
return null;
}
}
} // @SuppressWarnings("all") Just STFU, this _is_ terrific
// SonarLint: "clone" should not be overridden (java:S2975)
// And I wouldn't have done that if only CharacterIterator had not required
// exception safety.
// SonarLint: "toString()" and "clone()" methods should not return null
// (java:S2225)
// The clause is unreachable: CharacterArrayIterator implements Cloneable
// and superclass is Object.
@SuppressWarnings({ "squid:S2975", "squid:S2225" })
@Override
public FancyCharacterIterator clone() {
try {
return (FancyCharacterIterator) super.clone();
} catch (CloneNotSupportedException cnse) {
// Impossible
return null;
}
}
}

View File

@ -1,135 +1,138 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars;
package ru.windcorp.jputil.chars;
public class IndentedStringBuilder {
public class IndentedStringBuilder {
private final StringBuilder sb = new StringBuilder();
private final StringBuilder sb = new StringBuilder();
private int indentLevel = 0;
private boolean indentApplied = false; private int indentLevel = 0;
private boolean indentApplied = false;
private String[] indentCache = new String[16];
private String indent = ""; private String[] indentCache = new String[16];
private final char[] indentFill; private String indent = "";
private final char[] indentFill;
public IndentedStringBuilder(char[] indentFill) {
this.indentFill = indentFill; public IndentedStringBuilder(char[] indentFill) {
} this.indentFill = indentFill;
}
public IndentedStringBuilder(String indentFill) {
this(indentFill.toCharArray()); public IndentedStringBuilder(String indentFill) {
} this(indentFill.toCharArray());
}
public IndentedStringBuilder(char indentChar, int length) {
this(StringUtil.sequence(indentChar, length)); public IndentedStringBuilder(char indentChar, int length) {
} this(StringUtil.sequence(indentChar, length));
}
public IndentedStringBuilder() {
this(new char[] {' '}); public IndentedStringBuilder() {
} this(new char[] { ' ' });
}
@Override
public String toString() { @Override
return sb.toString(); public String toString() {
} return sb.toString();
}
public int getIndentLevel() {
return indentLevel; public int getIndentLevel() {
} return indentLevel;
}
public void setIndentLevel(int level) {
this.indentLevel = level; public void setIndentLevel(int level) {
updateIndent(); this.indentLevel = level;
} updateIndent();
}
public char[] getIndentFill() {
return indentFill; public char[] getIndentFill() {
} return indentFill;
}
protected void updateIndent() {
if (indentLevel < indentCache.length) { protected void updateIndent() {
indent = indentCache[indentLevel]; if (indentLevel < indentCache.length) {
if (indent != null) return; indent = indentCache[indentLevel];
} if (indent != null)
return;
char[] fill = getIndentFill(); }
char[] array = new char[fill.length * getIndentLevel()];
for (int i = 0; i < array.length; i += fill.length) char[] fill = getIndentFill();
System.arraycopy(fill, 0, array, i, fill.length); char[] array = new char[fill.length * getIndentLevel()];
indent = new String(array); for (int i = 0; i < array.length; i += fill.length)
System.arraycopy(fill, 0, array, i, fill.length);
if (indentLevel < indentCache.length) { indent = new String(array);
indentCache[indentLevel] = indent;
} if (indentLevel < indentCache.length) {
} indentCache[indentLevel] = indent;
}
public IndentedStringBuilder indent() { }
setIndentLevel(getIndentLevel() + 1);
return this; public IndentedStringBuilder indent() {
} setIndentLevel(getIndentLevel() + 1);
return this;
public IndentedStringBuilder unindent() { }
setIndentLevel(getIndentLevel() - 1);
return this; public IndentedStringBuilder unindent() {
} setIndentLevel(getIndentLevel() - 1);
return this;
public IndentedStringBuilder append(Object x) { }
if (x == null) {
appendRaw("null"); public IndentedStringBuilder append(Object x) {
return this; if (x == null) {
} appendRaw("null");
return this;
String str = x.toString(); }
int newLines = StringUtil.count(str, '\n');
String str = x.toString();
if (newLines == 0) { int newLines = StringUtil.count(str, '\n');
appendRaw(str);
return this; if (newLines == 0) {
} appendRaw(str);
return this;
String[] lines = StringUtil.split(str, '\n', newLines + 1); }
appendRaw(lines[0]);
String[] lines = StringUtil.split(str, '\n', newLines + 1);
for (int i = 1; i < lines.length; ++i) { appendRaw(lines[0]);
newLine();
appendRaw(lines[i]); for (int i = 1; i < lines.length; ++i) {
} newLine();
appendRaw(lines[i]);
return this; }
}
return this;
public IndentedStringBuilder appendRaw(String str) { }
if (str.isEmpty()) return this; // Do not append indent
public IndentedStringBuilder appendRaw(String str) {
if (!indentApplied) { if (str.isEmpty())
sb.append(indent); return this; // Do not append indent
indentApplied = true;
} if (!indentApplied) {
sb.append(indent);
sb.append(str); indentApplied = true;
return this; }
}
sb.append(str);
public IndentedStringBuilder newLine() { return this;
sb.append('\n'); }
indentApplied = false;
return this; public IndentedStringBuilder newLine() {
} sb.append('\n');
indentApplied = false;
} return this;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +1,38 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars;
package ru.windcorp.jputil.chars;
public class UncheckedEscapeException extends RuntimeException {
public class UncheckedEscapeException extends RuntimeException {
private static final long serialVersionUID = 5392628641744570926L;
private static final long serialVersionUID = 5392628641744570926L;
public UncheckedEscapeException(String message, EscapeException cause) {
super(message, cause); public UncheckedEscapeException(String message, EscapeException cause) {
} super(message, cause);
}
public UncheckedEscapeException(EscapeException cause) {
super(cause); public UncheckedEscapeException(EscapeException cause) {
} super(cause);
}
@Override
public synchronized EscapeException getCause() { @Override
return (EscapeException) super.getCause(); public synchronized EscapeException getCause() {
} return (EscapeException) super.getCause();
}
}
}

View File

@ -1,139 +1,143 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars;
package ru.windcorp.jputil.chars;
import java.io.IOException;
import java.io.Reader; import java.io.IOException;
import java.nio.CharBuffer; import java.io.Reader;
import java.util.Arrays; import java.nio.CharBuffer;
import java.util.Iterator; import java.util.Arrays;
import java.util.NoSuchElementException; import java.util.Iterator;
import java.util.NoSuchElementException;
public class WordReader implements Iterator<String> {
public class WordReader implements Iterator<String> {
private final Reader reader;
private final Reader reader;
private char[] wordBuffer = new char[1024];
private final CharBuffer inputBuffer; private char[] wordBuffer = new char[1024];
private final CharBuffer inputBuffer;
private String next = null;
private boolean isExhausted = false; private String next = null;
private boolean isExhausted = false;
private IOException lastException = null;
private IOException lastException = null;
public WordReader(Reader src, int bufferSize) {
this.reader = src; public WordReader(Reader src, int bufferSize) {
this.inputBuffer = CharBuffer.allocate(bufferSize); this.reader = src;
} this.inputBuffer = CharBuffer.allocate(bufferSize);
}
public WordReader(Reader src) {
this(src, 2048); public WordReader(Reader src) {
} this(src, 2048);
}
public WordReader(char[] array, int offset, int length) {
this.reader = null; public WordReader(char[] array, int offset, int length) {
this.inputBuffer = CharBuffer.wrap(Arrays.copyOfRange(array, offset, length + offset)); this.reader = null;
} this.inputBuffer = CharBuffer.wrap(Arrays.copyOfRange(array, offset, length + offset));
}
public WordReader(char[] array) {
this.reader = null; public WordReader(char[] array) {
this.inputBuffer = CharBuffer.wrap(array); this.reader = null;
} this.inputBuffer = CharBuffer.wrap(array);
}
public WordReader(String str) {
this(str.toCharArray()); public WordReader(String str) {
} this(str.toCharArray());
}
@Override
public String next() { @Override
if (!hasNext()) { public String next() {
throw new NoSuchElementException(); if (!hasNext()) {
} throw new NoSuchElementException();
}
String result = next;
next = null; String result = next;
return result; next = null;
} return result;
}
@Override
public boolean hasNext() { @Override
if (next != null) { public boolean hasNext() {
return true; if (next != null) {
} return true;
}
if (isExhausted) {
return false; if (isExhausted) {
} return false;
}
int length = 0;
char c; int length = 0;
while (true) { char c;
c = nextChar(); while (true) {
c = nextChar();
if (isExhausted) break;
if (isExhausted)
if (Character.isWhitespace(c)) { break;
if (length == 0) continue;
else break; if (Character.isWhitespace(c)) {
} if (length == 0)
continue;
if (wordBuffer.length == length) { else
char[] newBuf = new char[wordBuffer.length * 2]; break;
System.arraycopy(wordBuffer, 0, newBuf, 0, wordBuffer.length); }
wordBuffer = newBuf;
} if (wordBuffer.length == length) {
char[] newBuf = new char[wordBuffer.length * 2];
wordBuffer[length++] = c; System.arraycopy(wordBuffer, 0, newBuf, 0, wordBuffer.length);
} wordBuffer = newBuf;
}
if (length == 0) {
return false; wordBuffer[length++] = c;
} }
next = new String(wordBuffer, 0, length); if (length == 0) {
return true; return false;
} }
private char nextChar() { next = new String(wordBuffer, 0, length);
if (!inputBuffer.hasRemaining()) { return true;
if (reader == null) { }
isExhausted = true;
return 0; private char nextChar() {
} if (!inputBuffer.hasRemaining()) {
if (reader == null) {
inputBuffer.rewind(); isExhausted = true;
try { return 0;
if (reader.read(inputBuffer) == -1) { }
isExhausted = true;
} inputBuffer.rewind();
} catch (IOException e) { try {
lastException = e; if (reader.read(inputBuffer) == -1) {
isExhausted = true; isExhausted = true;
return 0; }
} } catch (IOException e) {
lastException = e;
} isExhausted = true;
return 0;
return inputBuffer.get(); }
}
}
public IOException getLastException() {
return lastException; return inputBuffer.get();
} }
} public IOException getLastException() {
return lastException;
}
}

View File

@ -1,104 +1,108 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars.reader;
package ru.windcorp.jputil.chars.reader;
/**
* @author Javapony /**
* * @author Javapony
*/ */
public abstract class AbstractCharReader implements CharReader { public abstract class AbstractCharReader implements CharReader {
protected static final int DEFAULT_MARK_STACK_SIZE = 8; protected static final int DEFAULT_MARK_STACK_SIZE = 8;
/** /**
* Current position of this CharReader. The reader maps its input to positions starting from 0. * Current position of this CharReader. The reader maps its input to
* Positions that are negative or lower than 0 are invalid. {@link #current()} * positions starting from 0.
* will throw an exception if position is invalid. * Positions that are negative or lower than 0 are invalid.
*/ * {@link #current()}
protected int position = 0; * will throw an exception if position is invalid.
*/
private int[] marks = new int[DEFAULT_MARK_STACK_SIZE]; protected int position = 0;
private int nextMark = 0;
private int[] marks = new int[DEFAULT_MARK_STACK_SIZE];
protected static int closestGreaterPowerOf2(int x) { private int nextMark = 0;
x |= x >> 1;
x |= x >> 2; protected static int closestGreaterPowerOf2(int x) {
x |= x >> 4; x |= x >> 1;
x |= x >> 8; x |= x >> 2;
x |= x >> 16; x |= x >> 4;
return x + 1; x |= x >> 8;
} x |= x >> 16;
return x + 1;
/** }
* @see ru.windcorp.jputil.chars.reader.CharReader#getPosition()
*/ /**
@Override * @see ru.windcorp.jputil.chars.reader.CharReader#getPosition()
public int getPosition() { */
return position; @Override
} public int getPosition() {
return position;
/** }
* @see ru.windcorp.jputil.chars.reader.CharReader#setPosition(int)
*/ /**
@Override * @see ru.windcorp.jputil.chars.reader.CharReader#setPosition(int)
public int setPosition(int position) { */
this.position = position; @Override
return position; public int setPosition(int position) {
} this.position = position;
return position;
/** }
* @see ru.windcorp.jputil.chars.reader.CharReader#mark()
*/ /**
@Override * @see ru.windcorp.jputil.chars.reader.CharReader#mark()
public int mark() { */
ensureMarksCapacity(); @Override
marks[nextMark++] = position; public int mark() {
return position; ensureMarksCapacity();
} marks[nextMark++] = position;
return position;
/** }
* @see ru.windcorp.jputil.chars.reader.CharReader#forget()
*/ /**
@Override * @see ru.windcorp.jputil.chars.reader.CharReader#forget()
public int forget() { */
return marks[--nextMark]; @Override
} public int forget() {
return marks[--nextMark];
private void ensureMarksCapacity() { }
if (nextMark < marks.length) return;
int[] newMarks = new int[closestGreaterPowerOf2(nextMark)]; private void ensureMarksCapacity() {
System.arraycopy(marks, 0, newMarks, 0, nextMark); if (nextMark < marks.length)
marks = newMarks; return;
} int[] newMarks = new int[closestGreaterPowerOf2(nextMark)];
System.arraycopy(marks, 0, newMarks, 0, nextMark);
@Override marks = newMarks;
public String toString() { }
StringBuilder sb = new StringBuilder("\"");
@Override
mark(); public String toString() {
position = 0; StringBuilder sb = new StringBuilder("\"");
sb.append(getChars());
reset(); mark();
position = 0;
sb.append("\"\n "); sb.append(getChars());
for (int i = 0; i < position; ++i) sb.append(' '); reset();
sb.append("^ (pos " + position + ")");
return sb.toString(); sb.append("\"\n ");
} for (int i = 0; i < position; ++i)
sb.append(' ');
} sb.append("^ (pos " + position + ")");
return sb.toString();
}
}

View File

@ -1,59 +1,60 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars.reader;
package ru.windcorp.jputil.chars.reader;
import java.util.Objects;
import java.util.Objects;
import ru.windcorp.jputil.ArrayUtil;
import ru.windcorp.jputil.ArrayUtil;
/**
* @author Javapony /**
* * @author Javapony
*/ */
public class ArrayCharReader extends AbstractCharReader { public class ArrayCharReader extends AbstractCharReader {
private final char[] array; private final char[] array;
private final int offset; private final int offset;
private final int length; private final int length;
public ArrayCharReader(char[] array, int offset, int length) { public ArrayCharReader(char[] array, int offset, int length) {
this.array = Objects.requireNonNull(array, "array"); this.array = Objects.requireNonNull(array, "array");
this.length = ArrayUtil.checkArrayOffsetLength(array, offset, length); this.length = ArrayUtil.checkArrayOffsetLength(array, offset, length);
this.offset = offset; this.offset = offset;
} }
/** /**
* @see ru.windcorp.jputil.chars.reader.CharReader#current() * @see ru.windcorp.jputil.chars.reader.CharReader#current()
*/ */
@Override @Override
public char current() { public char current() {
if (position >= length) return DONE; if (position >= length)
if (position < 0) return DONE;
throw new IllegalStateException("Position " + position + " is invalid"); if (position < 0)
return array[position + offset]; throw new IllegalStateException("Position " + position + " is invalid");
} return array[position + offset];
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#remaining() /**
*/ * @see ru.windcorp.jputil.chars.reader.CharReader#remaining()
@Override */
public int remaining() { @Override
return length - position; public int remaining() {
} return length - position;
}
}
}

View File

@ -1,122 +1,128 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars.reader;
package ru.windcorp.jputil.chars.reader;
/**
* @author Javapony /**
* * @author Javapony
*/ */
public abstract class BufferedCharReader extends AbstractCharReader { public abstract class BufferedCharReader extends AbstractCharReader {
protected static final int DEFAULT_BUFFER_SIZE = 256; protected static final int DEFAULT_BUFFER_SIZE = 256;
/** /**
* Buffer to store data acquired with {@link #pullChars(char[], int, int)}. * Buffer to store data acquired with {@link #pullChars(char[], int, int)}.
* Contains characters for positions <code>[0; bufferNextIndex)</code>. * Contains characters for positions <code>[0; bufferNextIndex)</code>.
*/ */
private char[] buffer = new char[DEFAULT_BUFFER_SIZE]; private char[] buffer = new char[DEFAULT_BUFFER_SIZE];
/** /**
* The index of the next character. * The index of the next character.
*/ */
private int bufferNextIndex = 0; private int bufferNextIndex = 0;
/** /**
* Whether this reader has been buffered completely. * Whether this reader has been buffered completely.
*/ */
private boolean exhausted = false; private boolean exhausted = false;
/** /**
* Acquires the next character. * Acquires the next character.
* @return the character or {@link #DONE} if the end of the reader has been reached *
*/ * @return the character or {@link #DONE} if the end of the reader has been
protected abstract char pullChar(); * reached
*/
/** protected abstract char pullChar();
* Acquires next characters and stores them in the array.
* /**
* @param buffer the output array * Acquires next characters and stores them in the array.
* @param offset index of the first character *
* @param length maximum amount of characters to be pulled * @param buffer the output array
* @return the amount of characters actually pulled * @param offset index of the first character
*/ * @param length maximum amount of characters to be pulled
protected int pullChars(char[] buffer, int offset, int length) { * @return the amount of characters actually pulled
for (int i = 0; i < length; ++i) { */
if ((buffer[offset + i] = pullChar()) == DONE) { protected int pullChars(char[] buffer, int offset, int length) {
return i; for (int i = 0; i < length; ++i) {
} if ((buffer[offset + i] = pullChar()) == DONE) {
} return i;
}
return length; }
}
return length;
private int pullChars(int offset, int length) { }
if (exhausted || length == 0) return 0;
private int pullChars(int offset, int length) {
int pulled = pullChars(buffer, offset, length); if (exhausted || length == 0)
if (pulled != length) { return 0;
exhausted = true;
} int pulled = pullChars(buffer, offset, length);
if (pulled != length) {
return pulled; exhausted = true;
} }
@Override return pulled;
public char current() { }
if (getPosition() < 0) {
throw new IllegalStateException("Position " + getPosition() + " is invalid"); @Override
} public char current() {
if (getPosition() < 0) {
if (getPosition() >= bufferNextIndex) { throw new IllegalStateException("Position " + getPosition() + " is invalid");
if (exhausted) return DONE; }
ensureBufferCapacity(); if (getPosition() >= bufferNextIndex) {
if (exhausted)
int needToPull = getPosition() - bufferNextIndex + 1; return DONE;
assert needToPull <= buffer.length : "buffer size not ensured!";
ensureBufferCapacity();
int pulled = pullChars(bufferNextIndex, needToPull);
bufferNextIndex += pulled; int needToPull = getPosition() - bufferNextIndex + 1;
assert needToPull <= buffer.length : "buffer size not ensured!";
if (exhausted) return DONE;
} int pulled = pullChars(bufferNextIndex, needToPull);
bufferNextIndex += pulled;
// TODO test the shit out of current()
if (exhausted)
return buffer[getPosition()]; return DONE;
} }
private void ensureBufferCapacity() { // TODO test the shit out of current()
if (getPosition() < buffer.length) return;
char[] newBuffer = new char[closestGreaterPowerOf2(getPosition())]; return buffer[getPosition()];
System.arraycopy(buffer, 0, newBuffer, 0, bufferNextIndex); }
buffer = newBuffer;
} private void ensureBufferCapacity() {
if (getPosition() < buffer.length)
/** return;
* @see ru.windcorp.jputil.chars.reader.CharReader#remaining() char[] newBuffer = new char[closestGreaterPowerOf2(getPosition())];
*/ System.arraycopy(buffer, 0, newBuffer, 0, bufferNextIndex);
@Override buffer = newBuffer;
public int remaining() { }
if (exhausted) {
return Math.max(bufferNextIndex - getPosition(), 0); /**
} * @see ru.windcorp.jputil.chars.reader.CharReader#remaining()
*/
return super.remaining(); @Override
} public int remaining() {
if (exhausted) {
} return Math.max(bufferNextIndex - getPosition(), 0);
}
return super.remaining();
}
}

View File

@ -1,270 +1,284 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars.reader;
package ru.windcorp.jputil.chars.reader;
import java.io.IOException;
import java.util.Arrays; import java.io.IOException;
import java.util.Arrays;
import ru.windcorp.jputil.chars.CharPredicate;
import ru.windcorp.jputil.chars.EscapeException; import ru.windcorp.jputil.chars.CharPredicate;
import ru.windcorp.jputil.chars.Escaper; import ru.windcorp.jputil.chars.EscapeException;
import ru.windcorp.jputil.chars.Escaper;
/**
* @author Javapony /**
* * @author Javapony
*/ */
// SonarLint: Constants should not be defined in interfaces (java:S1214) // SonarLint: Constants should not be defined in interfaces (java:S1214)
// DONE is an essential part of the interface // DONE is an essential part of the interface
@SuppressWarnings("squid:S1214") @SuppressWarnings("squid:S1214")
public interface CharReader { public interface CharReader {
char DONE = '\uFFFF'; char DONE = '\uFFFF';
char current(); char current();
int getPosition();
int setPosition(int position); int getPosition();
default char next() { int setPosition(int position);
return advance(1);
} default char next() {
return advance(1);
default char previous() { }
return rollBack(1);
} default char previous() {
return rollBack(1);
default char consume() { }
char c = current();
advance(1); default char consume() {
return c; char c = current();
} advance(1);
return c;
default char advance(int forward) { }
setPosition(getPosition() + forward);
return current(); default char advance(int forward) {
} setPosition(getPosition() + forward);
return current();
default char rollBack(int backward) { }
return advance(-backward);
} default char rollBack(int backward) {
return advance(-backward);
default boolean isEnd() { }
return current() == DONE;
} default boolean isEnd() {
return current() == DONE;
default boolean has() { }
return current() != DONE;
} default boolean has() {
return current() != DONE;
default boolean is(char c) { }
return current() == c;
} default boolean is(char c) {
return current() == c;
default int getChars(char[] output, int offset, int length) { }
for (int i = 0; i < length; ++i) {
if ((output[offset + i] = current()) == DONE) { default int getChars(char[] output, int offset, int length) {
return i; for (int i = 0; i < length; ++i) {
} if ((output[offset + i] = current()) == DONE) {
next(); return i;
} }
next();
return length; }
}
return length;
default int getChars(char[] output) { }
return getChars(output, 0, output.length);
} default int getChars(char[] output) {
return getChars(output, 0, output.length);
default char[] getChars(int length) { }
char[] result = new char[length];
int from = getChars(result); default char[] getChars(int length) {
if (from != length) Arrays.fill(result, from, length, DONE); char[] result = new char[length];
return result; int from = getChars(result);
} if (from != length)
Arrays.fill(result, from, length, DONE);
default char[] getChars() { return result;
return getChars(remaining()); }
}
default char[] getChars() {
default String getString(int length) { return getChars(remaining());
StringBuilder sb = new StringBuilder(); }
for (int i = 0; i < length && !isEnd(); ++i) sb.append(consume());
return sb.toString(); default String getString(int length) {
} StringBuilder sb = new StringBuilder();
for (int i = 0; i < length && !isEnd(); ++i)
default String getString() { sb.append(consume());
return getString(Integer.MAX_VALUE); return sb.toString();
} }
default boolean match(CharSequence seq) { default String getString() {
for (int i = 0; i < seq.length(); ++i) { return getString(Integer.MAX_VALUE);
if (isEnd()) return false; }
if (current() != seq.charAt(i)) return false;
next(); default boolean match(CharSequence seq) {
} for (int i = 0; i < seq.length(); ++i) {
if (isEnd())
return true; return false;
} if (current() != seq.charAt(i))
return false;
default boolean matchOrReset(CharSequence seq) { next();
mark(); }
if (match(seq)) {
forget(); return true;
return true; }
} else {
reset(); default boolean matchOrReset(CharSequence seq) {
return false; mark();
} if (match(seq)) {
} forget();
return true;
default boolean match(char[] array) { } else {
for (int i = 0; i < array.length; ++i) { reset();
if (isEnd()) return false; return false;
if (current() != array[i]) return false; }
next(); }
}
default boolean match(char[] array) {
return true; for (int i = 0; i < array.length; ++i) {
} if (isEnd())
return false;
default boolean matchOrReset(char[] array) { if (current() != array[i])
mark(); return false;
if (match(array)) { next();
forget(); }
return true;
} else { return true;
reset(); }
return false;
} default boolean matchOrReset(char[] array) {
} mark();
if (match(array)) {
default int skip(CharPredicate condition) { forget();
int i = 0; return true;
} else {
while (has() && condition.test(current())) { reset();
i++; return false;
next(); }
} }
return i; default int skip(CharPredicate condition) {
} int i = 0;
default int skipWhitespace() { while (has() && condition.test(current())) {
return skip(Character::isWhitespace); i++;
} next();
}
/**
* Skips to the end of the current line. Both <code>"\n"</code>, <code>"\r"</code> return i;
* and <code>"\r\n"</code> are considered line separators. }
* @return the amount of characters in the skipped line
*/ default int skipWhitespace() {
default int skipLine() { return skip(Character::isWhitespace);
int i = 0; }
while (!isEnd()) { /**
if (current() == '\r') { * Skips to the end of the current line. Both <code>"\n"</code>,
if (next() == '\n') { * <code>"\r"</code>
next(); * and <code>"\r\n"</code> are considered line separators.
} *
break; * @return the amount of characters in the skipped line
} else if (current() == '\n') { */
next(); default int skipLine() {
break; int i = 0;
}
while (!isEnd()) {
i++; if (current() == '\r') {
next(); if (next() == '\n') {
} next();
}
return i; break;
} } else if (current() == '\n') {
next();
default char[] readWhile(CharPredicate condition) { break;
return readUntil(CharPredicate.negate(condition)); }
}
i++;
default char[] readUntil(CharPredicate condition) { next();
mark(); }
int length = 0;
while (!isEnd() && !condition.test(current())) { return i;
length++; }
next();
} default char[] readWhile(CharPredicate condition) {
reset(); return readUntil(CharPredicate.negate(condition));
}
char[] result = new char[length];
for (int i = 0; i < length; ++i) result[i] = consume(); default char[] readUntil(CharPredicate condition) {
return result; mark();
} int length = 0;
while (!isEnd() && !condition.test(current())) {
default char[] readWord() { length++;
skipWhitespace(); next();
return readUntil(Character::isWhitespace); }
} reset();
default char[] readWord(Escaper escaper, char quotes) throws EscapeException { char[] result = new char[length];
skipWhitespace(); for (int i = 0; i < length; ++i)
result[i] = consume();
if (current() == quotes) { return result;
return escaper.unescape(this, quotes); }
} else {
return readWord(); default char[] readWord() {
} skipWhitespace();
} return readUntil(Character::isWhitespace);
}
default char[] readLine() {
mark(); default char[] readWord(Escaper escaper, char quotes) throws EscapeException {
int length = skipLine(); skipWhitespace();
reset();
if (current() == quotes) {
char[] result = new char[length]; return escaper.unescape(this, quotes);
for (int i = 0; i < result.length; ++i) result[i] = consume(); } else {
return result; return readWord();
} }
}
default int remaining() {
mark(); default char[] readLine() {
int result = 0; mark();
int length = skipLine();
while (consume() != DONE) result++; reset();
reset(); char[] result = new char[length];
return result; for (int i = 0; i < result.length; ++i)
} result[i] = consume();
return result;
int mark(); }
int forget();
default int remaining() {
default int reset() { mark();
return setPosition(forget()); int result = 0;
}
while (consume() != DONE)
default IOException getLastException() { result++;
return null;
} reset();
return result;
default void resetLastException() { }
// Do nothing
} int mark();
default boolean hasErrored() { int forget();
return getLastException() != null;
} default int reset() {
return setPosition(forget());
} }
default IOException getLastException() {
return null;
}
default void resetLastException() {
// Do nothing
}
default boolean hasErrored() {
return getLastException() != null;
}
}

View File

@ -1,112 +1,113 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars.reader;
package ru.windcorp.jputil.chars.reader;
import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStream;
import java.io.Reader; import java.io.InputStreamReader;
import java.nio.charset.Charset; import java.io.Reader;
import java.nio.charset.StandardCharsets; import java.nio.charset.Charset;
import java.text.CharacterIterator; import java.nio.charset.StandardCharsets;
import java.util.function.IntSupplier; import java.text.CharacterIterator;
import java.util.function.IntSupplier;
import ru.windcorp.jputil.chars.CharSupplier;
import ru.windcorp.jputil.chars.CharSupplier;
/**
* @author Javapony /**
* * @author Javapony
*/ */
public class CharReaders { public class CharReaders {
private CharReaders() {} private CharReaders() {
}
public static CharReader wrap(char[] array, int offset, int length) {
return new ArrayCharReader(array, offset, length); public static CharReader wrap(char[] array, int offset, int length) {
} return new ArrayCharReader(array, offset, length);
}
public static CharReader wrap(char[] array) {
return wrap(array, 0, array.length); public static CharReader wrap(char[] array) {
} return wrap(array, 0, array.length);
}
public static CharReader wrap(String str, int offset, int length) {
return new StringCharReader(str, offset, length); public static CharReader wrap(String str, int offset, int length) {
} return new StringCharReader(str, offset, length);
}
public static CharReader wrap(String str) {
return wrap(str, 0, str.length()); public static CharReader wrap(String str) {
} return wrap(str, 0, str.length());
}
public static CharReader wrap(CharSupplier supplier) {
return new BufferedCharReader() { public static CharReader wrap(CharSupplier supplier) {
@Override return new BufferedCharReader() {
protected char pullChar() { @Override
try { protected char pullChar() {
return supplier.getAsChar(); try {
} catch (Exception e) { return supplier.getAsChar();
return DONE; } catch (Exception e) {
} return DONE;
} }
}; }
} };
}
public static CharReader wrap(IntSupplier supplier) {
return new BufferedCharReader() { public static CharReader wrap(IntSupplier supplier) {
@Override return new BufferedCharReader() {
protected char pullChar() { @Override
try { protected char pullChar() {
int i = supplier.getAsInt(); try {
if (i < 0 || i > Character.MAX_VALUE) { int i = supplier.getAsInt();
return DONE; if (i < 0 || i > Character.MAX_VALUE) {
} else { return DONE;
return (char) i; } else {
} return (char) i;
} catch (Exception e) { }
return DONE; } catch (Exception e) {
} return DONE;
} }
}; }
} };
}
public static CharReader wrap(CharacterIterator it) {
return new BufferedCharReader() { public static CharReader wrap(CharacterIterator it) {
@Override return new BufferedCharReader() {
protected char pullChar() { @Override
char result = it.current(); protected char pullChar() {
it.next(); char result = it.current();
return result; it.next();
} return result;
}; }
} };
}
public static CharReader wrap(Reader reader) {
return new ReaderCharReader(reader); public static CharReader wrap(Reader reader) {
} return new ReaderCharReader(reader);
}
public static CharReader wrap(InputStream is, Charset charset) {
return wrap(new InputStreamReader(is, charset)); public static CharReader wrap(InputStream is, Charset charset) {
} return wrap(new InputStreamReader(is, charset));
}
public static CharReader wrapDefaultCS(InputStream is) {
return wrap(new InputStreamReader(is)); public static CharReader wrapDefaultCS(InputStream is) {
} return wrap(new InputStreamReader(is));
}
public static CharReader wrapUTF8(InputStream is) {
return wrap(new InputStreamReader(is, StandardCharsets.UTF_8)); public static CharReader wrapUTF8(InputStream is) {
} return wrap(new InputStreamReader(is, StandardCharsets.UTF_8));
}
}
}

View File

@ -1,70 +1,71 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars.reader;
package ru.windcorp.jputil.chars.reader;
import java.io.IOException;
import java.io.Reader; import java.io.IOException;
import java.io.Reader;
/**
* @author Javapony /**
* * @author Javapony
*/ */
public class ReaderCharReader extends BufferedCharReader { public class ReaderCharReader extends BufferedCharReader {
private final Reader src; private final Reader src;
private IOException lastException = null; private IOException lastException = null;
public ReaderCharReader(Reader src) { public ReaderCharReader(Reader src) {
this.src = src; this.src = src;
} }
/** /**
* @see ru.windcorp.jputil.chars.reader.BufferedCharReader#pullChar() * @see ru.windcorp.jputil.chars.reader.BufferedCharReader#pullChar()
*/ */
@Override @Override
protected char pullChar() { protected char pullChar() {
try { try {
return (char) src.read(); // Handles DONE correctly return (char) src.read(); // Handles DONE correctly
} catch (IOException e) { } catch (IOException e) {
lastException = e; lastException = e;
return DONE; return DONE;
} }
} }
/** /**
* @see ru.windcorp.jputil.chars.reader.BufferedCharReader#pullChars(char[], int, int) * @see ru.windcorp.jputil.chars.reader.BufferedCharReader#pullChars(char[],
*/ * int, int)
@Override */
protected int pullChars(char[] buffer, int offset, int length) { @Override
try { protected int pullChars(char[] buffer, int offset, int length) {
return src.read(buffer, offset, length); try {
} catch (IOException e) { return src.read(buffer, offset, length);
lastException = e; } catch (IOException e) {
return 0; lastException = e;
} return 0;
} }
}
/**
* @return the exception /**
*/ * @return the exception
@Override */
public IOException getLastException() { @Override
return lastException; public IOException getLastException() {
} return lastException;
}
}
}

View File

@ -1,65 +1,68 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.chars.reader;
package ru.windcorp.jputil.chars.reader;
import java.util.Objects;
import java.util.Objects;
/**
* @author Javapony /**
* * @author Javapony
*/ */
public class StringCharReader extends AbstractCharReader { public class StringCharReader extends AbstractCharReader {
private final String str; private final String str;
private final int offset; private final int offset;
private final int length; private final int length;
public StringCharReader(String str, int offset, int length) { public StringCharReader(String str, int offset, int length) {
this.str = Objects.requireNonNull(str, "str"); this.str = Objects.requireNonNull(str, "str");
if (length < 0) if (length < 0)
length = str.length(); length = str.length();
int end = offset + length; int end = offset + length;
if (end > str.length() || offset < 0) if (end > str.length() || offset < 0)
throw new IllegalArgumentException("String contains [0; " + str.length() + "), requested [" + offset + "; " + end + ")"); throw new IllegalArgumentException(
"String contains [0; " + str.length() + "), requested [" + offset + "; " + end + ")"
this.offset = offset; );
this.length = length;
} this.offset = offset;
this.length = length;
/** }
* @see ru.windcorp.jputil.chars.reader.CharReader#current()
*/ /**
@Override * @see ru.windcorp.jputil.chars.reader.CharReader#current()
public char current() { */
if (position >= length) return DONE; @Override
if (position < 0) public char current() {
throw new IllegalStateException("Position " + position + " is invalid"); if (position >= length)
return str.charAt(position + offset); return DONE;
} if (position < 0)
throw new IllegalStateException("Position " + position + " is invalid");
/** return str.charAt(position + offset);
* @see ru.windcorp.jputil.chars.reader.CharReader#remaining() }
*/
@Override /**
public int remaining() { * @see ru.windcorp.jputil.chars.reader.CharReader#remaining()
return length - position; */
} @Override
public int remaining() {
} return length - position;
}
}

View File

@ -1,8 +1,26 @@
package ru.windcorp.jputil.functions; /*
* JPUtil
@FunctionalInterface * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
public interface FloatSupplier { *
* This program is free software: you can redistribute it and/or modify
float getAsFloat(); * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
} * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.jputil.functions;
@FunctionalInterface
public interface FloatSupplier {
float getAsFloat();
}

View File

@ -1,72 +1,76 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.functions;
package ru.windcorp.jputil.functions;
import java.util.function.BiConsumer;
import java.util.function.BiConsumer;
@FunctionalInterface
public interface ThrowingBiConsumer<T, U, E extends Exception> { @FunctionalInterface
public interface ThrowingBiConsumer<T, U, E extends Exception> {
@FunctionalInterface
public static interface BiConsumerHandler<T, U, E extends Exception> { @FunctionalInterface
void handle(T t, U u, E e); public static interface BiConsumerHandler<T, U, E extends Exception> {
} void handle(T t, U u, E e);
}
void accept(T t, U u) throws E;
void accept(T t, U u) throws E;
@SuppressWarnings("unchecked")
default BiConsumer<T, U> withHandler(BiConsumerHandler<? super T, ? super U, ? super E> handler) { @SuppressWarnings("unchecked")
return (t, u) -> { default BiConsumer<T, U> withHandler(BiConsumerHandler<? super T, ? super U, ? super E> handler) {
try { return (t, u) -> {
accept(t, u); try {
} catch (RuntimeException e) { accept(t, u);
throw e; } catch (RuntimeException e) {
} catch (Exception e) { throw e;
handler.handle(t, u, (E) e); } catch (Exception e) {
} handler.handle(t, u, (E) e);
}; }
} };
}
public static <T, U, E extends Exception> ThrowingBiConsumer<T, U, E> concat(
ThrowingBiConsumer<? super T, ? super U, ? extends E> first, public static <T, U, E extends Exception> ThrowingBiConsumer<T, U, E> concat(
ThrowingBiConsumer<? super T, ? super U, ? extends E> second) { ThrowingBiConsumer<? super T, ? super U, ? extends E> first,
return (t, u) -> { ThrowingBiConsumer<? super T, ? super U, ? extends E> second
first.accept(t, u); ) {
second.accept(t, u); return (t, u) -> {
}; first.accept(t, u);
} second.accept(t, u);
};
public static <T, U, E extends Exception> ThrowingBiConsumer<T, U, E> concat( }
BiConsumer<? super T, ? super U> first,
ThrowingBiConsumer<? super T, ? super U, E> second) { public static <T, U, E extends Exception> ThrowingBiConsumer<T, U, E> concat(
return (t, u) -> { BiConsumer<? super T, ? super U> first,
first.accept(t, u); ThrowingBiConsumer<? super T, ? super U, E> second
second.accept(t, u); ) {
}; return (t, u) -> {
} first.accept(t, u);
second.accept(t, u);
public static <T, U, E extends Exception> ThrowingBiConsumer<T, U, E> concat( };
ThrowingBiConsumer<? super T, ? super U, E> first, }
BiConsumer<? super T, ? super U> second) {
return (t, u) -> { public static <T, U, E extends Exception> ThrowingBiConsumer<T, U, E> concat(
first.accept(t, u); ThrowingBiConsumer<? super T, ? super U, E> first,
second.accept(t, u); BiConsumer<? super T, ? super U> second
}; ) {
} return (t, u) -> {
first.accept(t, u);
} second.accept(t, u);
};
}
}

View File

@ -1,62 +1,72 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.functions;
package ru.windcorp.jputil.functions;
import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.BiConsumer;
import java.util.function.Consumer;
@FunctionalInterface
public interface ThrowingConsumer<T, E extends Exception> { @FunctionalInterface
public interface ThrowingConsumer<T, E extends Exception> {
void accept(T t) throws E;
void accept(T t) throws E;
@SuppressWarnings("unchecked")
default Consumer<T> withHandler(BiConsumer<? super T, ? super E> handler) { @SuppressWarnings("unchecked")
return t -> { default Consumer<T> withHandler(BiConsumer<? super T, ? super E> handler) {
try { return t -> {
accept(t); try {
} catch (RuntimeException e) { accept(t);
throw e; } catch (RuntimeException e) {
} catch (Exception e) { throw e;
handler.accept(t, (E) e); } catch (Exception e) {
} handler.accept(t, (E) e);
}; }
} };
}
public static <T, E extends Exception> ThrowingConsumer<T, E> concat(ThrowingConsumer<? super T, ? extends E> first, ThrowingConsumer<? super T, ? extends E> second) {
return t -> { public static <T, E extends Exception> ThrowingConsumer<T, E> concat(
first.accept(t); ThrowingConsumer<? super T, ? extends E> first,
second.accept(t); ThrowingConsumer<? super T, ? extends E> second
}; ) {
} return t -> {
first.accept(t);
public static <T, E extends Exception> ThrowingConsumer<T, E> concat(Consumer<? super T> first, ThrowingConsumer<? super T, ? extends E> second) { second.accept(t);
return t -> { };
first.accept(t); }
second.accept(t);
}; public static <T, E extends Exception> ThrowingConsumer<T, E> concat(
} Consumer<? super T> first,
ThrowingConsumer<? super T, ? extends E> second
public static <T, E extends Exception> ThrowingConsumer<T, E> concat(ThrowingConsumer<? super T, ? extends E> first, Consumer<? super T> second) { ) {
return t -> { return t -> {
first.accept(t); first.accept(t);
second.accept(t); second.accept(t);
}; };
} }
} public static <T, E extends Exception> ThrowingConsumer<T, E> concat(
ThrowingConsumer<? super T, ? extends E> first,
Consumer<? super T> second
) {
return t -> {
first.accept(t);
second.accept(t);
};
}
}

View File

@ -1,73 +1,81 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.functions;
package ru.windcorp.jputil.functions;
import java.util.function.BiConsumer;
import java.util.function.Function; import java.util.function.BiConsumer;
import java.util.function.Supplier; import java.util.function.Function;
import java.util.function.Supplier;
@FunctionalInterface
public interface ThrowingFunction<T, R, E extends Exception> { @FunctionalInterface
public interface ThrowingFunction<T, R, E extends Exception> {
R apply(T t) throws E;
R apply(T t) throws E;
@SuppressWarnings("unchecked")
default Function<T, R> withHandler(BiConsumer<? super T, ? super E> handler, Function<? super T, ? extends R> value) { @SuppressWarnings("unchecked")
return t -> { default Function<T, R> withHandler(
try { BiConsumer<? super T, ? super E> handler,
return apply(t); Function<? super T, ? extends R> value
} catch (RuntimeException e) { ) {
throw e; return t -> {
} catch (Exception e) { try {
if (handler != null) handler.accept(t, (E) e); return apply(t);
return value == null ? null : value.apply(t); } catch (RuntimeException e) {
} throw e;
}; } catch (Exception e) {
} if (handler != null)
handler.accept(t, (E) e);
default Function<T, R> withHandler(BiConsumer<? super T, ? super E> handler, Supplier<? extends R> value) { return value == null ? null : value.apply(t);
return withHandler(handler, t -> value.get()); }
} };
}
default Function<T, R> withHandler(BiConsumer<? super T, ? super E> handler, R value) {
return withHandler(handler, t -> value); default Function<T, R> withHandler(BiConsumer<? super T, ? super E> handler, Supplier<? extends R> value) {
} return withHandler(handler, t -> value.get());
}
default Function<T, R> withHandler(BiConsumer<? super T, ? super E> handler) {
return withHandler(handler, (Function<T, R>) null); default Function<T, R> withHandler(BiConsumer<? super T, ? super E> handler, R value) {
} return withHandler(handler, t -> value);
}
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
ThrowingFunction<? super T, I, ? extends E> first, default Function<T, R> withHandler(BiConsumer<? super T, ? super E> handler) {
ThrowingFunction<? super I, ? extends R, ? extends E> second) { return withHandler(handler, (Function<T, R>) null);
return t -> second.apply(first.apply(t)); }
}
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose( ThrowingFunction<? super T, I, ? extends E> first,
Function<? super T, I> first, ThrowingFunction<? super I, ? extends R, ? extends E> second
ThrowingFunction<? super I, ? extends R, E> second) { ) {
return t -> second.apply(first.apply(t)); return t -> second.apply(first.apply(t));
} }
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose( public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
ThrowingFunction<? super T, I, E> first, Function<? super T, I> first,
Function<? super I, ? extends R> second) { ThrowingFunction<? super I, ? extends R, E> second
return t -> second.apply(first.apply(t)); ) {
} return t -> second.apply(first.apply(t));
}
}
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
ThrowingFunction<? super T, I, E> first,
Function<? super I, ? extends R> second
) {
return t -> second.apply(first.apply(t));
}
}

View File

@ -1,64 +1,65 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.functions;
package ru.windcorp.jputil.functions;
import java.util.function.Consumer;
import java.util.function.Consumer;
@FunctionalInterface
public interface ThrowingRunnable<E extends Exception> { @FunctionalInterface
public interface ThrowingRunnable<E extends Exception> {
void run() throws E;
void run() throws E;
@SuppressWarnings("unchecked")
default Runnable withHandler(Consumer<? super E> handler) { @SuppressWarnings("unchecked")
return () -> { default Runnable withHandler(Consumer<? super E> handler) {
try { return () -> {
run(); try {
} catch (RuntimeException e) { run();
throw e; } catch (RuntimeException e) {
} catch (Exception e) { throw e;
handler.accept((E) e); } catch (Exception e) {
} handler.accept((E) e);
}; }
} };
}
public static <E extends Exception> ThrowingRunnable<E> concat(
ThrowingRunnable<? extends E> first, public static <E extends Exception> ThrowingRunnable<E> concat(
ThrowingRunnable<? extends E> second ThrowingRunnable<? extends E> first,
) { ThrowingRunnable<? extends E> second
return () -> { ) {
first.run(); return () -> {
second.run(); first.run();
}; second.run();
} };
}
public static <E extends Exception> ThrowingRunnable<E> concat(Runnable first, ThrowingRunnable<E> second) {
return () -> { public static <E extends Exception> ThrowingRunnable<E> concat(Runnable first, ThrowingRunnable<E> second) {
first.run(); return () -> {
second.run(); first.run();
}; second.run();
} };
}
public static <E extends Exception> ThrowingRunnable<E> concat(ThrowingRunnable<E> first, Runnable second) {
return () -> { public static <E extends Exception> ThrowingRunnable<E> concat(ThrowingRunnable<E> first, Runnable second) {
first.run(); return () -> {
second.run(); first.run();
}; second.run();
} };
}
}
}

View File

@ -1,50 +1,52 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.functions;
package ru.windcorp.jputil.functions;
import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Consumer;
import java.util.function.Supplier;
@FunctionalInterface
public interface ThrowingSupplier<T, E extends Exception> { @FunctionalInterface
public interface ThrowingSupplier<T, E extends Exception> {
T get() throws E;
T get() throws E;
@SuppressWarnings("unchecked")
default Supplier<T> withHandler(Consumer<? super E> handler, Supplier<? extends T> value) { @SuppressWarnings("unchecked")
return () -> { default Supplier<T> withHandler(Consumer<? super E> handler, Supplier<? extends T> value) {
try { return () -> {
return get(); try {
} catch (RuntimeException e) { return get();
throw e; } catch (RuntimeException e) {
} catch (Exception e) { throw e;
if (handler != null) handler.accept((E) e); } catch (Exception e) {
return value == null ? null : value.get(); if (handler != null)
} handler.accept((E) e);
}; return value == null ? null : value.get();
} }
};
default Supplier<T> withHandler(Consumer<? super E> handler, T value) { }
return withHandler(handler, () -> value);
} default Supplier<T> withHandler(Consumer<? super E> handler, T value) {
return withHandler(handler, () -> value);
default Supplier<T> withHandler(Consumer<? super E> handler) { }
return withHandler(handler, (Supplier<T>) null);
} default Supplier<T> withHandler(Consumer<? super E> handler) {
return withHandler(handler, (Supplier<T>) null);
} }
}

View File

@ -1,47 +1,48 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.iterators;
package ru.windcorp.jputil.iterators;
import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.Iterator;
import java.util.NoSuchElementException;
public class ArrayIterator<E> implements Iterator<E> {
public class ArrayIterator<E> implements Iterator<E> {
private final E[] array;
private int next; private final E[] array;
private int next;
@SafeVarargs
public ArrayIterator(E... array) { @SafeVarargs
this.array = array; public ArrayIterator(E... array) {
} this.array = array;
}
@Override
public boolean hasNext() { @Override
return next < array.length; public boolean hasNext() {
} return next < array.length;
}
@Override
public E next() { @Override
try { public E next() {
return array[next++]; try {
} catch (ArrayIndexOutOfBoundsException e) { return array[next++];
throw new NoSuchElementException(); } catch (ArrayIndexOutOfBoundsException e) {
} throw new NoSuchElementException();
} }
}
}
}

View File

@ -1,61 +1,61 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.iterators;
package ru.windcorp.jputil.iterators;
import java.util.Iterator;
import java.util.function.Function; import java.util.Iterator;
import java.util.function.Function;
/**
* @author Javapony /**
* * @author Javapony
*/ */
public class FunctionIterator<T, E> implements Iterator<E> { public class FunctionIterator<T, E> implements Iterator<E> {
private final Iterator<T> parent; private final Iterator<T> parent;
private final Function<T, E> function; private final Function<T, E> function;
public FunctionIterator(Iterator<T> parent, Function<T, E> function) { public FunctionIterator(Iterator<T> parent, Function<T, E> function) {
this.parent = parent; this.parent = parent;
this.function = function; this.function = function;
} }
/** /**
* @see java.util.Iterator#hasNext() * @see java.util.Iterator#hasNext()
*/ */
@Override @Override
public boolean hasNext() { public boolean hasNext() {
return parent.hasNext(); return parent.hasNext();
} }
/** /**
* @see java.util.Iterator#next() * @see java.util.Iterator#next()
*/ */
@Override @Override
public E next() { public E next() {
return function.apply(parent.next()); return function.apply(parent.next());
} }
/** /**
* @see java.util.Iterator#remove() * @see java.util.Iterator#remove()
*/ */
@Override @Override
public void remove() { public void remove() {
parent.remove(); parent.remove();
} }
} }

View File

@ -1,60 +1,62 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.iterators;
package ru.windcorp.jputil.iterators;
import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.Iterator;
import java.util.NoSuchElementException;
public class PeekingIterator<E> implements Iterator<E> {
public class PeekingIterator<E> implements Iterator<E> {
private final Iterator<? extends E> source;
private E next = null; private final Iterator<? extends E> source;
private E next = null;
public PeekingIterator(Iterator<? extends E> source) {
this.source = source; public PeekingIterator(Iterator<? extends E> source) {
} this.source = source;
}
@Override
public boolean hasNext() { @Override
return next != null || source.hasNext(); public boolean hasNext() {
} return next != null || source.hasNext();
}
public E peek() {
if (next == null) { public E peek() {
if (source.hasNext()) { if (next == null) {
next = source.next(); if (source.hasNext()) {
} else { next = source.next();
throw new NoSuchElementException(); } else {
} throw new NoSuchElementException();
} }
}
return next;
} return next;
}
// SonarLint: "Iterator.next()" methods should throw "NoSuchElementException" (java:S2272)
// peek() throws NoSuchElementException as expected // SonarLint: "Iterator.next()" methods should throw
@SuppressWarnings("squid:S2272") // "NoSuchElementException" (java:S2272)
// peek() throws NoSuchElementException as expected
@Override @SuppressWarnings("squid:S2272")
public E next() {
E element = peek(); @Override
next = null; public E next() {
return element; E element = peek();
} next = null;
return element;
} }
}

View File

@ -1,67 +1,70 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.iterators;
package ru.windcorp.jputil.iterators;
import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.Iterator;
import java.util.NoSuchElementException;
public class RangeIterator<E> implements Iterator<E> {
public class RangeIterator<E> implements Iterator<E> {
private final Iterator<E> parent;
private final int from; private final Iterator<E> parent;
private final int amount; private final int from;
private final int amount;
private int nextIndex = 0;
private int nextIndex = 0;
public RangeIterator(Iterator<E> iterator, int from, int amount) {
this.parent = iterator; public RangeIterator(Iterator<E> iterator, int from, int amount) {
this.from = from; this.parent = iterator;
this.amount = amount < 0 ? Integer.MAX_VALUE : amount; this.from = from;
} this.amount = amount < 0 ? Integer.MAX_VALUE : amount;
}
public RangeIterator(Iterator<E> iterator, int from) {
this(iterator, from, -1); public RangeIterator(Iterator<E> iterator, int from) {
} this(iterator, from, -1);
}
@Override
public boolean hasNext() { @Override
update(); public boolean hasNext() {
return nextIndex < from + amount && parent.hasNext(); update();
} return nextIndex < from + amount && parent.hasNext();
}
@Override
public E next() { @Override
update(); public E next() {
if (nextIndex >= from + amount) { update();
throw new NoSuchElementException("RangeIterator about to retrieve element " + nextIndex if (nextIndex >= from + amount) {
+ " which exceeds upper boundary " + (from + amount)); throw new NoSuchElementException(
} "RangeIterator about to retrieve element " + nextIndex
+ " which exceeds upper boundary " + (from + amount)
E result = parent.next(); );
nextIndex++; }
return result;
} E result = parent.next();
nextIndex++;
protected void update() { return result;
while (nextIndex < from && parent.hasNext()) { }
parent.next();
nextIndex++; protected void update() {
} while (nextIndex < from && parent.hasNext()) {
} parent.next();
nextIndex++;
} }
}
}

View File

@ -1,70 +1,72 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.iterators;
package ru.windcorp.jputil.iterators;
import java.util.ArrayList;
import java.util.Iterator; import java.util.ArrayList;
import java.util.NoSuchElementException; import java.util.Iterator;
import java.util.NoSuchElementException;
public class Reiterator<E> implements Iterable<E> {
public class Reiterator<E> implements Iterable<E> {
private class ReiteratorIterator implements Iterator<E> {
private class ReiteratorIterator implements Iterator<E> {
int index = 0;
int index = 0;
@Override
public boolean hasNext() { @Override
synchronized (source) { public boolean hasNext() {
if (index >= data.size()) { synchronized (source) {
if (!source.hasNext()) { if (index >= data.size()) {
return false; if (!source.hasNext()) {
} else { return false;
data.add(source.next()); } else {
} data.add(source.next());
} }
}
return true;
} return true;
} }
}
@Override
public E next() { @Override
E result; public E next() {
synchronized (source) { E result;
if (!hasNext()) throw new NoSuchElementException(); synchronized (source) {
result = data.get(index); if (!hasNext())
} throw new NoSuchElementException();
index++; result = data.get(index);
return result; }
} index++;
return result;
} }
private final Iterator<E> source; }
private final ArrayList<E> data = new ArrayList<>();
private final Iterator<E> source;
public Reiterator(Iterator<E> source) { private final ArrayList<E> data = new ArrayList<>();
this.source = source;
} public Reiterator(Iterator<E> source) {
this.source = source;
@Override }
public Iterator<E> iterator() {
return new ReiteratorIterator(); @Override
} public Iterator<E> iterator() {
return new ReiteratorIterator();
} }
}

View File

@ -1,39 +1,40 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.selectors;
package ru.windcorp.jputil.selectors;
public abstract class AbstractSelectorOperator implements SelectorOperator {
public abstract class AbstractSelectorOperator implements SelectorOperator {
private final String[] names;
private final String[] names;
public AbstractSelectorOperator(String[] names) {
this.names = names; public AbstractSelectorOperator(String[] names) {
} this.names = names;
}
@Override
public boolean matchesName(String name) { @Override
for (String n : names) { public boolean matchesName(String name) {
if (n.equals(name)) { for (String n : names) {
return true; if (n.equals(name)) {
} return true;
} }
}
return false;
} return false;
}
}
}

View File

@ -1,57 +1,58 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.selectors;
package ru.windcorp.jputil.selectors;
import ru.windcorp.jputil.SyntaxException;
import ru.windcorp.jputil.chars.StringUtil; import ru.windcorp.jputil.SyntaxException;
import ru.windcorp.jputil.chars.StringUtil;
public abstract class NamedParameterizedSelector<T> extends NamedSelector<T> {
public abstract class NamedParameterizedSelector<T> extends NamedSelector<T> {
private final char separator;
private String givenName; private final char separator;
private String givenName;
public NamedParameterizedSelector(char separator, String... names) {
super(names); public NamedParameterizedSelector(char separator, String... names) {
this.separator = separator; super(names);
} this.separator = separator;
}
@Override
public Selector<T> derive(String name) throws SyntaxException { @Override
String[] parts = StringUtil.split(name, separator, 2); public Selector<T> derive(String name) throws SyntaxException {
String[] parts = StringUtil.split(name, separator, 2);
if (parts[1] == null) {
return null; if (parts[1] == null) {
} return null;
}
if (!matchesName(parts[0])) {
return null; if (!matchesName(parts[0])) {
} return null;
}
NamedParameterizedSelector<T> selector = deriveImpl(parts[1]);
selector.givenName = name; NamedParameterizedSelector<T> selector = deriveImpl(parts[1]);
return selector; selector.givenName = name;
} return selector;
}
protected abstract NamedParameterizedSelector<T> deriveImpl(String param) throws SyntaxException;
protected abstract NamedParameterizedSelector<T> deriveImpl(String param) throws SyntaxException;
@Override
public String toString() { @Override
return givenName; public String toString() {
} return givenName;
}
}
}

View File

@ -1,50 +1,51 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.selectors;
package ru.windcorp.jputil.selectors;
import ru.windcorp.jputil.SyntaxException;
import ru.windcorp.jputil.SyntaxException;
public abstract class NamedSelector<T> implements Selector<T> {
public abstract class NamedSelector<T> implements Selector<T> {
private final String[] names;
private final String[] names;
public NamedSelector(String... names) {
this.names = names; public NamedSelector(String... names) {
} this.names = names;
}
public boolean matchesName(String name) {
for (String n : names) { public boolean matchesName(String name) {
if (n.equalsIgnoreCase(name)) { for (String n : names) {
return true; if (n.equalsIgnoreCase(name)) {
} return true;
} }
}
return false;
} return false;
}
@Override
public Selector<T> derive(String name) throws SyntaxException { @Override
return matchesName(name) ? this : null; public Selector<T> derive(String name) throws SyntaxException {
} return matchesName(name) ? this : null;
}
@Override
public String toString() { @Override
return names[0]; public String toString() {
} return names[0];
}
}
}

View File

@ -1,36 +1,37 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.selectors;
package ru.windcorp.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate; import java.util.Deque;
import java.util.function.Predicate;
public class OperatorAnd extends AbstractSelectorOperator {
public class OperatorAnd extends AbstractSelectorOperator {
public OperatorAnd(String... names) {
super(names); public OperatorAnd(String... names) {
} super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) { @Override
Predicate<T> arg2 = stack.pop(); public <T> void process(Deque<Predicate<T>> stack) {
Predicate<T> arg1 = stack.pop(); Predicate<T> arg2 = stack.pop();
stack.push(obj -> arg1.test(obj) && arg2.test(obj)); Predicate<T> arg1 = stack.pop();
} stack.push(obj -> arg1.test(obj) && arg2.test(obj));
}
}
}

View File

@ -1,36 +1,37 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.selectors;
package ru.windcorp.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate; import java.util.Deque;
import java.util.function.Predicate;
public class OperatorExclude extends AbstractSelectorOperator {
public class OperatorExclude extends AbstractSelectorOperator {
public OperatorExclude(String... names) {
super(names); public OperatorExclude(String... names) {
} super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) { @Override
Predicate<T> arg2 = stack.pop(); public <T> void process(Deque<Predicate<T>> stack) {
Predicate<T> arg1 = stack.pop(); Predicate<T> arg2 = stack.pop();
stack.push(obj -> arg1.test(obj) && !arg2.test(obj)); Predicate<T> arg1 = stack.pop();
} stack.push(obj -> arg1.test(obj) && !arg2.test(obj));
}
}
}

View File

@ -1,34 +1,35 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.selectors;
package ru.windcorp.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate; import java.util.Deque;
import java.util.function.Predicate;
public class OperatorNot extends AbstractSelectorOperator {
public class OperatorNot extends AbstractSelectorOperator {
public OperatorNot(String... names) {
super(names); public OperatorNot(String... names) {
} super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) { @Override
stack.push(stack.pop().negate()); public <T> void process(Deque<Predicate<T>> stack) {
} stack.push(stack.pop().negate());
}
}
}

View File

@ -1,36 +1,37 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.selectors;
package ru.windcorp.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate; import java.util.Deque;
import java.util.function.Predicate;
public class OperatorOr extends AbstractSelectorOperator {
public class OperatorOr extends AbstractSelectorOperator {
public OperatorOr(String... names) {
super(names); public OperatorOr(String... names) {
} super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) { @Override
Predicate<T> arg2 = stack.pop(); public <T> void process(Deque<Predicate<T>> stack) {
Predicate<T> arg1 = stack.pop(); Predicate<T> arg2 = stack.pop();
stack.push(obj -> arg1.test(obj) || arg2.test(obj)); Predicate<T> arg1 = stack.pop();
} stack.push(obj -> arg1.test(obj) || arg2.test(obj));
}
}
}

View File

@ -1,36 +1,37 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.selectors;
package ru.windcorp.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate; import java.util.Deque;
import java.util.function.Predicate;
public class OperatorXor extends AbstractSelectorOperator {
public class OperatorXor extends AbstractSelectorOperator {
public OperatorXor(String... names) {
super(names); public OperatorXor(String... names) {
} super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) { @Override
Predicate<T> arg2 = stack.pop(); public <T> void process(Deque<Predicate<T>> stack) {
Predicate<T> arg1 = stack.pop(); Predicate<T> arg2 = stack.pop();
stack.push(obj -> arg1.test(obj) != arg2.test(obj)); Predicate<T> arg1 = stack.pop();
} stack.push(obj -> arg1.test(obj) != arg2.test(obj));
}
}
}

View File

@ -1,36 +1,37 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.selectors;
package ru.windcorp.jputil.selectors;
import java.util.function.Predicate;
import java.util.function.Predicate;
public class PredicateWrapper<T> extends NamedSelector<T> {
public class PredicateWrapper<T> extends NamedSelector<T> {
private final Predicate<? super T> predicate;
private final Predicate<? super T> predicate;
public PredicateWrapper(String name, Predicate<? super T> predicate) {
super(name); public PredicateWrapper(String name, Predicate<? super T> predicate) {
this.predicate = predicate; super(name);
} this.predicate = predicate;
}
@Override
public boolean test(T obj) { @Override
return predicate.test(obj); public boolean test(T obj) {
} return predicate.test(obj);
}
}
}

View File

@ -1,28 +1,29 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.selectors;
package ru.windcorp.jputil.selectors;
import java.util.function.Predicate;
import java.util.function.Predicate;
import ru.windcorp.jputil.SyntaxException;
import ru.windcorp.jputil.SyntaxException;
public interface Selector<T> extends Predicate<T> {
public interface Selector<T> extends Predicate<T> {
public Selector<T> derive(String name) throws SyntaxException;
public Selector<T> derive(String name) throws SyntaxException;
}
}

View File

@ -1,29 +1,30 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.selectors;
package ru.windcorp.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate; import java.util.Deque;
import java.util.function.Predicate;
public interface SelectorOperator {
public interface SelectorOperator {
public <T> void process(Deque<Predicate<T>> stack);
public <T> void process(Deque<Predicate<T>> stack);
public boolean matchesName(String name);
public boolean matchesName(String name);
}
}

View File

@ -1,176 +1,175 @@
/******************************************************************************* /*
* JPUtil * JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA * Copyright (C) 2019-2021 OLEGSHA/Javapony and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.jputil.selectors;
package ru.windcorp.jputil.selectors;
import java.util.ArrayList;
import java.util.Collection; import java.util.ArrayList;
import java.util.Collections; import java.util.Collection;
import java.util.Deque; import java.util.Collections;
import java.util.Iterator; import java.util.Deque;
import java.util.LinkedList; import java.util.Iterator;
import java.util.function.Predicate; import java.util.LinkedList;
import java.util.function.Predicate;
import ru.windcorp.jputil.SyntaxException;
import ru.windcorp.jputil.iterators.PeekingIterator; import ru.windcorp.jputil.SyntaxException;
import ru.windcorp.jputil.iterators.PeekingIterator;
public class SelectorSystem<T> {
public class SelectorSystem<T> {
public static final char EXPRESSION_OPEN = '(';
public static final char EXPRESSION_CLOSE = ')'; public static final char EXPRESSION_OPEN = '(';
public static final char EXPRESSION_CLOSE = ')';
private final Collection<Selector<T>> selectors =
Collections.synchronizedCollection(new ArrayList<Selector<T>>()); private final Collection<Selector<T>> selectors = Collections.synchronizedCollection(new ArrayList<Selector<T>>());
private final Collection<SelectorOperator> operators = private final Collection<SelectorOperator> operators = Collections
Collections.synchronizedCollection(new ArrayList<SelectorOperator>()); .synchronizedCollection(new ArrayList<SelectorOperator>());
private String stackPrefix = null; private String stackPrefix = null;
public Collection<Selector<T>> getSelectors() { public Collection<Selector<T>> getSelectors() {
return this.selectors; return this.selectors;
} }
public Collection<SelectorOperator> getSelectorOperators() { public Collection<SelectorOperator> getSelectorOperators() {
return this.operators; return this.operators;
} }
public String getStackPrefix() { public String getStackPrefix() {
return stackPrefix; return stackPrefix;
} }
public SelectorSystem<T> setStackPrefix(String stackPrefix) { public SelectorSystem<T> setStackPrefix(String stackPrefix) {
this.stackPrefix = stackPrefix; this.stackPrefix = stackPrefix;
return this; return this;
} }
public SelectorSystem<T> add(Selector<T> selector) { public SelectorSystem<T> add(Selector<T> selector) {
getSelectors().add(selector); getSelectors().add(selector);
return this; return this;
} }
public SelectorSystem<T> add(SelectorOperator operator) { public SelectorSystem<T> add(SelectorOperator operator) {
getSelectorOperators().add(operator); getSelectorOperators().add(operator);
return this; return this;
} }
public Predicate<T> parse(Iterator<String> tokens) throws SyntaxException { public Predicate<T> parse(Iterator<String> tokens) throws SyntaxException {
PeekingIterator<String> peeker = new PeekingIterator<>(tokens); PeekingIterator<String> peeker = new PeekingIterator<>(tokens);
if (getStackPrefix() != null && peeker.hasNext() && getStackPrefix().equals(peeker.peek())) { if (getStackPrefix() != null && peeker.hasNext() && getStackPrefix().equals(peeker.peek())) {
peeker.next(); peeker.next();
return parseStack(peeker); return parseStack(peeker);
} }
Deque<Predicate<T>> stack = new LinkedList<>(); Deque<Predicate<T>> stack = new LinkedList<>();
synchronized (getSelectorOperators()) { synchronized (getSelectorOperators()) {
synchronized (getSelectors()) { synchronized (getSelectors()) {
while (peeker.hasNext()) { while (peeker.hasNext()) {
parseToken(stack, peeker); parseToken(stack, peeker);
} }
} }
} }
return compress(stack); return compress(stack);
} }
private void parseToken(Deque<Predicate<T>> stack, Iterator<String> tokens) throws SyntaxException { private void parseToken(Deque<Predicate<T>> stack, Iterator<String> tokens) throws SyntaxException {
if (!tokens.hasNext()) { if (!tokens.hasNext()) {
throw new SyntaxException("Not enough tokens"); throw new SyntaxException("Not enough tokens");
} }
String token = tokens.next(); String token = tokens.next();
for (SelectorOperator operator : getSelectorOperators()) { for (SelectorOperator operator : getSelectorOperators()) {
if (operator.matchesName(token.toLowerCase())) { if (operator.matchesName(token.toLowerCase())) {
parseToken(stack, tokens); parseToken(stack, tokens);
operator.process(stack); operator.process(stack);
return; return;
} }
} }
Selector<T> tmp; Selector<T> tmp;
for (Selector<T> selector : getSelectors()) { for (Selector<T> selector : getSelectors()) {
if ((tmp = selector.derive(token)) != null) { if ((tmp = selector.derive(token)) != null) {
stack.push(tmp); stack.push(tmp);
return; return;
} }
} }
throw new SyntaxException("Unknown token \"" + token + "\""); throw new SyntaxException("Unknown token \"" + token + "\"");
} }
public Predicate<T> parseStack(Iterator<String> tokens) throws SyntaxException { public Predicate<T> parseStack(Iterator<String> tokens) throws SyntaxException {
Deque<Predicate<T>> stack = new LinkedList<>(); Deque<Predicate<T>> stack = new LinkedList<>();
String token; String token;
synchronized (getSelectorOperators()) { synchronized (getSelectorOperators()) {
synchronized (getSelectors()) { synchronized (getSelectors()) {
tokenCycle: tokenCycle: while (tokens.hasNext()) {
while (tokens.hasNext()) { token = tokens.next();
token = tokens.next();
for (SelectorOperator operator : getSelectorOperators()) {
for (SelectorOperator operator : getSelectorOperators()) { if (operator.matchesName(token.toLowerCase())) {
if (operator.matchesName(token.toLowerCase())) { operator.process(stack);
operator.process(stack); continue tokenCycle;
continue tokenCycle; }
} }
}
for (Selector<T> selector : getSelectors()) {
for (Selector<T> selector : getSelectors()) { Selector<T> tmp;
Selector<T> tmp; if ((tmp = selector.derive(token)) != null) {
if ((tmp = selector.derive(token)) != null) { stack.push(tmp);
stack.push(tmp); continue tokenCycle;
continue tokenCycle; }
} }
}
throw new SyntaxException("Unknown token \"" + token + "\"");
throw new SyntaxException("Unknown token \"" + token + "\"");
}
} }
} }
}
return compress(stack);
return compress(stack); }
}
private Predicate<T> compress(Deque<Predicate<T>> stack) throws SyntaxException {
private Predicate<T> compress(Deque<Predicate<T>> stack) throws SyntaxException { if (stack.isEmpty()) {
if (stack.isEmpty()) { throw new SyntaxException("Stack is empty");
throw new SyntaxException("Stack is empty"); }
}
if (stack.size() == 1) {
if (stack.size() == 1) { return stack.pop();
return stack.pop(); }
}
return obj -> {
return obj -> { for (Predicate<? super T> predicate : stack) {
for (Predicate<? super T> predicate : stack) { if (predicate.test(obj)) {
if (predicate.test(obj)) { return true;
return true; }
} }
}
return false;
return false; };
}; }
}
}
}

View File

@ -1,22 +1,23 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia;
package ru.windcorp.progressia;
public class Progressia {
public class Progressia {
}
}

View File

@ -1,50 +1,51 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia;
package ru.windcorp.progressia;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.common.util.crash.analyzers.OutOfMemoryAnalyzer; import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.common.util.crash.providers.*; import ru.windcorp.progressia.common.util.crash.analyzers.OutOfMemoryAnalyzer;
import ru.windcorp.progressia.common.util.crash.providers.*;
public class ProgressiaLauncher {
public class ProgressiaLauncher {
public static String[] arguments;
public static String[] arguments;
public static void launch(String[] args, Proxy proxy) {
arguments = args.clone(); public static void launch(String[] args, Proxy proxy) {
setupCrashReports(); arguments = args.clone();
proxy.initialize(); setupCrashReports();
} proxy.initialize();
}
private static void setupCrashReports() {
// Context providers private static void setupCrashReports() {
CrashReports.registerProvider(new OSContextProvider()); // Context providers
CrashReports.registerProvider(new RAMContextProvider()); CrashReports.registerProvider(new OSContextProvider());
CrashReports.registerProvider(new JavaVersionContextProvider()); CrashReports.registerProvider(new RAMContextProvider());
CrashReports.registerProvider(new OpenALContextProvider()); CrashReports.registerProvider(new JavaVersionContextProvider());
CrashReports.registerProvider(new ArgsContextProvider()); CrashReports.registerProvider(new OpenALContextProvider());
CrashReports.registerProvider(new LanguageContextProvider()); CrashReports.registerProvider(new ArgsContextProvider());
// Analyzers CrashReports.registerProvider(new LanguageContextProvider());
CrashReports.registerAnalyzer(new OutOfMemoryAnalyzer()); // Analyzers
CrashReports.registerAnalyzer(new OutOfMemoryAnalyzer());
Thread.setDefaultUncaughtExceptionHandler((Thread thread, Throwable t)-> {
CrashReports.crash(t, "Uncaught exception in thread %s", thread.getName()); Thread.setDefaultUncaughtExceptionHandler((Thread thread, Throwable t) -> {
}); CrashReports.crash(t, "Uncaught exception in thread %s", thread.getName());
} });
}
}
}

View File

@ -1,24 +1,25 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia;
package ru.windcorp.progressia;
public interface Proxy {
public interface Proxy {
void initialize();
void initialize();
}
}

View File

@ -1,59 +1,79 @@
package ru.windcorp.progressia.client; /*
* Progressia
import ru.windcorp.progressia.client.comms.DefaultClientCommsListener; * Copyright (C) 2020-2021 Wind Corporation and contributors
import ru.windcorp.progressia.client.comms.ServerCommsChannel; *
import ru.windcorp.progressia.client.graphics.world.Camera; * This program is free software: you can redistribute it and/or modify
import ru.windcorp.progressia.client.graphics.world.EntityAnchor; * it under the terms of the GNU General Public License as published by
import ru.windcorp.progressia.client.graphics.world.LocalPlayer; * the Free Software Foundation, either version 3 of the License, or
import ru.windcorp.progressia.client.world.WorldRender; * (at your option) any later version.
import ru.windcorp.progressia.common.world.WorldData; *
import ru.windcorp.progressia.common.world.entity.EntityData; * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
public class Client { * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
private final WorldRender world; *
private final LocalPlayer localPlayer = new LocalPlayer(this); * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
private final Camera camera = new Camera((float) Math.toRadians(70)); */
private final ServerCommsChannel comms; package ru.windcorp.progressia.client;
public Client(WorldData world, ServerCommsChannel comms) { import ru.windcorp.progressia.client.comms.DefaultClientCommsListener;
this.world = new WorldRender(world, this); import ru.windcorp.progressia.client.comms.ServerCommsChannel;
this.comms = comms; import ru.windcorp.progressia.client.graphics.world.Camera;
import ru.windcorp.progressia.client.graphics.world.EntityAnchor;
comms.addListener(new DefaultClientCommsListener(this)); import ru.windcorp.progressia.client.graphics.world.LocalPlayer;
} import ru.windcorp.progressia.client.world.WorldRender;
import ru.windcorp.progressia.common.world.WorldData;
public WorldRender getWorld() { import ru.windcorp.progressia.common.world.entity.EntityData;
return world;
} public class Client {
public LocalPlayer getLocalPlayer() { private final WorldRender world;
return localPlayer; private final LocalPlayer localPlayer = new LocalPlayer(this);
}
private final Camera camera = new Camera((float) Math.toRadians(70));
public boolean isReady() {
return localPlayer.hasEntity(); private final ServerCommsChannel comms;
}
public Client(WorldData world, ServerCommsChannel comms) {
public Camera getCamera() { this.world = new WorldRender(world, this);
return camera; this.comms = comms;
}
comms.addListener(new DefaultClientCommsListener(this));
public ServerCommsChannel getComms() { }
return comms;
} public WorldRender getWorld() {
return world;
public void onLocalPlayerEntityChanged(EntityData entity, EntityData lastKnownEntity) { }
if (entity == null) {
getCamera().setAnchor(null); public LocalPlayer getLocalPlayer() {
return; return localPlayer;
} }
getCamera().setAnchor(new EntityAnchor( public boolean isReady() {
getWorld().getEntityRenderable(entity) return localPlayer.hasEntity();
)); }
}
public Camera getCamera() {
} return camera;
}
public ServerCommsChannel getComms() {
return comms;
}
public void onLocalPlayerEntityChanged(EntityData entity, EntityData lastKnownEntity) {
if (entity == null) {
getCamera().setAnchor(null);
return;
}
getCamera().setAnchor(
new EntityAnchor(
getWorld().getEntityRenderable(entity)
)
);
}
}

View File

@ -1,60 +1,64 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client;
package ru.windcorp.progressia.client;
import ru.windcorp.progressia.Proxy;
import ru.windcorp.progressia.client.audio.AudioSystem; import ru.windcorp.progressia.Proxy;
import ru.windcorp.progressia.client.graphics.backend.GraphicsBackend; import ru.windcorp.progressia.client.audio.AudioSystem;
import ru.windcorp.progressia.client.graphics.backend.RenderTaskQueue; import ru.windcorp.progressia.client.graphics.backend.GraphicsBackend;
import ru.windcorp.progressia.client.graphics.flat.FlatRenderProgram; import ru.windcorp.progressia.client.graphics.backend.RenderTaskQueue;
import ru.windcorp.progressia.client.graphics.font.GNUUnifontLoader; import ru.windcorp.progressia.client.graphics.flat.FlatRenderProgram;
import ru.windcorp.progressia.client.graphics.font.Typefaces; import ru.windcorp.progressia.client.graphics.font.GNUUnifontLoader;
import ru.windcorp.progressia.client.graphics.texture.Atlases; import ru.windcorp.progressia.client.graphics.font.Typefaces;
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram; import ru.windcorp.progressia.client.graphics.texture.Atlases;
import ru.windcorp.progressia.client.localization.Localizer; import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
import ru.windcorp.progressia.common.resource.ResourceManager; import ru.windcorp.progressia.client.localization.Localizer;
import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.resource.ResourceManager;
import ru.windcorp.progressia.server.ServerState; import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.test.TestContent; import ru.windcorp.progressia.server.ServerState;
import ru.windcorp.progressia.test.TestContent;
public class ClientProxy implements Proxy {
public class ClientProxy implements Proxy {
@Override
public void initialize() { @Override
GraphicsBackend.initialize(); public void initialize() {
try { GraphicsBackend.initialize();
RenderTaskQueue.waitAndInvoke(FlatRenderProgram::init); try {
RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init); RenderTaskQueue.waitAndInvoke(FlatRenderProgram::init);
RenderTaskQueue.waitAndInvoke(() -> Typefaces.setDefault(GNUUnifontLoader.load(ResourceManager.getResource("assets/unifont-13.0.03.hex.gz")))); RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init);
} catch (InterruptedException e) { RenderTaskQueue.waitAndInvoke(
throw CrashReports.report(e, "ClientProxy failed"); () -> Typefaces
} .setDefault(GNUUnifontLoader.load(ResourceManager.getResource("assets/unifont-13.0.03.hex.gz")))
);
Localizer.getInstance().setLanguage("en-US"); } catch (InterruptedException e) {
throw CrashReports.report(e, "ClientProxy failed");
TestContent.registerContent(); }
Atlases.loadAllAtlases(); Localizer.getInstance().setLanguage("en-US");
AudioSystem.initialize(); TestContent.registerContent();
ServerState.startServer(); Atlases.loadAllAtlases();
ClientState.connectToLocalServer();
} AudioSystem.initialize();
} ServerState.startServer();
ClientState.connectToLocalServer();
}
}

View File

@ -1,46 +1,65 @@
package ru.windcorp.progressia.client; /*
* Progressia
import ru.windcorp.progressia.client.comms.localhost.LocalServerCommsChannel; * Copyright (C) 2020-2021 Wind Corporation and contributors
import ru.windcorp.progressia.client.graphics.GUI; *
import ru.windcorp.progressia.client.graphics.world.LayerWorld; * This program is free software: you can redistribute it and/or modify
import ru.windcorp.progressia.common.world.WorldData; * it under the terms of the GNU General Public License as published by
import ru.windcorp.progressia.server.ServerState; * the Free Software Foundation, either version 3 of the License, or
import ru.windcorp.progressia.test.LayerAbout; * (at your option) any later version.
import ru.windcorp.progressia.test.LayerTestUI; *
import ru.windcorp.progressia.test.TestContent; * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
public class ClientState { * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
private static Client instance; *
* You should have received a copy of the GNU General Public License
public static Client getInstance() { * along with this program. If not, see <https://www.gnu.org/licenses/>.
return instance; */
}
package ru.windcorp.progressia.client;
public static void setInstance(Client instance) {
ClientState.instance = instance; import ru.windcorp.progressia.client.comms.localhost.LocalServerCommsChannel;
} import ru.windcorp.progressia.client.graphics.GUI;
import ru.windcorp.progressia.client.graphics.world.LayerWorld;
public static void connectToLocalServer() { import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.server.ServerState;
WorldData world = new WorldData(); import ru.windcorp.progressia.test.LayerAbout;
import ru.windcorp.progressia.test.LayerTestUI;
LocalServerCommsChannel channel = new LocalServerCommsChannel( import ru.windcorp.progressia.test.TestContent;
ServerState.getInstance()
); public class ClientState {
Client client = new Client(world, channel); private static Client instance;
channel.connect(TestContent.PLAYER_LOGIN); public static Client getInstance() {
return instance;
setInstance(client); }
GUI.addBottomLayer(new LayerWorld(client)); public static void setInstance(Client instance) {
GUI.addTopLayer(new LayerTestUI()); ClientState.instance = instance;
GUI.addTopLayer(new LayerAbout()); }
} public static void connectToLocalServer() {
private ClientState() {} WorldData world = new WorldData();
} LocalServerCommsChannel channel = new LocalServerCommsChannel(
ServerState.getInstance()
);
Client client = new Client(world, channel);
channel.connect(TestContent.PLAYER_LOGIN);
setInstance(client);
GUI.addBottomLayer(new LayerWorld(client));
GUI.addTopLayer(new LayerTestUI());
GUI.addTopLayer(new LayerAbout());
}
private ClientState() {
}
}

View File

@ -1,28 +1,29 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client;
package ru.windcorp.progressia.client;
import ru.windcorp.progressia.ProgressiaLauncher;
import ru.windcorp.progressia.ProgressiaLauncher;
public class ProgressiaClientMain {
public class ProgressiaClientMain {
public static void main(String[] args) {
ProgressiaLauncher.launch(args, new ClientProxy()); public static void main(String[] args) {
} ProgressiaLauncher.launch(args, new ClientProxy());
}
}
}

View File

@ -1,5 +1,23 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.audio; package ru.windcorp.progressia.client.audio;
public enum AudioFormat { public enum AudioFormat {
MONO, STEREO MONO, STEREO
} }

View File

@ -1,3 +1,21 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.audio; package ru.windcorp.progressia.client.audio;
import org.lwjgl.openal.*; import org.lwjgl.openal.*;
@ -26,8 +44,8 @@ public class AudioManager {
public static void initAL() { public static void initAL() {
String defaultDeviceName = alcGetString( String defaultDeviceName = alcGetString(
0, 0,
ALC_DEFAULT_DEVICE_SPECIFIER ALC_DEFAULT_DEVICE_SPECIFIER
); );
device = alcOpenDevice(defaultDeviceName); device = alcOpenDevice(defaultDeviceName);
@ -57,27 +75,30 @@ public class AudioManager {
lastSoundIndex = 0; lastSoundIndex = 0;
} }
speaker = soundSpeakers.get(lastSoundIndex); speaker = soundSpeakers.get(lastSoundIndex);
} while (speaker.getState() } while (
.equals(Speaker.State.PLAYING_LOOP)); speaker.getState()
.equals(Speaker.State.PLAYING_LOOP)
);
return speaker; return speaker;
} }
private static SoundType findSoundType(String soundID) throws Exception { private static SoundType findSoundType(String soundID) throws Exception {
for (SoundType s : soundsBuffer) { for (SoundType s : soundsBuffer) {
if (s.getId().equals(soundID)) { if (s.getId().equals(soundID)) {
return s; return s;
} }
} }
throw new Exception("ERROR: The selected sound is not loaded or" + throw new Exception(
" not exists"); "ERROR: The selected sound is not loaded or" +
" not exists"
);
} }
public static Speaker initSpeaker(String soundID) { public static Speaker initSpeaker(String soundID) {
Speaker speaker = getLastSpeaker(); Speaker speaker = getLastSpeaker();
try { try {
findSoundType(soundID).initSpeaker(speaker); findSoundType(soundID).initSpeaker(speaker);
} catch (Exception ex) } catch (Exception ex) {
{
throw new RuntimeException(); throw new RuntimeException();
} }
return speaker; return speaker;
@ -86,8 +107,7 @@ public class AudioManager {
public static Speaker initMusicSpeaker(String soundID) { public static Speaker initMusicSpeaker(String soundID) {
try { try {
findSoundType(soundID).initSpeaker(musicSpeaker); findSoundType(soundID).initSpeaker(musicSpeaker);
} catch (Exception ex) } catch (Exception ex) {
{
throw new RuntimeException(); throw new RuntimeException();
} }
return musicSpeaker; return musicSpeaker;
@ -103,8 +123,7 @@ public class AudioManager {
public static void loadSound(String path, String id, AudioFormat format) { public static void loadSound(String path, String id, AudioFormat format) {
if (format == AudioFormat.MONO) { if (format == AudioFormat.MONO) {
soundsBuffer.add(AudioReader.readAsMono(path, id)); soundsBuffer.add(AudioReader.readAsMono(path, id));
} else } else {
{
soundsBuffer.add(AudioReader.readAsStereo(path, id)); soundsBuffer.add(AudioReader.readAsStereo(path, id));
} }
} }
@ -128,8 +147,7 @@ public class AudioManager {
return deviceCapabilities; return deviceCapabilities;
} }
public static void createBuffers() public static void createBuffers() {
{
for (int i = 0; i < SOUNDS_NUM; ++i) { for (int i = 0; i < SOUNDS_NUM; ++i) {
soundSpeakers.add(new Speaker()); soundSpeakers.add(new Speaker());
} }
@ -141,4 +159,4 @@ public class AudioManager {
return alGetString(AL11.AL_VERSION); return alGetString(AL11.AL_VERSION);
} }
} }

View File

@ -1,3 +1,21 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.audio; package ru.windcorp.progressia.client.audio;
public class AudioSystem { public class AudioSystem {
@ -9,8 +27,10 @@ public class AudioSystem {
} }
static void loadAudioData() { static void loadAudioData() {
AudioManager.loadSound("assets/sounds/block_destroy_clap.ogg", AudioManager.loadSound(
"Progressia:BlockDestroy", "assets/sounds/block_destroy_clap.ogg",
AudioFormat.MONO); "Progressia:BlockDestroy",
AudioFormat.MONO
);
} }
} }

View File

@ -1,3 +1,21 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.audio; package ru.windcorp.progressia.client.audio;
import glm.vec._3.Vec3; import glm.vec._3.Vec3;
@ -5,66 +23,68 @@ import ru.windcorp.progressia.client.audio.backend.Speaker;
import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.util.namespaces.Namespaced;
public class Music extends Namespaced { public class Music extends Namespaced {
private Vec3 position = new Vec3(); private Vec3 position = new Vec3();
private Vec3 velocity = new Vec3(); private Vec3 velocity = new Vec3();
private float pitch = 1.0f; private float pitch = 1.0f;
private float gain = 1.0f; private float gain = 1.0f;
public Music(String id) {
super(id);
}
public Music(String id) public Music(
{ String id,
super(id); Vec3 position,
} Vec3 velocity,
float pitch,
float gain
) {
this(id);
this.position = position;
this.velocity = velocity;
this.pitch = pitch;
this.gain = gain;
}
public Music(String id, public void play(boolean loop) {
Vec3 position, Speaker speaker = AudioManager.initMusicSpeaker(this.getId());
Vec3 velocity, speaker.setGain(gain);
float pitch, speaker.setPitch(pitch);
float gain) speaker.setPosition(position);
{ speaker.setVelocity(velocity);
this(id);
this.position = position;
this.velocity = velocity;
this.pitch = pitch;
this.gain = gain;
}
public void play(boolean loop) if (loop) {
{ speaker.playLoop();
Speaker speaker = AudioManager.initMusicSpeaker(this.getId()); } else {
speaker.setGain(gain); speaker.play();
speaker.setPitch(pitch); }
speaker.setPosition(position); }
speaker.setVelocity(velocity);
if (loop) { public void setGain(float gain) {
speaker.playLoop(); this.gain = gain;
} else { }
speaker.play();
}
}
public void setGain(float gain) { public void setPitch(float pitch) {
this.gain = gain; this.pitch = pitch;
} }
public void setPitch(float pitch) { this.pitch = pitch; } public void setVelocity(Vec3 velocity) {
this.velocity = velocity;
}
public void setVelocity(Vec3 velocity) { public Vec3 getPosition() {
this.velocity = velocity; return position;
} }
public Vec3 getPosition() { return position; } public float getGain() {
return gain;
}
public float getGain() { public Vec3 getVelocity() {
return gain; return velocity;
} }
public Vec3 getVelocity() { public float getPitch() {
return velocity; return pitch;
} }
public float getPitch() {
return pitch;
}
} }

View File

@ -1,3 +1,21 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.audio; package ru.windcorp.progressia.client.audio;
import glm.vec._3.Vec3; import glm.vec._3.Vec3;
@ -5,74 +23,74 @@ import ru.windcorp.progressia.client.audio.backend.Speaker;
import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.util.namespaces.Namespaced;
public class SoundEffect public class SoundEffect
extends Namespaced { extends Namespaced {
private Vec3 position = new Vec3(); private Vec3 position = new Vec3();
private Vec3 velocity = new Vec3(); private Vec3 velocity = new Vec3();
private float pitch = 1.0f; private float pitch = 1.0f;
private float gain = 1.0f; private float gain = 1.0f;
public SoundEffect(String id) {
super(id);
}
public SoundEffect(String id) public SoundEffect(
{ String id,
super(id); Vec3 position,
} Vec3 velocity,
float pitch,
float gain
) {
this(id);
this.position = position;
this.velocity = velocity;
this.pitch = pitch;
this.gain = gain;
}
public SoundEffect(String id, public void play(boolean loop) {
Vec3 position, Speaker speaker = AudioManager.initSpeaker(this.getId());
Vec3 velocity, speaker.setGain(gain);
float pitch, speaker.setPitch(pitch);
float gain) speaker.setPosition(position);
{ speaker.setVelocity(velocity);
this(id);
this.position = position;
this.velocity = velocity;
this.pitch = pitch;
this.gain = gain;
}
public void play(boolean loop) if (loop) {
{ speaker.playLoop();
Speaker speaker = AudioManager.initSpeaker(this.getId()); } else {
speaker.setGain(gain); speaker.play();
speaker.setPitch(pitch); }
speaker.setPosition(position); }
speaker.setVelocity(velocity);
if (loop) { public void setGain(float gain) {
speaker.playLoop(); this.gain = gain;
} else { }
speaker.play();
}
}
public void setGain(float gain) { public void setPitch(float pitch) {
this.gain = gain; this.pitch = pitch;
} }
public void setPitch(float pitch) { this.pitch = pitch; } public void setPosition(Vec3 position) {
this.position = position;
}
public void setPosition(Vec3 position) { public void setVelocity(Vec3 velocity) {
this.position = position; this.velocity = velocity;
} }
public void setVelocity(Vec3 velocity) { public Vec3 getPosition() {
this.velocity = velocity; return position;
} }
public Vec3 getPosition() { public float getGain() {
return position; return gain;
} }
public float getGain() { public Vec3 getVelocity() {
return gain; return velocity;
} }
public Vec3 getVelocity() { public float getPitch() {
return velocity; return pitch;
} }
public float getPitch() {
return pitch;
}
} }

View File

@ -1,3 +1,21 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.audio.backend; package ru.windcorp.progressia.client.audio.backend;
import org.lwjgl.BufferUtils; import org.lwjgl.BufferUtils;
@ -11,7 +29,8 @@ import static org.lwjgl.openal.AL10.*;
public class AudioReader { public class AudioReader {
private AudioReader() {} private AudioReader() {
}
// TODO fix converting from mono-stereo // TODO fix converting from mono-stereo
private static SoundType readAsSpecified(String path, String id, int format) { private static SoundType readAsSpecified(String path, String id, int format) {
@ -22,27 +41,31 @@ public class AudioReader {
ShortBuffer rawAudio = decodeVorbis(res, channelBuffer, rateBuffer); ShortBuffer rawAudio = decodeVorbis(res, channelBuffer, rateBuffer);
return new SoundType(id, rawAudio, format, return new SoundType(
rateBuffer.get(0)); id,
rawAudio,
format,
rateBuffer.get(0)
);
} }
public static SoundType readAsMono(String path, String id) { public static SoundType readAsMono(String path, String id) {
return readAsSpecified(path, id, AL_FORMAT_MONO16); return readAsSpecified(path, id, AL_FORMAT_MONO16);
} }
public static SoundType readAsStereo(String path,String id) { public static SoundType readAsStereo(String path, String id) {
return readAsSpecified(path, id, AL_FORMAT_STEREO16); return readAsSpecified(path, id, AL_FORMAT_STEREO16);
} }
private static ShortBuffer decodeVorbis( private static ShortBuffer decodeVorbis(
Resource dataToDecode, Resource dataToDecode,
IntBuffer channelsBuffer, IntBuffer channelsBuffer,
IntBuffer rateBuffer IntBuffer rateBuffer
) { ) {
return stb_vorbis_decode_memory( return stb_vorbis_decode_memory(
dataToDecode.readAsBytes(), dataToDecode.readAsBytes(),
channelsBuffer, channelsBuffer,
rateBuffer rateBuffer
); );
} }
} }

View File

@ -1,3 +1,21 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.audio.backend; package ru.windcorp.progressia.client.audio.backend;
import glm.vec._3.Vec3; import glm.vec._3.Vec3;
@ -12,7 +30,8 @@ public class Listener {
private static final Listener INSTANCE = new Listener(); private static final Listener INSTANCE = new Listener();
private Listener() {} private Listener() {
}
public static Listener getInstance() { public static Listener getInstance() {
return INSTANCE; return INSTANCE;
@ -37,7 +56,7 @@ public class Listener {
if (wasInWorld) { if (wasInWorld) {
velocity.set(camera.getLastAnchorPosition()).sub(position).div( velocity.set(camera.getLastAnchorPosition()).sub(position).div(
(float) GraphicsInterface.getFrameLength() (float) GraphicsInterface.getFrameLength()
); );
} else { } else {
// If !wasInWorld, previous position is nonsence. Assume 0. // If !wasInWorld, previous position is nonsence. Assume 0.
@ -72,9 +91,17 @@ public class Listener {
private void applyParams() { private void applyParams() {
alListener3f(AL_POSITION, position.x, position.y, position.z); alListener3f(AL_POSITION, position.x, position.y, position.z);
alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z); alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z);
alListenerfv(AL_ORIENTATION, new float[] { alListenerfv(
oriAt.x, oriAt.y, oriAt.z, oriUp.x, oriUp.y, oriUp.z AL_ORIENTATION,
}); new float[] {
oriAt.x,
oriAt.y,
oriAt.z,
oriUp.x,
oriUp.y,
oriUp.z
}
);
} }
} }

View File

@ -1,3 +1,21 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.audio.backend; package ru.windcorp.progressia.client.audio.backend;
import ru.windcorp.progressia.common.util.namespaces.Namespaced; import ru.windcorp.progressia.common.util.namespaces.Namespaced;
@ -12,8 +30,12 @@ public class SoundType extends Namespaced {
private int format; private int format;
private int audioBuffer; private int audioBuffer;
public SoundType(String id, ShortBuffer rawAudio, public SoundType(
int format, int sampleRate) { String id,
ShortBuffer rawAudio,
int format,
int sampleRate
) {
super(id); super(id);
this.rawAudio = rawAudio; this.rawAudio = rawAudio;
this.sampleRate = sampleRate; this.sampleRate = sampleRate;

View File

@ -1,3 +1,21 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.audio.backend; package ru.windcorp.progressia.client.audio.backend;
import glm.vec._3.Vec3; import glm.vec._3.Vec3;
@ -5,147 +23,145 @@ import static org.lwjgl.openal.AL11.*;
public class Speaker { public class Speaker {
public enum State { public enum State {
NOT_PLAYING, NOT_PLAYING,
PLAYING, PLAYING,
PLAYING_LOOP PLAYING_LOOP
} }
// Buffers // Buffers
private int audioData; private int audioData;
private int sourceData; private int sourceData;
// Characteristics // Characteristics
private Vec3 position = new Vec3(); private Vec3 position = new Vec3();
private Vec3 velocity = new Vec3(); private Vec3 velocity = new Vec3();
private float pitch = 1.0f; private float pitch = 1.0f;
private float gain = 1.0f; private float gain = 1.0f;
private State state = State.NOT_PLAYING; private State state = State.NOT_PLAYING;
public Speaker() { public Speaker() {
sourceData = alGenSources(); sourceData = alGenSources();
} }
public Speaker(int audioData) { public Speaker(int audioData) {
this(); this();
setAudioData(audioData); setAudioData(audioData);
} }
public Speaker( public Speaker(
int audioData, int audioData,
Vec3 position, Vec3 position,
Vec3 velocity, Vec3 velocity,
float pitch, float pitch,
float gain float gain
) { ) {
setAudioData(audioData); setAudioData(audioData);
setPosition(position); setPosition(position);
setVelocity(velocity); setVelocity(velocity);
setPitch(pitch); setPitch(pitch);
setGain(gain); setGain(gain);
} }
public Speaker( public Speaker(
Vec3 position, Vec3 position,
Vec3 velocity, Vec3 velocity,
float pitch, float pitch,
float gain float gain
) { ) {
setPosition(position); setPosition(position);
setVelocity(velocity); setVelocity(velocity);
setPitch(pitch); setPitch(pitch);
setGain(gain); setGain(gain);
} }
public void play() { public void play() {
alSourcePlay(sourceData); alSourcePlay(sourceData);
state = State.PLAYING; state = State.PLAYING;
} }
public void playLoop() { public void playLoop() {
alSourcei(sourceData, AL_LOOPING, AL_TRUE); alSourcei(sourceData, AL_LOOPING, AL_TRUE);
alSourcePlay(sourceData); alSourcePlay(sourceData);
state = State.PLAYING_LOOP; state = State.PLAYING_LOOP;
} }
public void stop() { public void stop() {
alSourceStop(sourceData); alSourceStop(sourceData);
if (state == State.PLAYING_LOOP) { if (state == State.PLAYING_LOOP) {
alSourcei(sourceData, AL_LOOPING, AL_FALSE); alSourcei(sourceData, AL_LOOPING, AL_FALSE);
} }
state = State.NOT_PLAYING; state = State.NOT_PLAYING;
} }
public void pause() { public void pause() {
alSourcePause(sourceData); alSourcePause(sourceData);
state = State.NOT_PLAYING; state = State.NOT_PLAYING;
} }
public boolean isPlaying() { public boolean isPlaying() {
final int speakerState = alGetSourcei(sourceData, AL_SOURCE_STATE); final int speakerState = alGetSourcei(sourceData, AL_SOURCE_STATE);
if (speakerState == AL_PLAYING) { if (speakerState == AL_PLAYING) {
return true; return true;
} } else {
else { state = State.NOT_PLAYING;
state = State.NOT_PLAYING; return false;
return false; }
} }
}
// GETTERS & SETTERS // GETTERS & SETTERS
public int getAudioData() { public int getAudioData() {
return audioData; return audioData;
} }
public int getSourceData() { public int getSourceData() {
return sourceData; return sourceData;
} }
public void setAudioData(int audioData) { public void setAudioData(int audioData) {
this.audioData = audioData; this.audioData = audioData;
alSourcei(this.sourceData, AL_BUFFER, audioData); alSourcei(this.sourceData, AL_BUFFER, audioData);
} }
public void setPosition(Vec3 position) { public void setPosition(Vec3 position) {
this.position = position; this.position = position;
alSource3f(sourceData, AL_POSITION, position.x, position.y, position.z); alSource3f(sourceData, AL_POSITION, position.x, position.y, position.z);
} }
public Vec3 getPosition() { public Vec3 getPosition() {
return position; return position;
} }
public void setVelocity(Vec3 velocity) { public void setVelocity(Vec3 velocity) {
alSource3f(sourceData, AL_VELOCITY, velocity.x, velocity.y, velocity.z); alSource3f(sourceData, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
this.velocity = velocity; this.velocity = velocity;
} }
public Vec3 getVelocity() { public Vec3 getVelocity() {
return velocity; return velocity;
} }
public void setPitch(float pitch) { public void setPitch(float pitch) {
alSourcef(sourceData, AL_PITCH, pitch); alSourcef(sourceData, AL_PITCH, pitch);
this.pitch = pitch; this.pitch = pitch;
} }
public float getPitch() { public float getPitch() {
return pitch; return pitch;
} }
public void setGain(float gain) { public void setGain(float gain) {
alSourcef(sourceData, AL_GAIN, gain); alSourcef(sourceData, AL_GAIN, gain);
this.gain = gain; this.gain = gain;
} }
public float getGain() { public float getGain() {
return gain; return gain;
} }
public State getState() public State getState() {
{ return state;
return state; }
}
} }

View File

@ -1,46 +1,64 @@
package ru.windcorp.progressia.client.comms; /*
* Progressia
import java.io.IOException; * Copyright (C) 2020-2021 Wind Corporation and contributors
*
import ru.windcorp.progressia.client.Client; * This program is free software: you can redistribute it and/or modify
import ru.windcorp.progressia.common.comms.CommsListener; * it under the terms of the GNU General Public License as published by
import ru.windcorp.progressia.common.comms.packets.Packet; * the Free Software Foundation, either version 3 of the License, or
import ru.windcorp.progressia.common.util.crash.CrashReports; * (at your option) any later version.
import ru.windcorp.progressia.common.world.PacketSetLocalPlayer; *
import ru.windcorp.progressia.common.world.PacketAffectWorld; * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
// TODO refactor with no mercy * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
public class DefaultClientCommsListener implements CommsListener { * GNU General Public License for more details.
*
private final Client client; * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
public DefaultClientCommsListener(Client client) { */
this.client = client;
} package ru.windcorp.progressia.client.comms;
@Override import java.io.IOException;
public void onPacketReceived(Packet packet) {
if (packet instanceof PacketAffectWorld) { import ru.windcorp.progressia.client.Client;
((PacketAffectWorld) packet).apply( import ru.windcorp.progressia.common.comms.CommsListener;
getClient().getWorld().getData() import ru.windcorp.progressia.common.comms.packets.Packet;
); import ru.windcorp.progressia.common.util.crash.CrashReports;
} else if (packet instanceof PacketSetLocalPlayer) { import ru.windcorp.progressia.common.world.PacketSetLocalPlayer;
setLocalPlayer((PacketSetLocalPlayer) packet); import ru.windcorp.progressia.common.world.PacketAffectWorld;
}
} // TODO refactor with no mercy
public class DefaultClientCommsListener implements CommsListener {
private void setLocalPlayer(PacketSetLocalPlayer packet) {
getClient().getLocalPlayer().setEntityId(packet.getEntityId()); private final Client client;
}
public DefaultClientCommsListener(Client client) {
@Override this.client = client;
public void onIOError(IOException reason) { }
throw CrashReports.report(reason, "An IOException has occurred in communications");
// TODO implement @Override
} public void onPacketReceived(Packet packet) {
if (packet instanceof PacketAffectWorld) {
public Client getClient() { ((PacketAffectWorld) packet).apply(
return client; getClient().getWorld().getData()
} );
} else if (packet instanceof PacketSetLocalPlayer) {
} setLocalPlayer((PacketSetLocalPlayer) packet);
}
}
private void setLocalPlayer(PacketSetLocalPlayer packet) {
getClient().getLocalPlayer().setEntityId(packet.getEntityId());
}
@Override
public void onIOError(IOException reason) {
throw CrashReports.report(reason, "An IOException has occurred in communications");
// TODO implement
}
public Client getClient() {
return client;
}
}

View File

@ -1,7 +1,25 @@
package ru.windcorp.progressia.client.comms; /*
* Progressia
import ru.windcorp.progressia.common.comms.CommsChannel; * Copyright (C) 2020-2021 Wind Corporation and contributors
*
public abstract class ServerCommsChannel extends CommsChannel { * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
} * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.comms;
import ru.windcorp.progressia.common.comms.CommsChannel;
public abstract class ServerCommsChannel extends CommsChannel {
}

View File

@ -1,11 +1,29 @@
package ru.windcorp.progressia.client.comms.controls; /*
* Progressia
import ru.windcorp.progressia.common.util.namespaces.Namespaced; * Copyright (C) 2020-2021 Wind Corporation and contributors
*
public abstract class ControlTrigger extends Namespaced { * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
public ControlTrigger(String id) { * the Free Software Foundation, either version 3 of the License, or
super(id); * (at your option) any later version.
} *
* This program is distributed in the hope that it will be useful,
} * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.comms.controls;
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
public abstract class ControlTrigger extends Namespaced {
public ControlTrigger(String id) {
super(id);
}
}

View File

@ -1,14 +1,32 @@
package ru.windcorp.progressia.client.comms.controls; /*
* Progressia
import ru.windcorp.progressia.client.graphics.input.InputEvent; * Copyright (C) 2020-2021 Wind Corporation and contributors
import ru.windcorp.progressia.common.comms.controls.PacketControl; *
* This program is free software: you can redistribute it and/or modify
public abstract class ControlTriggerInputBased extends ControlTrigger { * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
public ControlTriggerInputBased(String id) { * (at your option) any later version.
super(id); *
} * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
public abstract PacketControl onInputEvent(InputEvent event); * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
} *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.comms.controls;
import ru.windcorp.progressia.client.graphics.input.InputEvent;
import ru.windcorp.progressia.common.comms.controls.PacketControl;
public abstract class ControlTriggerInputBased extends ControlTrigger {
public ControlTriggerInputBased(String id) {
super(id);
}
public abstract PacketControl onInputEvent(InputEvent event);
}

View File

@ -1,48 +1,67 @@
package ru.windcorp.progressia.client.comms.controls; /*
* Progressia
import java.util.function.BiConsumer; * Copyright (C) 2020-2021 Wind Corporation and contributors
import java.util.function.Predicate; *
* This program is free software: you can redistribute it and/or modify
import ru.windcorp.progressia.client.graphics.input.InputEvent; * it under the terms of the GNU General Public License as published by
import ru.windcorp.progressia.common.comms.controls.ControlData; * the Free Software Foundation, either version 3 of the License, or
import ru.windcorp.progressia.common.comms.controls.ControlDataRegistry; * (at your option) any later version.
import ru.windcorp.progressia.common.comms.controls.PacketControl; *
import ru.windcorp.progressia.common.util.namespaces.NamespacedUtil; * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
public class ControlTriggerLambda extends ControlTriggerInputBased { * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
private final String packetId; *
private final Predicate<InputEvent> predicate; * You should have received a copy of the GNU General Public License
private final BiConsumer<InputEvent, ControlData> dataWriter; * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
public ControlTriggerLambda(
String id, package ru.windcorp.progressia.client.comms.controls;
Predicate<InputEvent> predicate,
BiConsumer<InputEvent, ControlData> dataWriter import java.util.function.BiConsumer;
) { import java.util.function.Predicate;
super(id);
import ru.windcorp.progressia.client.graphics.input.InputEvent;
this.packetId = NamespacedUtil.getId( import ru.windcorp.progressia.common.comms.controls.ControlData;
NamespacedUtil.getNamespace(id), import ru.windcorp.progressia.common.comms.controls.ControlDataRegistry;
"ControlKeyPress" + NamespacedUtil.getName(id) import ru.windcorp.progressia.common.comms.controls.PacketControl;
); import ru.windcorp.progressia.common.util.namespaces.NamespacedUtil;
this.predicate = predicate; public class ControlTriggerLambda extends ControlTriggerInputBased {
this.dataWriter = dataWriter;
} private final String packetId;
private final Predicate<InputEvent> predicate;
@Override private final BiConsumer<InputEvent, ControlData> dataWriter;
public PacketControl onInputEvent(InputEvent event) {
if (!predicate.test(event)) return null; public ControlTriggerLambda(
String id,
PacketControl packet = new PacketControl( Predicate<InputEvent> predicate,
packetId, BiConsumer<InputEvent, ControlData> dataWriter
ControlDataRegistry.getInstance().create(getId()) ) {
); super(id);
dataWriter.accept(event, packet.getControl()); this.packetId = NamespacedUtil.getId(
NamespacedUtil.getNamespace(id),
return packet; "ControlKeyPress" + NamespacedUtil.getName(id)
} );
} this.predicate = predicate;
this.dataWriter = dataWriter;
}
@Override
public PacketControl onInputEvent(InputEvent event) {
if (!predicate.test(event))
return null;
PacketControl packet = new PacketControl(
packetId,
ControlDataRegistry.getInstance().create(getId())
);
dataWriter.accept(event, packet.getControl());
return packet;
}
}

View File

@ -1,14 +1,31 @@
package ru.windcorp.progressia.client.comms.controls; /*
* Progressia
import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry; * Copyright (C) 2020-2021 Wind Corporation and contributors
*
public class ControlTriggerRegistry extends NamespacedInstanceRegistry<ControlTrigger> { * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
private static final ControlTriggerRegistry INSTANCE = * the Free Software Foundation, either version 3 of the License, or
new ControlTriggerRegistry(); * (at your option) any later version.
*
public static ControlTriggerRegistry getInstance() { * This program is distributed in the hope that it will be useful,
return INSTANCE; * but WITHOUT ANY WARRANTY; without even the implied warranty of
} * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
} *
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.comms.controls;
import ru.windcorp.progressia.common.util.namespaces.NamespacedInstanceRegistry;
public class ControlTriggerRegistry extends NamespacedInstanceRegistry<ControlTrigger> {
private static final ControlTriggerRegistry INSTANCE = new ControlTriggerRegistry();
public static ControlTriggerRegistry getInstance() {
return INSTANCE;
}
}

View File

@ -1,3 +1,21 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.comms.controls; package ru.windcorp.progressia.client.comms.controls;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
@ -8,145 +26,142 @@ import ru.windcorp.progressia.client.graphics.input.InputEvent;
import ru.windcorp.progressia.common.comms.controls.ControlData; import ru.windcorp.progressia.common.comms.controls.ControlData;
public class ControlTriggers { public class ControlTriggers {
public static ControlTriggerInputBased of( public static ControlTriggerInputBased of(
String id, String id,
BiConsumer<InputEvent, ControlData> dataWriter, BiConsumer<InputEvent, ControlData> dataWriter,
Predicate<InputEvent> predicate Predicate<InputEvent> predicate
) { ) {
return new ControlTriggerLambda(id, predicate, dataWriter); return new ControlTriggerLambda(id, predicate, dataWriter);
} }
public static ControlTriggerInputBased of( public static ControlTriggerInputBased of(
String id, String id,
Consumer<ControlData> dataWriter, Consumer<ControlData> dataWriter,
Predicate<InputEvent> predicate Predicate<InputEvent> predicate
) { ) {
return of( return of(
id, id,
(input, control) -> dataWriter.accept(control), (input, control) -> dataWriter.accept(control),
predicate predicate
);
}
public static ControlTriggerInputBased of(
String id,
Predicate<InputEvent> predicate
) {
return of(
id,
(input, control) -> {},
predicate
);
}
@SafeVarargs
public static <I extends InputEvent> ControlTriggerInputBased of(
String id,
Class<I> inputType,
BiConsumer<I, ControlData> dataWriter,
Predicate<I>... predicates
) {
return of(
id,
createCheckedDataWriter(inputType, dataWriter),
createCheckedCompoundPredicate(inputType, predicates)
);
}
@SafeVarargs
public static <I extends InputEvent> ControlTriggerInputBased of(
String id,
Class<I> inputType,
Consumer<ControlData> dataWriter,
Predicate<I>... predicates
) {
return of(
id,
inputType,
(input, control) -> dataWriter.accept(control),
predicates
);
}
@SafeVarargs
public static <I extends InputEvent> ControlTriggerInputBased of(
String id,
Class<I> inputType,
Predicate<I>... predicates
) {
return of(
id,
(input, control) -> {},
createCheckedCompoundPredicate(inputType, predicates)
);
}
@SafeVarargs
public static ControlTriggerInputBased of(
String id,
BiConsumer<InputEvent, ControlData> dataWriter,
Predicate<InputEvent>... predicates
) {
return of(
id,
InputEvent.class,
dataWriter,
predicates
);
}
@SafeVarargs
public static <I extends InputEvent> ControlTriggerInputBased of(
String id,
Consumer<ControlData> dataWriter,
Predicate<InputEvent>... predicates
) {
return of(
id,
(input, control) -> dataWriter.accept(control),
predicates
);
}
@SafeVarargs
public static ControlTriggerInputBased of(
String id,
Predicate<InputEvent>... predicates
) {
return of(
id,
InputEvent.class,
(input, control) -> {},
predicates
); );
} }
private static public static ControlTriggerInputBased of(
<I extends InputEvent> String id,
BiConsumer<InputEvent, ControlData> Predicate<InputEvent> predicate
createCheckedDataWriter( ) {
Class<I> inputType, return of(
BiConsumer<I, ControlData> dataWriter id,
(input, control) -> {
},
predicate
);
}
@SafeVarargs
public static <I extends InputEvent> ControlTriggerInputBased of(
String id,
Class<I> inputType,
BiConsumer<I, ControlData> dataWriter,
Predicate<I>... predicates
) {
return of(
id,
createCheckedDataWriter(inputType, dataWriter),
createCheckedCompoundPredicate(inputType, predicates)
);
}
@SafeVarargs
public static <I extends InputEvent> ControlTriggerInputBased of(
String id,
Class<I> inputType,
Consumer<ControlData> dataWriter,
Predicate<I>... predicates
) {
return of(
id,
inputType,
(input, control) -> dataWriter.accept(control),
predicates
);
}
@SafeVarargs
public static <I extends InputEvent> ControlTriggerInputBased of(
String id,
Class<I> inputType,
Predicate<I>... predicates
) {
return of(
id,
(input, control) -> {
},
createCheckedCompoundPredicate(inputType, predicates)
);
}
@SafeVarargs
public static ControlTriggerInputBased of(
String id,
BiConsumer<InputEvent, ControlData> dataWriter,
Predicate<InputEvent>... predicates
) {
return of(
id,
InputEvent.class,
dataWriter,
predicates
);
}
@SafeVarargs
public static <I extends InputEvent> ControlTriggerInputBased of(
String id,
Consumer<ControlData> dataWriter,
Predicate<InputEvent>... predicates
) {
return of(
id,
(input, control) -> dataWriter.accept(control),
predicates
);
}
@SafeVarargs
public static ControlTriggerInputBased of(
String id,
Predicate<InputEvent>... predicates
) {
return of(
id,
InputEvent.class,
(input, control) -> {
},
predicates
);
}
private static <I extends InputEvent> BiConsumer<InputEvent, ControlData> createCheckedDataWriter(
Class<I> inputType,
BiConsumer<I, ControlData> dataWriter
) { ) {
return (inputEvent, control) -> dataWriter.accept(inputType.cast(inputEvent), control); return (inputEvent, control) -> dataWriter.accept(inputType.cast(inputEvent), control);
} }
private static private static <I extends InputEvent> Predicate<InputEvent> createCheckedCompoundPredicate(
<I extends InputEvent> Class<I> inputType,
Predicate<InputEvent> Predicate<I>[] predicates
createCheckedCompoundPredicate(
Class<I> inputType,
Predicate<I>[] predicates
) { ) {
return new CompoundCastPredicate<>(inputType, predicates); return new CompoundCastPredicate<>(inputType, predicates);
} }
private static class CompoundCastPredicate<I extends InputEvent> implements Predicate<InputEvent> { private static class CompoundCastPredicate<I extends InputEvent> implements Predicate<InputEvent> {
private final Class<I> inputType; private final Class<I> inputType;
private final Predicate<I>[] predicates; private final Predicate<I>[] predicates;
public CompoundCastPredicate(Class<I> inputType, Predicate<I>[] predicates) { public CompoundCastPredicate(Class<I> inputType, Predicate<I>[] predicates) {
this.inputType = inputType; this.inputType = inputType;
this.predicates = predicates; this.predicates = predicates;
@ -157,20 +172,21 @@ public class ControlTriggers {
if (!inputType.isInstance(inputEvent)) { if (!inputType.isInstance(inputEvent)) {
return false; return false;
} }
I castEvent = inputType.cast(inputEvent); I castEvent = inputType.cast(inputEvent);
for (Predicate<I> predicate : predicates) { for (Predicate<I> predicate : predicates) {
if (!predicate.test(castEvent)) { if (!predicate.test(castEvent)) {
return false; return false;
} }
} }
return true; return true;
} }
} }
private ControlTriggers() {} private ControlTriggers() {
}
} }

View File

@ -1,33 +1,51 @@
package ru.windcorp.progressia.client.comms.controls; /*
* Progressia
import ru.windcorp.progressia.client.Client; * Copyright (C) 2020-2021 Wind Corporation and contributors
import ru.windcorp.progressia.client.graphics.input.bus.Input; *
import ru.windcorp.progressia.common.comms.packets.Packet; * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
public class InputBasedControls { * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
private final Client client; *
* This program is distributed in the hope that it will be useful,
private final ControlTriggerInputBased[] controls; * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
public InputBasedControls(Client client) { * GNU General Public License for more details.
this.client = client; *
* You should have received a copy of the GNU General Public License
this.controls = ControlTriggerRegistry.getInstance().values().stream() * along with this program. If not, see <https://www.gnu.org/licenses/>.
.filter(ControlTriggerInputBased.class::isInstance) */
.toArray(ControlTriggerInputBased[]::new);
} package ru.windcorp.progressia.client.comms.controls;
public void handleInput(Input input) { import ru.windcorp.progressia.client.Client;
for (ControlTriggerInputBased c : controls) { import ru.windcorp.progressia.client.graphics.input.bus.Input;
Packet packet = c.onInputEvent(input.getEvent()); import ru.windcorp.progressia.common.comms.packets.Packet;
if (packet != null) { public class InputBasedControls {
input.consume();
client.getComms().sendPacket(packet); private final Client client;
break;
} private final ControlTriggerInputBased[] controls;
}
} public InputBasedControls(Client client) {
this.client = client;
}
this.controls = ControlTriggerRegistry.getInstance().values().stream()
.filter(ControlTriggerInputBased.class::isInstance)
.toArray(ControlTriggerInputBased[]::new);
}
public void handleInput(Input input) {
for (ControlTriggerInputBased c : controls) {
Packet packet = c.onInputEvent(input.getEvent());
if (packet != null) {
input.consume();
client.getComms().sendPacket(packet);
break;
}
}
}
}

View File

@ -1,41 +1,59 @@
package ru.windcorp.progressia.client.comms.localhost; /*
* Progressia
import java.io.IOException; * Copyright (C) 2020-2021 Wind Corporation and contributors
*
import ru.windcorp.progressia.common.comms.packets.Packet; * This program is free software: you can redistribute it and/or modify
import ru.windcorp.progressia.server.comms.ClientPlayer; * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
public class LocalClient extends ClientPlayer { * (at your option) any later version.
*
private final LocalServerCommsChannel serverComms; * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
private final String login; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
public LocalClient(int id, String login, LocalServerCommsChannel serverComms) { *
super(id); * You should have received a copy of the GNU General Public License
setState(State.CONNECTED); * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
this.serverComms = serverComms;
this.login = login; package ru.windcorp.progressia.client.comms.localhost;
}
import java.io.IOException;
@Override
public String getLogin() { import ru.windcorp.progressia.common.comms.packets.Packet;
return this.login; import ru.windcorp.progressia.server.comms.ClientPlayer;
}
public class LocalClient extends ClientPlayer {
@Override
protected void doSendPacket(Packet packet) throws IOException { private final LocalServerCommsChannel serverComms;
this.serverComms.relayPacketToClient(packet);
} private final String login;
public void relayPacketToServer(Packet packet) { public LocalClient(int id, String login, LocalServerCommsChannel serverComms) {
onPacketReceived(packet); super(id);
} setState(State.CONNECTED);
@Override this.serverComms = serverComms;
public void disconnect() { this.login = login;
// Do nothing }
}
@Override
} public String getLogin() {
return this.login;
}
@Override
protected void doSendPacket(Packet packet) throws IOException {
this.serverComms.relayPacketToClient(packet);
}
public void relayPacketToServer(Packet packet) {
onPacketReceived(packet);
}
@Override
public void disconnect() {
// Do nothing
}
}

View File

@ -1,42 +1,60 @@
package ru.windcorp.progressia.client.comms.localhost; /*
* Progressia
import ru.windcorp.progressia.client.comms.ServerCommsChannel; * Copyright (C) 2020-2021 Wind Corporation and contributors
import ru.windcorp.progressia.common.comms.packets.Packet; *
import ru.windcorp.progressia.server.Server; * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
public class LocalServerCommsChannel extends ServerCommsChannel { * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
private LocalClient localClient; *
private final Server server; * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
public LocalServerCommsChannel(Server server) { * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
this.server = server; * GNU General Public License for more details.
} *
* You should have received a copy of the GNU General Public License
public void connect(String login) { * along with this program. If not, see <https://www.gnu.org/licenses/>.
setState(State.CONNECTED); */
this.localClient = new LocalClient( package ru.windcorp.progressia.client.comms.localhost;
server.getClientManager().grabClientId(),
login, import ru.windcorp.progressia.client.comms.ServerCommsChannel;
this import ru.windcorp.progressia.common.comms.packets.Packet;
); import ru.windcorp.progressia.server.Server;
server.getClientManager().addClient(localClient); public class LocalServerCommsChannel extends ServerCommsChannel {
}
private LocalClient localClient;
@Override private final Server server;
protected void doSendPacket(Packet packet) {
localClient.relayPacketToServer(packet); public LocalServerCommsChannel(Server server) {
} this.server = server;
}
public void relayPacketToClient(Packet packet) {
onPacketReceived(packet); public void connect(String login) {
} setState(State.CONNECTED);
@Override this.localClient = new LocalClient(
public void disconnect() { server.getClientManager().grabClientId(),
// Do nothing login,
} this
);
}
server.getClientManager().addClient(localClient);
}
@Override
protected void doSendPacket(Packet packet) {
localClient.relayPacketToServer(packet);
}
public void relayPacketToClient(Packet packet) {
onPacketReceived(packet);
}
@Override
public void disconnect() {
// Do nothing
}
}

View File

@ -1,61 +1,62 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics;
package ru.windcorp.progressia.client.graphics;
import glm.vec._4.Vec4;
import glm.vec._4.Vec4;
public class Colors {
public class Colors {
public static final Vec4
WHITE = toVector(0xFFFFFFFF), public static final Vec4 WHITE = toVector(0xFFFFFFFF),
BLACK = toVector(0xFF000000), BLACK = toVector(0xFF000000),
GRAY_4 = toVector(0xFF444444), GRAY_4 = toVector(0xFF444444),
GRAY = toVector(0xFF888888), GRAY = toVector(0xFF888888),
GRAY_A = toVector(0xFFAAAAAA), GRAY_A = toVector(0xFFAAAAAA),
DEBUG_RED = toVector(0xFFFF0000), DEBUG_RED = toVector(0xFFFF0000),
DEBUG_GREEN = toVector(0xFF00FF00), DEBUG_GREEN = toVector(0xFF00FF00),
DEBUG_BLUE = toVector(0xFF0000FF), DEBUG_BLUE = toVector(0xFF0000FF),
DEBUG_CYAN = toVector(0xFF00FFFF), DEBUG_CYAN = toVector(0xFF00FFFF),
DEBUG_MAGENTA = toVector(0xFFFF00FF), DEBUG_MAGENTA = toVector(0xFFFF00FF),
DEBUG_YELLOW = toVector(0xFFFFFF00); DEBUG_YELLOW = toVector(0xFFFFFF00);
public static Vec4 toVector(int argb) { public static Vec4 toVector(int argb) {
return toVector(argb, new Vec4()); return toVector(argb, new Vec4());
} }
public static Vec4 multiplyRGB(Vec4 color, float multiplier) { public static Vec4 multiplyRGB(Vec4 color, float multiplier) {
return color.mul(multiplier, multiplier, multiplier, 1); return color.mul(multiplier, multiplier, multiplier, 1);
} }
public static Vec4 multiplyRGB(Vec4 color, float multiplier, Vec4 output) { public static Vec4 multiplyRGB(Vec4 color, float multiplier, Vec4 output) {
if (output == null) output = new Vec4(); if (output == null)
return color.mul(multiplier, multiplier, multiplier, 1, output); output = new Vec4();
} return color.mul(multiplier, multiplier, multiplier, 1, output);
}
public static Vec4 toVector(int argb, Vec4 output) {
output.w = ((argb & 0xFF000000) >>> 24) / (float) 0xFF; // Alpha public static Vec4 toVector(int argb, Vec4 output) {
output.x = ((argb & 0x00FF0000) >>> 16) / (float) 0xFF; // Red output.w = ((argb & 0xFF000000) >>> 24) / (float) 0xFF; // Alpha
output.y = ((argb & 0x0000FF00) >>> 8) / (float) 0xFF; // Green output.x = ((argb & 0x00FF0000) >>> 16) / (float) 0xFF; // Red
output.z = ((argb & 0x000000FF) ) / (float) 0xFF; // Blue output.y = ((argb & 0x0000FF00) >>> 8) / (float) 0xFF; // Green
output.z = ((argb & 0x000000FF)) / (float) 0xFF; // Blue
return output;
} return output;
}
}
}

View File

@ -1,130 +1,133 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics;
package ru.windcorp.progressia.client.graphics;
import java.util.ArrayList;
import java.util.Collections; import java.util.ArrayList;
import java.util.List; import java.util.Collections;
import java.util.List;
import com.google.common.eventbus.Subscribe;
import com.google.common.eventbus.Subscribe;
import ru.windcorp.progressia.client.graphics.input.CursorEvent;
import ru.windcorp.progressia.client.graphics.input.FrameResizeEvent; import ru.windcorp.progressia.client.graphics.input.CursorEvent;
import ru.windcorp.progressia.client.graphics.input.InputEvent; import ru.windcorp.progressia.client.graphics.input.FrameResizeEvent;
import ru.windcorp.progressia.client.graphics.input.KeyEvent; import ru.windcorp.progressia.client.graphics.input.InputEvent;
import ru.windcorp.progressia.client.graphics.input.WheelEvent; import ru.windcorp.progressia.client.graphics.input.KeyEvent;
import ru.windcorp.progressia.client.graphics.input.bus.Input; import ru.windcorp.progressia.client.graphics.input.WheelEvent;
import ru.windcorp.progressia.client.graphics.input.bus.Input;
public class GUI {
public class GUI {
private static final List<Layer> LAYERS = Collections.synchronizedList(new ArrayList<>());
private static final List<Layer> UNMODIFIABLE_LAYERS = Collections.unmodifiableList(LAYERS); private static final List<Layer> LAYERS = Collections.synchronizedList(new ArrayList<>());
private static final List<Layer> UNMODIFIABLE_LAYERS = Collections.unmodifiableList(LAYERS);
@FunctionalInterface
private interface LayerStackModification { @FunctionalInterface
void affect(List<Layer> layers); private interface LayerStackModification {
} void affect(List<Layer> layers);
}
private static final List<LayerStackModification> MODIFICATION_QUEUE = Collections.synchronizedList(new ArrayList<>());
private static final List<LayerStackModification> MODIFICATION_QUEUE = Collections
private static class ModifiableInput extends Input { .synchronizedList(new ArrayList<>());
@Override
public void initialize(InputEvent event, Target target) { private static class ModifiableInput extends Input {
super.initialize(event, target); @Override
} public void initialize(InputEvent event, Target target) {
} super.initialize(event, target);
}
private static final ModifiableInput THE_INPUT = new ModifiableInput(); }
private GUI() {} private static final ModifiableInput THE_INPUT = new ModifiableInput();
public static void addBottomLayer(Layer layer) { private GUI() {
modify(layers -> layers.add(layer)); }
}
public static void addBottomLayer(Layer layer) {
public static void addTopLayer(Layer layer) { modify(layers -> layers.add(layer));
modify(layers -> layers.add(0, layer)); }
}
public static void addTopLayer(Layer layer) {
public static void removeLayer(Layer layer) { modify(layers -> layers.add(0, layer));
modify(layers -> layers.remove(layer)); }
}
public static void removeLayer(Layer layer) {
private static void modify(LayerStackModification mod) { modify(layers -> layers.remove(layer));
MODIFICATION_QUEUE.add(mod); }
}
private static void modify(LayerStackModification mod) {
public static List<Layer> getLayers() { MODIFICATION_QUEUE.add(mod);
return UNMODIFIABLE_LAYERS; }
}
public static List<Layer> getLayers() {
public static void render() { return UNMODIFIABLE_LAYERS;
synchronized (LAYERS) { }
MODIFICATION_QUEUE.forEach(action -> action.affect(LAYERS));
MODIFICATION_QUEUE.clear(); public static void render() {
synchronized (LAYERS) {
for (int i = LAYERS.size() - 1; i >= 0; --i) { MODIFICATION_QUEUE.forEach(action -> action.affect(LAYERS));
LAYERS.get(i).render(); MODIFICATION_QUEUE.clear();
}
} for (int i = LAYERS.size() - 1; i >= 0; --i) {
} LAYERS.get(i).render();
}
public static void invalidateEverything() { }
LAYERS.forEach(Layer::invalidate); }
}
public static void invalidateEverything() {
private static void dispatchInputEvent(InputEvent event) { LAYERS.forEach(Layer::invalidate);
Input.Target target; }
if (event instanceof KeyEvent) { private static void dispatchInputEvent(InputEvent event) {
if (((KeyEvent) event).isMouse()) { Input.Target target;
target = Input.Target.HOVERED;
} else { if (event instanceof KeyEvent) {
target = Input.Target.FOCUSED; if (((KeyEvent) event).isMouse()) {
} target = Input.Target.HOVERED;
} else if (event instanceof CursorEvent) { } else {
target = Input.Target.HOVERED; target = Input.Target.FOCUSED;
} else if (event instanceof WheelEvent) { }
target = Input.Target.HOVERED; } else if (event instanceof CursorEvent) {
} else if (event instanceof FrameResizeEvent) { target = Input.Target.HOVERED;
return; } else if (event instanceof WheelEvent) {
} else { target = Input.Target.HOVERED;
target = Input.Target.ALL; } else if (event instanceof FrameResizeEvent) {
} return;
} else {
THE_INPUT.initialize(event, target); target = Input.Target.ALL;
LAYERS.forEach(l -> l.handleInput(THE_INPUT)); }
}
THE_INPUT.initialize(event, target);
public static Object getEventSubscriber() { LAYERS.forEach(l -> l.handleInput(THE_INPUT));
return new Object() { }
@Subscribe public static Object getEventSubscriber() {
public void onFrameResized(FrameResizeEvent event) { return new Object() {
GUI.invalidateEverything();
} @Subscribe
public void onFrameResized(FrameResizeEvent event) {
@Subscribe GUI.invalidateEverything();
public void onInput(InputEvent event) { }
dispatchInputEvent(event);
} @Subscribe
public void onInput(InputEvent event) {
}; dispatchInputEvent(event);
} }
} };
}
}

View File

@ -1,81 +1,82 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics;
package ru.windcorp.progressia.client.graphics;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicBoolean;
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
import ru.windcorp.progressia.client.graphics.input.bus.Input; import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
import ru.windcorp.progressia.client.graphics.input.bus.Input;
public abstract class Layer {
public abstract class Layer {
private final String name;
private final String name;
private boolean hasInitialized = false;
private boolean hasInitialized = false;
private final AtomicBoolean isValid = new AtomicBoolean(false);
private final AtomicBoolean isValid = new AtomicBoolean(false);
public Layer(String name) {
this.name = name; public Layer(String name) {
} this.name = name;
}
@Override
public String toString() { @Override
return "Layer " + name; public String toString() {
} return "Layer " + name;
}
void render() {
GraphicsInterface.startNextLayer(); void render() {
GraphicsInterface.startNextLayer();
validate();
validate();
if (!hasInitialized) {
initialize(); if (!hasInitialized) {
hasInitialized = true; initialize();
} hasInitialized = true;
}
doRender();
} doRender();
}
void validate() {
if (isValid.compareAndSet(false, true)) { void validate() {
doValidate(); if (isValid.compareAndSet(false, true)) {
} doValidate();
} }
}
public void invalidate() {
isValid.set(false); public void invalidate() {
} isValid.set(false);
}
protected abstract void initialize();
protected abstract void initialize();
protected abstract void doValidate();
protected abstract void doValidate();
protected abstract void doRender();
protected abstract void doRender();
protected abstract void handleInput(Input input);
protected abstract void handleInput(Input input);
protected int getWidth() {
return GraphicsInterface.getFrameWidth(); protected int getWidth() {
} return GraphicsInterface.getFrameWidth();
}
protected int getHeight() {
return GraphicsInterface.getFrameHeight(); protected int getHeight() {
} return GraphicsInterface.getFrameHeight();
}
}
}

View File

@ -1,27 +1,46 @@
/*
* Progressia
* Copyright (C) 2020-2021 Wind Corporation and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package ru.windcorp.progressia.client.graphics.backend; package ru.windcorp.progressia.client.graphics.backend;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Deque; import java.util.Deque;
public class FaceCulling { public class FaceCulling {
private static final Deque<Boolean> STACK = new ArrayDeque<>(); private static final Deque<Boolean> STACK = new ArrayDeque<>();
public static void push(boolean useFaceCulling) { public static void push(boolean useFaceCulling) {
GraphicsBackend.setFaceCulling(useFaceCulling); GraphicsBackend.setFaceCulling(useFaceCulling);
STACK.push(Boolean.valueOf(useFaceCulling)); STACK.push(Boolean.valueOf(useFaceCulling));
} }
public static void pop() { public static void pop() {
STACK.pop(); STACK.pop();
if (STACK.isEmpty()) { if (STACK.isEmpty()) {
GraphicsBackend.setFaceCulling(false); GraphicsBackend.setFaceCulling(false);
} else { } else {
GraphicsBackend.setFaceCulling(STACK.getFirst()); GraphicsBackend.setFaceCulling(STACK.getFirst());
} }
} }
private FaceCulling() {} private FaceCulling() {
}
} }

View File

@ -1,127 +1,131 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend;
package ru.windcorp.progressia.client.graphics.backend;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL11.*;
import glm.vec._2.i.Vec2i;
import glm.vec._2.i.Vec2i;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.glfw.GLFW.*;
public class GraphicsBackend {
public class GraphicsBackend {
private static RenderThread renderThread;
private static RenderThread renderThread;
private static long windowHandle;
private static long windowHandle;
private static final Vec2i FRAME_SIZE = new Vec2i();
private static final Vec2i FRAME_SIZE = new Vec2i();
private static double frameLength = 1.0 / 60; // TODO do something about it
private static long framesRendered = 0; private static double frameLength = 1.0 / 60; // TODO do something about it
private static double frameStart = Double.NaN; private static long framesRendered = 0;
private static double frameStart = Double.NaN;
private static boolean faceCullingEnabled = false;
private static boolean faceCullingEnabled = false;
private GraphicsBackend() {}
private GraphicsBackend() {
public static void initialize() { }
startRenderThread();
} public static void initialize() {
startRenderThread();
private static void startRenderThread() { }
renderThread = new RenderThread();
renderThread.start(); private static void startRenderThread() {
} renderThread = new RenderThread();
renderThread.start();
public static Thread getRenderThread() { }
return renderThread;
} public static Thread getRenderThread() {
return renderThread;
static void setWindowHandle(long windowHandle) { }
GraphicsBackend.windowHandle = windowHandle;
} static void setWindowHandle(long windowHandle) {
GraphicsBackend.windowHandle = windowHandle;
public static long getWindowHandle() { }
return windowHandle;
} public static long getWindowHandle() {
return windowHandle;
public static int getFrameWidth() { }
return FRAME_SIZE.x;
} public static int getFrameWidth() {
return FRAME_SIZE.x;
public static int getFrameHeight() { }
return FRAME_SIZE.y;
} public static int getFrameHeight() {
return FRAME_SIZE.y;
public static Vec2i getFrameSize() { }
return FRAME_SIZE;
} public static Vec2i getFrameSize() {
return FRAME_SIZE;
static void onFrameResized(long window, int newWidth, int newHeight) { }
if (window != windowHandle) return;
static void onFrameResized(long window, int newWidth, int newHeight) {
InputHandler.handleFrameResize(newWidth, newHeight); if (window != windowHandle)
FRAME_SIZE.set(newWidth, newHeight); return;
glViewport(0, 0, newWidth, newHeight); InputHandler.handleFrameResize(newWidth, newHeight);
} FRAME_SIZE.set(newWidth, newHeight);
static void startFrame() { glViewport(0, 0, newWidth, newHeight);
double now = glfwGetTime(); }
if (Double.isNaN(frameStart)) { static void startFrame() {
frameStart = now; double now = glfwGetTime();
} else {
frameLength = now - frameStart; if (Double.isNaN(frameStart)) {
frameStart = now; frameStart = now;
} } else {
} frameLength = now - frameStart;
frameStart = now;
static void endFrame() { }
framesRendered++; }
}
static void endFrame() {
public static double getFrameStart() { framesRendered++;
return frameStart; }
}
public static double getFrameStart() {
public static double getFrameLength() { return frameStart;
return frameLength; }
}
public static double getFrameLength() {
public static long getFramesRendered() { return frameLength;
return framesRendered; }
}
public static long getFramesRendered() {
public static void startNextLayer() { return framesRendered;
glClear(GL_DEPTH_BUFFER_BIT); }
}
public static void startNextLayer() {
public static void setFaceCulling(boolean useFaceCulling) { glClear(GL_DEPTH_BUFFER_BIT);
if (useFaceCulling == faceCullingEnabled) return; }
if (useFaceCulling) { public static void setFaceCulling(boolean useFaceCulling) {
glEnable(GL_CULL_FACE); if (useFaceCulling == faceCullingEnabled)
} else { return;
glDisable(GL_CULL_FACE);
} if (useFaceCulling) {
glEnable(GL_CULL_FACE);
faceCullingEnabled = useFaceCulling; } else {
} glDisable(GL_CULL_FACE);
}
}
faceCullingEnabled = useFaceCulling;
}
}

View File

@ -1,74 +1,76 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend;
package ru.windcorp.progressia.client.graphics.backend;
import glm.vec._2.i.Vec2i;
import glm.vec._2.i.Vec2i;
public class GraphicsInterface {
public class GraphicsInterface {
private GraphicsInterface() {}
private GraphicsInterface() {
public static Thread getRenderThread() { }
return GraphicsBackend.getRenderThread();
} public static Thread getRenderThread() {
return GraphicsBackend.getRenderThread();
public static boolean isRenderThread() { }
return Thread.currentThread() == getRenderThread();
} public static boolean isRenderThread() {
return Thread.currentThread() == getRenderThread();
public static int getFrameWidth() { }
return GraphicsBackend.getFrameWidth();
} public static int getFrameWidth() {
return GraphicsBackend.getFrameWidth();
public static int getFrameHeight() { }
return GraphicsBackend.getFrameHeight();
} public static int getFrameHeight() {
return GraphicsBackend.getFrameHeight();
public static Vec2i getFrameSize() { }
return GraphicsBackend.getFrameSize();
} public static Vec2i getFrameSize() {
return GraphicsBackend.getFrameSize();
public static float getAspectRatio() { }
return ((float) getFrameWidth()) / getFrameHeight();
} public static float getAspectRatio() {
return ((float) getFrameWidth()) / getFrameHeight();
public static double getTime() { }
return GraphicsBackend.getFrameStart();
} public static double getTime() {
return GraphicsBackend.getFrameStart();
public static double getFrameLength() { }
return GraphicsBackend.getFrameLength();
} public static double getFrameLength() {
return GraphicsBackend.getFrameLength();
public static double getFPS() { }
return 1 / GraphicsBackend.getFrameLength();
} public static double getFPS() {
return 1 / GraphicsBackend.getFrameLength();
public static long getFramesRendered() { }
return GraphicsBackend.getFramesRendered();
} public static long getFramesRendered() {
return GraphicsBackend.getFramesRendered();
public static void subscribeToInputEvents(Object listener) { }
InputHandler.register(listener);
} public static void subscribeToInputEvents(Object listener) {
InputHandler.register(listener);
public static void startNextLayer() { }
GraphicsBackend.startNextLayer();
} public static void startNextLayer() {
GraphicsBackend.startNextLayer();
} }
}

View File

@ -1,182 +1,183 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend;
package ru.windcorp.progressia.client.graphics.backend;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFW;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.EventBus;
import ru.windcorp.progressia.client.graphics.input.*;
import ru.windcorp.progressia.common.util.crash.ReportingEventBus; import ru.windcorp.progressia.client.graphics.input.*;
import ru.windcorp.progressia.common.util.crash.ReportingEventBus;
public class InputHandler {
public class InputHandler {
private static final EventBus INPUT_EVENT_BUS = ReportingEventBus.create("Input");
private static final EventBus INPUT_EVENT_BUS = ReportingEventBus.create("Input");
// KeyEvent
// KeyEvent
private static class ModifiableKeyEvent extends KeyEvent {
private static class ModifiableKeyEvent extends KeyEvent {
protected ModifiableKeyEvent() {
super(0, 0, 0, 0, Double.NaN); protected ModifiableKeyEvent() {
} super(0, 0, 0, 0, Double.NaN);
}
public void initialize(int key, int scancode, int action, int mods) {
this.setTime(GraphicsInterface.getTime()); public void initialize(int key, int scancode, int action, int mods) {
this.key = key; this.setTime(GraphicsInterface.getTime());
this.scancode = scancode; this.key = key;
this.action = action; this.scancode = scancode;
this.mods = mods; this.action = action;
} this.mods = mods;
}
}
}
private static final ModifiableKeyEvent THE_KEY_EVENT =
new ModifiableKeyEvent(); private static final ModifiableKeyEvent THE_KEY_EVENT = new ModifiableKeyEvent();
static void handleKeyInput( static void handleKeyInput(
long window, long window,
int key, int key,
int scancode, int scancode,
int action, int action,
int mods int mods
) { ) {
if (GraphicsBackend.getWindowHandle() != window) return; if (GraphicsBackend.getWindowHandle() != window)
THE_KEY_EVENT.initialize(key, scancode, action, mods); return;
dispatch(THE_KEY_EVENT); THE_KEY_EVENT.initialize(key, scancode, action, mods);
dispatch(THE_KEY_EVENT);
switch (action) {
case GLFW.GLFW_PRESS: switch (action) {
InputTracker.setKeyState(key, true); case GLFW.GLFW_PRESS:
break; InputTracker.setKeyState(key, true);
case GLFW.GLFW_RELEASE: break;
InputTracker.setKeyState(key, false); case GLFW.GLFW_RELEASE:
break; InputTracker.setKeyState(key, false);
} break;
} }
}
static void handleMouseButtonInput(
long window, static void handleMouseButtonInput(
int key, long window,
int action, int key,
int mods int action,
) { int mods
handleKeyInput(window, key, Integer.MAX_VALUE - key, action, mods); ) {
} handleKeyInput(window, key, Integer.MAX_VALUE - key, action, mods);
}
// CursorMoveEvent
// CursorMoveEvent
private static class ModifiableCursorMoveEvent extends CursorMoveEvent {
private static class ModifiableCursorMoveEvent extends CursorMoveEvent {
protected ModifiableCursorMoveEvent() {
super(0, 0, Double.NaN); protected ModifiableCursorMoveEvent() {
} super(0, 0, Double.NaN);
}
public void initialize(double x, double y) {
this.setTime(GraphicsInterface.getTime()); public void initialize(double x, double y) {
getNewPosition().set(x, y); this.setTime(GraphicsInterface.getTime());
} getNewPosition().set(x, y);
}
}
}
private static final ModifiableCursorMoveEvent THE_CURSOR_MOVE_EVENT =
new ModifiableCursorMoveEvent(); private static final ModifiableCursorMoveEvent THE_CURSOR_MOVE_EVENT = new ModifiableCursorMoveEvent();
static void handleMouseMoveInput( static void handleMouseMoveInput(
long window, long window,
double x, double y double x,
) { double y
if (GraphicsBackend.getWindowHandle() != window) return; ) {
y = GraphicsInterface.getFrameHeight() - y; // Flip y axis if (GraphicsBackend.getWindowHandle() != window)
return;
InputTracker.initializeCursorPosition(x, y); y = GraphicsInterface.getFrameHeight() - y; // Flip y axis
THE_CURSOR_MOVE_EVENT.initialize(x, y); InputTracker.initializeCursorPosition(x, y);
dispatch(THE_CURSOR_MOVE_EVENT);
THE_CURSOR_MOVE_EVENT.initialize(x, y);
InputTracker.getCursorPosition().set(x, y); dispatch(THE_CURSOR_MOVE_EVENT);
}
InputTracker.getCursorPosition().set(x, y);
// ScrollEvent }
private static class ModifiableWheelScrollEvent extends WheelScrollEvent { // ScrollEvent
public ModifiableWheelScrollEvent() { private static class ModifiableWheelScrollEvent extends WheelScrollEvent {
super(0, 0, Double.NaN);
} public ModifiableWheelScrollEvent() {
super(0, 0, Double.NaN);
public void initialize(double xOffset, double yOffset) { }
this.setTime(GraphicsInterface.getTime());
this.getOffset().set(xOffset, yOffset); public void initialize(double xOffset, double yOffset) {
} this.setTime(GraphicsInterface.getTime());
this.getOffset().set(xOffset, yOffset);
} }
private static final ModifiableWheelScrollEvent THE_WHEEL_SCROLL_EVENT = }
new ModifiableWheelScrollEvent();
private static final ModifiableWheelScrollEvent THE_WHEEL_SCROLL_EVENT = new ModifiableWheelScrollEvent();
static void handleWheelScroll(
long window, static void handleWheelScroll(
double xoffset, long window,
double yoffset double xoffset,
) { double yoffset
if (GraphicsBackend.getWindowHandle() != window) return; ) {
THE_WHEEL_SCROLL_EVENT.initialize(xoffset, yoffset); if (GraphicsBackend.getWindowHandle() != window)
dispatch(THE_WHEEL_SCROLL_EVENT); return;
} THE_WHEEL_SCROLL_EVENT.initialize(xoffset, yoffset);
dispatch(THE_WHEEL_SCROLL_EVENT);
// FrameResizeEvent }
private static class ModifiableFrameResizeEvent extends FrameResizeEvent { // FrameResizeEvent
public ModifiableFrameResizeEvent() { private static class ModifiableFrameResizeEvent extends FrameResizeEvent {
super(0, 0, Double.NaN);
} public ModifiableFrameResizeEvent() {
super(0, 0, Double.NaN);
public void initialize(int width, int height) { }
this.setTime(GraphicsInterface.getTime());
this.getNewSize().set(width, height); public void initialize(int width, int height) {
} this.setTime(GraphicsInterface.getTime());
this.getNewSize().set(width, height);
} }
private static final ModifiableFrameResizeEvent THE_FRAME_RESIZE_EVENT = }
new ModifiableFrameResizeEvent();
private static final ModifiableFrameResizeEvent THE_FRAME_RESIZE_EVENT = new ModifiableFrameResizeEvent();
/*
* NB: this is NOT a GLFW callback, the raw callback is in GraphicsBackend /*
*/ * NB: this is NOT a GLFW callback, the raw callback is in GraphicsBackend
static void handleFrameResize( */
int width, static void handleFrameResize(
int height int width,
) { int height
THE_FRAME_RESIZE_EVENT.initialize(width, height); ) {
dispatch(THE_FRAME_RESIZE_EVENT); THE_FRAME_RESIZE_EVENT.initialize(width, height);
} dispatch(THE_FRAME_RESIZE_EVENT);
}
// Misc
// Misc
private static void dispatch(InputEvent event) {
INPUT_EVENT_BUS.post(event); private static void dispatch(InputEvent event) {
} INPUT_EVENT_BUS.post(event);
}
public static void register(Object listener) {
INPUT_EVENT_BUS.register(listener); public static void register(Object listener) {
} INPUT_EVENT_BUS.register(listener);
}
}
}

View File

@ -1,72 +1,75 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend;
package ru.windcorp.progressia.client.graphics.backend;
import glm.vec._2.d.Vec2d;
import gnu.trove.set.TIntSet; import glm.vec._2.d.Vec2d;
import gnu.trove.set.hash.TIntHashSet; import gnu.trove.set.TIntSet;
import gnu.trove.set.hash.TIntHashSet;
public class InputTracker {
public class InputTracker {
private static final Vec2d CURSOR_POSITION = new Vec2d(
Double.NaN, Double.NaN private static final Vec2d CURSOR_POSITION = new Vec2d(
); Double.NaN,
Double.NaN
private static final TIntSet PRESSED_KEYS = new TIntHashSet(256); );
private InputTracker() {} private static final TIntSet PRESSED_KEYS = new TIntHashSet(256);
public static double getCursorX() { private InputTracker() {
return CURSOR_POSITION.x; }
}
public static double getCursorX() {
public static double getCursorY() { return CURSOR_POSITION.x;
return CURSOR_POSITION.y; }
}
public static double getCursorY() {
public static Vec2d getCursorPosition() { return CURSOR_POSITION.y;
return CURSOR_POSITION; }
}
public static Vec2d getCursorPosition() {
static void initializeCursorPosition(double x, double y) { return CURSOR_POSITION;
if (Double.isNaN(CURSOR_POSITION.x)) { }
CURSOR_POSITION.set(x, y);
} static void initializeCursorPosition(double x, double y) {
} if (Double.isNaN(CURSOR_POSITION.x)) {
CURSOR_POSITION.set(x, y);
public static boolean isKeyPressed(int glfwCode) { }
return PRESSED_KEYS.contains(glfwCode); }
}
public static boolean isKeyPressed(int glfwCode) {
static void setKeyState(int glfwCode, boolean isPressed) { return PRESSED_KEYS.contains(glfwCode);
if (isPressed) { }
PRESSED_KEYS.add(glfwCode);
} else { static void setKeyState(int glfwCode, boolean isPressed) {
PRESSED_KEYS.remove(glfwCode); if (isPressed) {
} PRESSED_KEYS.add(glfwCode);
} } else {
PRESSED_KEYS.remove(glfwCode);
public static TIntSet getPressedKeys() { }
return PRESSED_KEYS; }
}
public static TIntSet getPressedKeys() {
static void releaseEverything() { return PRESSED_KEYS;
PRESSED_KEYS.clear(); }
}
static void releaseEverything() {
} PRESSED_KEYS.clear();
}
}

View File

@ -1,107 +1,113 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend;
package ru.windcorp.progressia.client.graphics.backend;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.glfw.GLFW.*; import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.system.MemoryUtil.*; import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.system.MemoryUtil.*;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL;
import ru.windcorp.progressia.client.graphics.GUI;
import ru.windcorp.progressia.client.graphics.GUI;
class LWJGLInitializer {
class LWJGLInitializer {
private LWJGLInitializer() {}
private LWJGLInitializer() {
public static void initialize() { }
checkEnvironment();
initializeGLFW(); public static void initialize() {
createWindow(); checkEnvironment();
positionWindow(); initializeGLFW();
createWindowIcons(); createWindow();
initializeOpenGL(); positionWindow();
setupWindowCallbacks(); createWindowIcons();
initializeOpenGL();
glfwShowWindow(GraphicsBackend.getWindowHandle()); setupWindowCallbacks();
}
glfwShowWindow(GraphicsBackend.getWindowHandle());
private static void checkEnvironment() { }
// TODO Auto-generated method stub
} private static void checkEnvironment() {
// TODO Auto-generated method stub
private static void initializeGLFW() { }
// TODO Do GLFW error handling: check glfwInit, setup error callback
glfwInit(); private static void initializeGLFW() {
} // TODO Do GLFW error handling: check glfwInit, setup error callback
glfwInit();
private static void createWindow() { }
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); private static void createWindow() {
glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE); glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE); glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
long handle = glfwCreateWindow(900, 900, "ProgressiaTest", NULL, NULL); glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
// TODO Check that handle != NULL long handle = glfwCreateWindow(900, 900, "ProgressiaTest", NULL, NULL);
GraphicsBackend.setWindowHandle(handle); // TODO Check that handle != NULL
glfwSetInputMode(handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED); GraphicsBackend.setWindowHandle(handle);
glfwMakeContextCurrent(handle); glfwSetInputMode(handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwSwapInterval(0);
} glfwMakeContextCurrent(handle);
glfwSwapInterval(0);
private static void positionWindow() { }
// TODO Auto-generated method stub
private static void positionWindow() {
} // TODO Auto-generated method stub
private static void createWindowIcons() { }
// TODO Auto-generated method stub
private static void createWindowIcons() {
} // TODO Auto-generated method stub
private static void initializeOpenGL() { }
GL.createCapabilities();
glEnable(GL_DEPTH_TEST); private static void initializeOpenGL() {
glEnable(GL_BLEND); GL.createCapabilities();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
RenderTaskQueue.schedule(OpenGLObjectTracker::deleteEnqueuedObjects); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
RenderTaskQueue.schedule(OpenGLObjectTracker::deleteEnqueuedObjects);
private static void setupWindowCallbacks() { }
long handle = GraphicsBackend.getWindowHandle();
private static void setupWindowCallbacks() {
glfwSetFramebufferSizeCallback(handle, long handle = GraphicsBackend.getWindowHandle();
GraphicsBackend::onFrameResized);
glfwSetFramebufferSizeCallback(
glfwSetKeyCallback(handle, InputHandler::handleKeyInput); handle,
glfwSetMouseButtonCallback(handle, GraphicsBackend::onFrameResized
InputHandler::handleMouseButtonInput); );
glfwSetCursorPosCallback(handle, InputHandler::handleMouseMoveInput); glfwSetKeyCallback(handle, InputHandler::handleKeyInput);
glfwSetMouseButtonCallback(
glfwSetScrollCallback(handle, InputHandler::handleWheelScroll); handle,
InputHandler::handleMouseButtonInput
GraphicsInterface.subscribeToInputEvents(GUI.getEventSubscriber()); );
}
glfwSetCursorPosCallback(handle, InputHandler::handleMouseMoveInput);
}
glfwSetScrollCallback(handle, InputHandler::handleWheelScroll);
GraphicsInterface.subscribeToInputEvents(GUI.getEventSubscriber());
}
}

View File

@ -1,92 +1,101 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend;
package ru.windcorp.progressia.client.graphics.backend;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue; import java.lang.ref.PhantomReference;
import java.util.ArrayList; import java.lang.ref.ReferenceQueue;
import java.util.Collection; import java.util.ArrayList;
import java.util.function.IntConsumer; import java.util.Collection;
import java.util.function.IntConsumer;
public class OpenGLObjectTracker {
public class OpenGLObjectTracker {
public interface OpenGLDeletable {
int getHandle(); public interface OpenGLDeletable {
} int getHandle();
}
private static final Collection<GLPhantomReference<OpenGLDeletable>> TO_DELETE = new ArrayList<>();
private static final ReferenceQueue<OpenGLDeletable> DELETE_QUEUE = new ReferenceQueue<>(); private static final Collection<GLPhantomReference<OpenGLDeletable>> TO_DELETE = new ArrayList<>();
private static final ReferenceQueue<OpenGLDeletable> DELETE_QUEUE = new ReferenceQueue<>();
public synchronized static void register(OpenGLDeletable object, IntConsumer glDeleter) {
GLPhantomReference<OpenGLDeletable> glRef = public synchronized static void register(OpenGLDeletable object, IntConsumer glDeleter) {
new GLPhantomReference<>(object, DELETE_QUEUE, object.getHandle(), glDeleter); GLPhantomReference<OpenGLDeletable> glRef = new GLPhantomReference<>(
TO_DELETE.add(glRef); object,
} DELETE_QUEUE,
object.getHandle(),
public static void deleteAllObjects() { glDeleter
for (GLPhantomReference<OpenGLDeletable> glRef );
: TO_DELETE TO_DELETE.add(glRef);
) { }
glRef.clear();
} public static void deleteAllObjects() {
} for (
GLPhantomReference<OpenGLDeletable> glRef : TO_DELETE
public static void deleteEnqueuedObjects() { ) {
while (true) { glRef.clear();
GLPhantomReference<?> glRef; }
glRef = (GLPhantomReference<?>) DELETE_QUEUE.poll(); }
if (glRef == null) {
break; public static void deleteEnqueuedObjects() {
} else { while (true) {
glRef.delete(); GLPhantomReference<?> glRef;
} glRef = (GLPhantomReference<?>) DELETE_QUEUE.poll();
} if (glRef == null) {
} break;
} else {
private static class GLPhantomReference<T> extends PhantomReference<T> { glRef.delete();
}
private final int referentGLhandle; }
private final IntConsumer GLDeleter; }
/** private static class GLPhantomReference<T> extends PhantomReference<T> {
* Creates a new phantom reference that refers to the given object and
* is registered with the given queue. private final int referentGLhandle;
* private final IntConsumer GLDeleter;
* <p> It is possible to create a phantom reference with a {@code null}
* queue, but such a reference is completely useless: Its {@code get} /**
* method will always return {@code null} and, since it does not have a queue, * Creates a new phantom reference that refers to the given object and
* it will never be enqueued. * is registered with the given queue.
* * <p>
* @param referent the object the new phantom reference will refer to * It is possible to create a phantom reference with a {@code null}
* @param q the queue with which the reference is to be registered, * queue, but such a reference is completely useless: Its {@code get}
* or {@code null} if registration is not required * method will always return {@code null} and, since it does not have a
*/ * queue,
public GLPhantomReference(T referent, * it will never be enqueued.
ReferenceQueue<? super T> q, *
int referentGLhandle, * @param referent the object the new phantom reference will refer to
IntConsumer GLDeleter) { * @param q the queue with which the reference is to be
super(referent, q); * registered,
this.referentGLhandle = referentGLhandle; * or {@code null} if registration is not required
this.GLDeleter = GLDeleter; */
} public GLPhantomReference(
T referent,
public void delete() { ReferenceQueue<? super T> q,
GLDeleter.accept(referentGLhandle); int referentGLhandle,
} IntConsumer GLDeleter
} ) {
} super(referent, q);
this.referentGLhandle = referentGLhandle;
this.GLDeleter = GLDeleter;
}
public void delete() {
GLDeleter.accept(referentGLhandle);
}
}
}

View File

@ -1,54 +1,56 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend;
package ru.windcorp.progressia.client.graphics.backend;
import ru.windcorp.jputil.functions.ThrowingRunnable;
import ru.windcorp.progressia.common.util.TaskQueue; import ru.windcorp.jputil.functions.ThrowingRunnable;
import ru.windcorp.progressia.common.util.TaskQueue;
public class RenderTaskQueue {
public class RenderTaskQueue {
private static final TaskQueue HANDLER =
new TaskQueue(GraphicsInterface::isRenderThread); private static final TaskQueue HANDLER = new TaskQueue(GraphicsInterface::isRenderThread);
public static void schedule(Runnable task) { public static void schedule(Runnable task) {
HANDLER.schedule(task); HANDLER.schedule(task);
} }
public static void removeScheduled(Runnable task) { public static void removeScheduled(Runnable task) {
HANDLER.removeScheduled(task); HANDLER.removeScheduled(task);
} }
public static void invokeLater(Runnable task) { public static void invokeLater(Runnable task) {
HANDLER.invokeLater(task); HANDLER.invokeLater(task);
} }
public static void invokeNow(Runnable task) { public static void invokeNow(Runnable task) {
HANDLER.invokeNow(task); HANDLER.invokeNow(task);
} }
public static <E extends Exception> void waitAndInvoke( public static <E extends Exception> void waitAndInvoke(
ThrowingRunnable<E> task ThrowingRunnable<E> task
) throws InterruptedException, E { )
HANDLER.waitAndInvoke(task); throws InterruptedException,
} E {
HANDLER.waitAndInvoke(task);
public static void runTasks() { }
HANDLER.runTasks();
} public static void runTasks() {
HANDLER.runTasks();
} }
}

View File

@ -1,79 +1,80 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend;
package ru.windcorp.progressia.client.graphics.backend;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.opengl.GL11.*;
import ru.windcorp.progressia.client.audio.AudioManager;
import ru.windcorp.progressia.client.graphics.GUI; import ru.windcorp.progressia.client.audio.AudioManager;
import ru.windcorp.progressia.client.graphics.GUI;
class RenderThread extends Thread {
class RenderThread extends Thread {
public RenderThread() {
super("Render"); public RenderThread() {
} super("Render");
}
@Override
public void run() { @Override
LWJGLInitializer.initialize(); public void run() {
mainLoop(); LWJGLInitializer.initialize();
freeResources(); mainLoop();
} freeResources();
}
private void mainLoop() {
while (shouldRun()) { private void mainLoop() {
GraphicsBackend.startFrame(); while (shouldRun()) {
RenderTaskQueue.runTasks(); GraphicsBackend.startFrame();
render(); RenderTaskQueue.runTasks();
waitForFrame(); render();
GraphicsBackend.endFrame(); waitForFrame();
} GraphicsBackend.endFrame();
}
System.exit(0);
} System.exit(0);
}
private void render() {
clear(); private void render() {
doRender(); clear();
glfwPollEvents(); doRender();
} glfwPollEvents();
}
private void clear() {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f); private void clear() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
} glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
private void doRender() {
GUI.render(); private void doRender() {
AudioManager.update(); GUI.render();
} AudioManager.update();
}
private void waitForFrame() {
glfwSwapBuffers(GraphicsBackend.getWindowHandle()); private void waitForFrame() {
} glfwSwapBuffers(GraphicsBackend.getWindowHandle());
}
private void freeResources() {
OpenGLObjectTracker.deleteAllObjects(); private void freeResources() {
} OpenGLObjectTracker.deleteAllObjects();
}
private boolean shouldRun() {
return !glfwWindowShouldClose(GraphicsBackend.getWindowHandle()); private boolean shouldRun() {
} return !glfwWindowShouldClose(GraphicsBackend.getWindowHandle());
}
}
}

View File

@ -1,38 +1,39 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend;
package ru.windcorp.progressia.client.graphics.backend;
import static org.lwjgl.opengl.GL15.GL_DYNAMIC_DRAW;
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; import static org.lwjgl.opengl.GL15.GL_DYNAMIC_DRAW;
import static org.lwjgl.opengl.GL15.GL_STREAM_DRAW; import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
import static org.lwjgl.opengl.GL15.GL_STREAM_DRAW;
public enum Usage { // TODO add _COPY and _READ, pref. as another enum
STATIC(GL_STATIC_DRAW), public enum Usage { // TODO add _COPY and _READ, pref. as another enum
DYNAMIC(GL_DYNAMIC_DRAW), STATIC(GL_STATIC_DRAW),
STREAM(GL_STREAM_DRAW); DYNAMIC(GL_DYNAMIC_DRAW),
STREAM(GL_STREAM_DRAW);
private final int glCode;
private final int glCode;
private Usage(int glCode) {
this.glCode = glCode; private Usage(int glCode) {
} this.glCode = glCode;
}
public int getGlCode() {
return glCode; public int getGlCode() {
} return glCode;
} }
}

View File

@ -1,199 +1,200 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend;
package ru.windcorp.progressia.client.graphics.backend;
import static org.lwjgl.opengl.GL20.*;
import static org.lwjgl.opengl.GL20.*;
import java.nio.*;
import java.nio.*;
import org.lwjgl.opengl.GL20;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable; import org.lwjgl.opengl.GL20;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable;
public class VertexBufferObject implements OpenGLDeletable {
public class VertexBufferObject implements OpenGLDeletable {
public static enum BindTarget {
ARRAY(GL_ARRAY_BUFFER), public static enum BindTarget {
ELEMENT_ARRAY(GL_ELEMENT_ARRAY_BUFFER); ARRAY(GL_ARRAY_BUFFER),
ELEMENT_ARRAY(GL_ELEMENT_ARRAY_BUFFER);
private final int glCode;
private final int glCode;
private BindTarget(int glCode) {
this.glCode = glCode; private BindTarget(int glCode) {
} this.glCode = glCode;
}
public int getGlCode() {
return glCode; public int getGlCode() {
} return glCode;
} }
}
private final int handle;
private final int handle;
private long length = 0;
private final Usage usage; private long length = 0;
private final Usage usage;
public VertexBufferObject(Usage usage) {
handle = glGenBuffers(); public VertexBufferObject(Usage usage) {
OpenGLObjectTracker.register(this, GL20::glDeleteBuffers); handle = glGenBuffers();
OpenGLObjectTracker.register(this, GL20::glDeleteBuffers);
this.usage = usage;
} this.usage = usage;
}
public void setData(ByteBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(ByteBuffer data) {
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode()); glBindBuffer(GL_ARRAY_BUFFER, handle);
length = data.remaining(); glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
} length = data.remaining();
}
public void setData(double[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(double[] data) {
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode()); glBindBuffer(GL_ARRAY_BUFFER, handle);
length = data.length * Double.BYTES; glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
} length = data.length * Double.BYTES;
}
public void setData(DoubleBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(DoubleBuffer data) {
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode()); glBindBuffer(GL_ARRAY_BUFFER, handle);
length = data.remaining() * Double.BYTES; glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
} length = data.remaining() * Double.BYTES;
}
public void setData(float[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(float[] data) {
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode()); glBindBuffer(GL_ARRAY_BUFFER, handle);
length = data.length * Float.BYTES; glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
} length = data.length * Float.BYTES;
}
public void setData(FloatBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(FloatBuffer data) {
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode()); glBindBuffer(GL_ARRAY_BUFFER, handle);
length = data.remaining() * Float.BYTES; glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
} length = data.remaining() * Float.BYTES;
}
public void setData(int[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(int[] data) {
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode()); glBindBuffer(GL_ARRAY_BUFFER, handle);
length = data.length * Integer.BYTES; glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
} length = data.length * Integer.BYTES;
}
public void setData(IntBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(IntBuffer data) {
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode()); glBindBuffer(GL_ARRAY_BUFFER, handle);
length = data.remaining() * Integer.BYTES; glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
} length = data.remaining() * Integer.BYTES;
}
public void setData(long[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(long[] data) {
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode()); glBindBuffer(GL_ARRAY_BUFFER, handle);
length = data.length * Long.BYTES; glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
} length = data.length * Long.BYTES;
}
public void setData(LongBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(LongBuffer data) {
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode()); glBindBuffer(GL_ARRAY_BUFFER, handle);
length = data.remaining() * Long.BYTES; glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
} length = data.remaining() * Long.BYTES;
}
public void setData(short[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(short[] data) {
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode()); glBindBuffer(GL_ARRAY_BUFFER, handle);
length = data.length * Short.BYTES; glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
} length = data.length * Short.BYTES;
}
public void setData(ShortBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(ShortBuffer data) {
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode()); glBindBuffer(GL_ARRAY_BUFFER, handle);
length = data.remaining() * Short.BYTES; glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
} length = data.remaining() * Short.BYTES;
}
public void initData(long length) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void initData(long length) {
glBufferData(GL_ARRAY_BUFFER, length, usage.getGlCode()); glBindBuffer(GL_ARRAY_BUFFER, handle);
this.length = length; glBufferData(GL_ARRAY_BUFFER, length, usage.getGlCode());
} this.length = length;
}
public void setData(int offset, ByteBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(int offset, ByteBuffer data) {
glBufferSubData(GL_ARRAY_BUFFER, offset, data); glBindBuffer(GL_ARRAY_BUFFER, handle);
} glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, double[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(int offset, double[] data) {
glBufferSubData(GL_ARRAY_BUFFER, offset, data); glBindBuffer(GL_ARRAY_BUFFER, handle);
} glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, DoubleBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(int offset, DoubleBuffer data) {
glBufferSubData(GL_ARRAY_BUFFER, offset, data); glBindBuffer(GL_ARRAY_BUFFER, handle);
} glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, float[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(int offset, float[] data) {
glBufferSubData(GL_ARRAY_BUFFER, offset, data); glBindBuffer(GL_ARRAY_BUFFER, handle);
} glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, FloatBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(int offset, FloatBuffer data) {
glBufferSubData(GL_ARRAY_BUFFER, offset, data); glBindBuffer(GL_ARRAY_BUFFER, handle);
} glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, int[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(int offset, int[] data) {
glBufferSubData(GL_ARRAY_BUFFER, offset, data); glBindBuffer(GL_ARRAY_BUFFER, handle);
} glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, IntBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(int offset, IntBuffer data) {
glBufferSubData(GL_ARRAY_BUFFER, offset, data); glBindBuffer(GL_ARRAY_BUFFER, handle);
} glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, long[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(int offset, long[] data) {
glBufferSubData(GL_ARRAY_BUFFER, offset, data); glBindBuffer(GL_ARRAY_BUFFER, handle);
} glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, LongBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(int offset, LongBuffer data) {
glBufferSubData(GL_ARRAY_BUFFER, offset, data); glBindBuffer(GL_ARRAY_BUFFER, handle);
} glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, short[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(int offset, short[] data) {
glBufferSubData(GL_ARRAY_BUFFER, offset, data); glBindBuffer(GL_ARRAY_BUFFER, handle);
} glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, ShortBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle); public void setData(int offset, ShortBuffer data) {
glBufferSubData(GL_ARRAY_BUFFER, offset, data); glBindBuffer(GL_ARRAY_BUFFER, handle);
} glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void bind(BindTarget target) {
glBindBuffer(target.getGlCode(), handle); public void bind(BindTarget target) {
} glBindBuffer(target.getGlCode(), handle);
}
public long getLength() {
return length; public long getLength() {
} return length;
}
public Usage getUsage() {
return usage; public Usage getUsage() {
} return usage;
}
@Override
public int getHandle() { @Override
return handle; public int getHandle() {
} return handle;
} }
}

View File

@ -1,93 +1,95 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend.shaders;
package ru.windcorp.progressia.client.graphics.backend.shaders;
import ru.windcorp.progressia.common.resource.Resource;
import ru.windcorp.progressia.common.resource.Resource;
public class CombinedShader extends Shader {
public class CombinedShader extends Shader {
public CombinedShader(String... resources) {
super(getTypeOf(resources), combine(resources)); public CombinedShader(String... resources) {
} super(getTypeOf(resources), combine(resources));
}
private static ShaderType getTypeOf(String[] resources) {
ShaderType first = ShaderType.guessByResourceName(resources[0]); private static ShaderType getTypeOf(String[] resources) {
ShaderType first = ShaderType.guessByResourceName(resources[0]);
for (int i = 1; i < resources.length; ++i) {
if (ShaderType.guessByResourceName(resources[i]) != first) { for (int i = 1; i < resources.length; ++i) {
throw new IllegalArgumentException( if (ShaderType.guessByResourceName(resources[i]) != first) {
"Deduced shader types of " throw new IllegalArgumentException(
+ resources[0] "Deduced shader types of "
+ " and " + resources[0]
+ resources[i] + " and "
+ " differ" + resources[i]
); + " differ"
} );
} }
}
return first;
} return first;
}
private static String combine(String[] resources) {
StringBuilder accumulator = new StringBuilder("#version 120\n"); private static String combine(String[] resources) {
StringBuilder accumulator = new StringBuilder("#version 120\n");
for (String resourceName : resources) {
Resource resource = getShaderResource(resourceName); for (String resourceName : resources) {
Resource resource = getShaderResource(resourceName);
accumulator.append("\n// START " + resourceName);
accumulator.append(stripVersionAnnotations(resource)); accumulator.append("\n// START " + resourceName);
accumulator.append('\n'); accumulator.append(stripVersionAnnotations(resource));
} accumulator.append('\n');
}
return accumulator.toString();
} return accumulator.toString();
}
private static String stripVersionAnnotations(Resource resource) {
String contents = resource.readAsString(); private static String stripVersionAnnotations(Resource resource) {
String contents = resource.readAsString();
int versionIndex;
for (versionIndex = 0; versionIndex < contents.length(); ++versionIndex) int versionIndex;
{ for (versionIndex = 0; versionIndex < contents.length(); ++versionIndex) {
if (!Character.isWhitespace(contents.codePointAt(versionIndex))) if (!Character.isWhitespace(contents.codePointAt(versionIndex)))
break; break;
} }
if (versionIndex < contents.length()) { if (versionIndex < contents.length()) {
if (contents.codePointAt(versionIndex) == '#') { if (contents.codePointAt(versionIndex) == '#') {
final String versionAnnotation = "#version "; final String versionAnnotation = "#version ";
if (contents.regionMatches( if (
versionIndex, contents.regionMatches(
versionAnnotation, versionIndex,
0, versionAnnotation,
versionAnnotation.length() 0,
)) { versionAnnotation.length()
contents = contents.substring( )
versionIndex ) {
+ versionAnnotation.length() contents = contents.substring(
+ "120".length() versionIndex
); + versionAnnotation.length()
} + "120".length()
);
} }
}
}
return contents; }
}
return contents;
} }
}

View File

@ -1,63 +1,66 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend.shaders;
package ru.windcorp.progressia.client.graphics.backend.shaders;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*; import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import org.lwjgl.opengl.GL20;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker; import org.lwjgl.opengl.GL20;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable; import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker;
import ru.windcorp.progressia.client.graphics.backend.shaders.attributes.Attribute; import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable;
import ru.windcorp.progressia.client.graphics.backend.shaders.uniforms.Uniform; import ru.windcorp.progressia.client.graphics.backend.shaders.attributes.Attribute;
import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.client.graphics.backend.shaders.uniforms.Uniform;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Program implements OpenGLDeletable {
public class Program implements OpenGLDeletable {
private int handle;
private int handle;
public Program(Shader vertexShader, Shader fragmentShader) {
handle = glCreateProgram(); public Program(Shader vertexShader, Shader fragmentShader) {
OpenGLObjectTracker.register(this, GL20::glDeleteProgram); handle = glCreateProgram();
OpenGLObjectTracker.register(this, GL20::glDeleteProgram);
glAttachShader(handle, vertexShader.getHandle());
glAttachShader(handle, fragmentShader.getHandle()); glAttachShader(handle, vertexShader.getHandle());
glAttachShader(handle, fragmentShader.getHandle());
glLinkProgram(handle);
glLinkProgram(handle);
if (glGetProgrami(handle, GL_LINK_STATUS) == GL_FALSE) {
throw CrashReports.report(null, "Bad program:\n%s", glGetProgramInfoLog(handle)); if (glGetProgrami(handle, GL_LINK_STATUS) == GL_FALSE) {
} throw CrashReports.report(null, "Bad program:\n%s", glGetProgramInfoLog(handle));
} }
}
public Attribute getAttribute(String name) {
return new Attribute(glGetAttribLocation(handle, name), this); public Attribute getAttribute(String name) {
} return new Attribute(glGetAttribLocation(handle, name), this);
}
public Uniform getUniform(String name) {
return new Uniform(glGetUniformLocation(handle, name), this); public Uniform getUniform(String name) {
} return new Uniform(glGetUniformLocation(handle, name), this);
}
public void use() {
glUseProgram(handle); public void use() {
} glUseProgram(handle);
}
@Override
public int getHandle() { return handle; } @Override
public int getHandle() {
} return handle;
}
}

View File

@ -1,103 +1,108 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend.shaders;
package ru.windcorp.progressia.client.graphics.backend.shaders;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*; import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import java.util.Locale;
import java.util.Locale;
import org.lwjgl.opengl.GL20;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker; import org.lwjgl.opengl.GL20;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable; import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker;
import ru.windcorp.progressia.common.resource.Resource; import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable;
import ru.windcorp.progressia.common.resource.ResourceManager; import ru.windcorp.progressia.common.resource.Resource;
import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.common.resource.ResourceManager;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Shader implements OpenGLDeletable {
public class Shader implements OpenGLDeletable {
public static enum ShaderType {
VERTEX(GL_VERTEX_SHADER), FRAGMENT(GL_FRAGMENT_SHADER); public static enum ShaderType {
VERTEX(GL_VERTEX_SHADER), FRAGMENT(GL_FRAGMENT_SHADER);
private final int glCode;
private final int glCode;
private ShaderType(int glCode) {
this.glCode = glCode; private ShaderType(int glCode) {
} this.glCode = glCode;
}
public int getGlCode() {
return glCode; public int getGlCode() {
} return glCode;
}
public static ShaderType guessByResourceName(String resource) {
resource = resource.toLowerCase(Locale.ENGLISH); public static ShaderType guessByResourceName(String resource) {
resource = resource.toLowerCase(Locale.ENGLISH);
if (resource.contains("vertex")) return VERTEX;
if (resource.contains("fragment")) return FRAGMENT; if (resource.contains("vertex"))
if (resource.contains("vsh")) return VERTEX; return VERTEX;
if (resource.contains("fsh")) return FRAGMENT; if (resource.contains("fragment"))
return FRAGMENT;
throw new IllegalArgumentException( if (resource.contains("vsh"))
"Cannot deduce shader type from resource name \"" + return VERTEX;
resource + "\"" if (resource.contains("fsh"))
); return FRAGMENT;
}
} throw new IllegalArgumentException(
"Cannot deduce shader type from resource name \"" +
private static final String SHADER_ASSETS_PREFIX = "assets/shaders/"; resource + "\""
);
protected static Resource getShaderResource(String name) { }
return ResourceManager.getResource(SHADER_ASSETS_PREFIX + name); }
}
private static final String SHADER_ASSETS_PREFIX = "assets/shaders/";
private final int handle;
private final ShaderType type; protected static Resource getShaderResource(String name) {
return ResourceManager.getResource(SHADER_ASSETS_PREFIX + name);
public Shader(ShaderType type, String source) { }
handle = glCreateShader(type.getGlCode());
OpenGLObjectTracker.register(this, GL20::glDeleteShader); private final int handle;
private final ShaderType type;
this.type = type;
public Shader(ShaderType type, String source) {
glShaderSource(handle, source); handle = glCreateShader(type.getGlCode());
glCompileShader(handle); OpenGLObjectTracker.register(this, GL20::glDeleteShader);
if (glGetShaderi(handle, GL_COMPILE_STATUS) == GL_FALSE) { this.type = type;
System.out.println("***************** ERROR ******************");
System.out.println(source); glShaderSource(handle, source);
throw CrashReports.report(null, "Bad shader:\n %s", glGetShaderInfoLog(handle)); glCompileShader(handle);
}
} if (glGetShaderi(handle, GL_COMPILE_STATUS) == GL_FALSE) {
System.out.println("***************** ERROR ******************");
public Shader(String resource) { System.out.println(source);
this( throw CrashReports.report(null, "Bad shader:\n %s", glGetShaderInfoLog(handle));
ShaderType.guessByResourceName(resource), }
getShaderResource(resource).readAsString() }
);
} public Shader(String resource) {
this(
@Override ShaderType.guessByResourceName(resource),
public int getHandle() { getShaderResource(resource).readAsString()
return handle; );
} }
public ShaderType getType() { @Override
return type; public int getHandle() {
} return handle;
}
}
public ShaderType getType() {
return type;
}
}

View File

@ -1,49 +1,50 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend.shaders.attributes;
package ru.windcorp.progressia.client.graphics.backend.shaders.attributes;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Attribute {
public class Attribute {
protected final int handle;
private final Program program; protected final int handle;
private final Program program;
public Attribute(int handle, Program program) {
if (handle < 0) { public Attribute(int handle, Program program) {
throw CrashReports.report(null, "Bad handle: %d", handle); if (handle < 0) {
} throw CrashReports.report(null, "Bad handle: %d", handle);
}
this.handle = handle;
this.program = program; this.handle = handle;
} this.program = program;
}
public int getHandle() {
return handle; public int getHandle() {
} return handle;
}
public Program getProgram() {
return program; public Program getProgram() {
} return program;
}
public AttributeVertexArray asVertexArray() {
return new AttributeVertexArray(handle, program); public AttributeVertexArray asVertexArray() {
} return new AttributeVertexArray(handle, program);
}
}
}

View File

@ -1,114 +1,154 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend.shaders.attributes;
package ru.windcorp.progressia.client.graphics.backend.shaders.attributes;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*; import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer; import java.nio.ByteBuffer;
import java.nio.IntBuffer; import java.nio.FloatBuffer;
import java.nio.ShortBuffer; import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import ru.windcorp.progressia.client.graphics.backend.VertexBufferObject;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program; import ru.windcorp.progressia.client.graphics.backend.VertexBufferObject;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
public class AttributeVertexArray extends Attribute {
public class AttributeVertexArray extends Attribute {
private boolean isEnabled = false;
private boolean isEnabled = false;
public AttributeVertexArray(int handle, Program program) {
super(handle, program); public AttributeVertexArray(int handle, Program program) {
} super(handle, program);
}
public void enable() {
if (!isEnabled) { public void enable() {
glEnableVertexAttribArray(handle); if (!isEnabled) {
isEnabled = true; glEnableVertexAttribArray(handle);
} isEnabled = true;
} }
}
public void disable() {
if (isEnabled) { public void disable() {
glDisableVertexAttribArray(handle); if (isEnabled) {
isEnabled = false; glDisableVertexAttribArray(handle);
} isEnabled = false;
} }
}
public void set(
int size, boolean normalized, int stride, public void set(
ByteBuffer pointer int size,
) { boolean normalized,
glVertexAttribPointer( int stride,
handle, ByteBuffer pointer
size, GL_BYTE, normalized, stride, pointer ) {
); glVertexAttribPointer(
} handle,
size,
public void set( GL_BYTE,
int size, boolean normalized, int stride, normalized,
FloatBuffer pointer stride,
) { pointer
glVertexAttribPointer( );
handle, }
size, GL_FLOAT, normalized, stride, pointer
); public void set(
} int size,
boolean normalized,
public void set( int stride,
int size, boolean normalized, int stride, FloatBuffer pointer
IntBuffer pointer ) {
) { glVertexAttribPointer(
glVertexAttribPointer( handle,
handle, size,
size, GL_INT, normalized, stride, pointer GL_FLOAT,
); normalized,
} stride,
pointer
public void set( );
int size, boolean normalized, int stride, }
ShortBuffer pointer
) { public void set(
glVertexAttribPointer( int size,
handle, boolean normalized,
size, GL_SHORT, normalized, stride, pointer int stride,
); IntBuffer pointer
} ) {
glVertexAttribPointer(
public void set( handle,
int size, int type, boolean normalized, int stride, size,
long pointer GL_INT,
) { normalized,
glVertexAttribPointer( stride,
handle, pointer
size, type, normalized, stride, pointer );
); }
}
public void set(
public void set( int size,
int size, int type, boolean normalized, int stride, boolean normalized,
VertexBufferObject vbo, long offset int stride,
) { ShortBuffer pointer
glBindBuffer(GL_ARRAY_BUFFER, vbo.getHandle()); ) {
glVertexAttribPointer( glVertexAttribPointer(
handle, handle,
size, type, normalized, stride, offset size,
); GL_SHORT,
} normalized,
stride,
} pointer
);
}
public void set(
int size,
int type,
boolean normalized,
int stride,
long pointer
) {
glVertexAttribPointer(
handle,
size,
type,
normalized,
stride,
pointer
);
}
public void set(
int size,
int type,
boolean normalized,
int stride,
VertexBufferObject vbo,
long offset
) {
glBindBuffer(GL_ARRAY_BUFFER, vbo.getHandle());
glVertexAttribPointer(
handle,
size,
type,
normalized,
stride,
offset
);
}
}

View File

@ -1,89 +1,90 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms;
package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
import ru.windcorp.progressia.common.util.crash.CrashReports; import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Uniform {
public class Uniform {
protected final int handle;
private final Program program; protected final int handle;
private final Program program;
public Uniform(int handle, Program program) {
if (handle < 0) { public Uniform(int handle, Program program) {
throw CrashReports.report(null, "Bad handle: %d", handle); if (handle < 0) {
} throw CrashReports.report(null, "Bad handle: %d", handle);
}
this.handle = handle;
this.program = program; this.handle = handle;
} this.program = program;
}
public int getHandle() {
return handle; public int getHandle() {
} return handle;
}
public Program getProgram() {
return program; public Program getProgram() {
} return program;
}
public Uniform1Float as1Float() {
return new Uniform1Float(handle, program); public Uniform1Float as1Float() {
} return new Uniform1Float(handle, program);
}
public Uniform1Int as1Int() {
return new Uniform1Int(handle, program); public Uniform1Int as1Int() {
} return new Uniform1Int(handle, program);
}
public Uniform2Float as2Float() {
return new Uniform2Float(handle, program); public Uniform2Float as2Float() {
} return new Uniform2Float(handle, program);
}
public Uniform2Int as2Int() {
return new Uniform2Int(handle, program); public Uniform2Int as2Int() {
} return new Uniform2Int(handle, program);
}
public Uniform3Float as3Float() {
return new Uniform3Float(handle, program); public Uniform3Float as3Float() {
} return new Uniform3Float(handle, program);
}
public Uniform3Int as3Int() {
return new Uniform3Int(handle, program); public Uniform3Int as3Int() {
} return new Uniform3Int(handle, program);
}
public Uniform4Float as4Float() {
return new Uniform4Float(handle, program); public Uniform4Float as4Float() {
} return new Uniform4Float(handle, program);
}
public Uniform4Int as4Int() {
return new Uniform4Int(handle, program); public Uniform4Int as4Int() {
} return new Uniform4Int(handle, program);
}
public Uniform2Matrix as2Matrix() {
return new Uniform2Matrix(handle, program); public Uniform2Matrix as2Matrix() {
} return new Uniform2Matrix(handle, program);
}
public Uniform3Matrix as3Matrix() {
return new Uniform3Matrix(handle, program); public Uniform3Matrix as3Matrix() {
} return new Uniform3Matrix(handle, program);
}
public Uniform4Matrix as4Matrix() {
return new Uniform4Matrix(handle, program); public Uniform4Matrix as4Matrix() {
} return new Uniform4Matrix(handle, program);
}
}
}

View File

@ -1,43 +1,44 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms;
package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms;
import static org.lwjgl.opengl.GL20.*;
import java.nio.FloatBuffer; import static org.lwjgl.opengl.GL20.*;
import java.nio.FloatBuffer;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
public class Uniform1Float extends Uniform {
public class Uniform1Float extends Uniform {
public Uniform1Float(int handle, Program program) {
super(handle, program); public Uniform1Float(int handle, Program program) {
} super(handle, program);
}
public void set(float value) {
glUniform1f(handle, value); public void set(float value) {
} glUniform1f(handle, value);
}
public void set(float[] value) {
glUniform1fv(handle, value); public void set(float[] value) {
} glUniform1fv(handle, value);
}
public void set(FloatBuffer value) {
glUniform1fv(handle, value); public void set(FloatBuffer value) {
} glUniform1fv(handle, value);
}
}
}

View File

@ -1,43 +1,44 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms;
package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms;
import static org.lwjgl.opengl.GL20.*;
import java.nio.IntBuffer; import static org.lwjgl.opengl.GL20.*;
import java.nio.IntBuffer;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
public class Uniform1Int extends Uniform {
public class Uniform1Int extends Uniform {
public Uniform1Int(int handle, Program program) {
super(handle, program); public Uniform1Int(int handle, Program program) {
} super(handle, program);
}
public void set(int value) {
glUniform1i(handle, value); public void set(int value) {
} glUniform1i(handle, value);
}
public void set(int[] value) {
glUniform1iv(handle, value); public void set(int[] value) {
} glUniform1iv(handle, value);
}
public void set(IntBuffer value) {
glUniform1iv(handle, value); public void set(IntBuffer value) {
} glUniform1iv(handle, value);
}
}
}

View File

@ -1,48 +1,49 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms;
package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms;
import static org.lwjgl.opengl.GL20.*;
import java.nio.FloatBuffer; import static org.lwjgl.opengl.GL20.*;
import java.nio.FloatBuffer;
import glm.vec._2.Vec2;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program; import glm.vec._2.Vec2;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
public class Uniform2Float extends Uniform {
public class Uniform2Float extends Uniform {
public Uniform2Float(int handle, Program program) {
super(handle, program); public Uniform2Float(int handle, Program program) {
} super(handle, program);
}
public void set(float x, float y) {
glUniform2f(handle, x, y); public void set(float x, float y) {
} glUniform2f(handle, x, y);
}
public void set(float[] value) {
glUniform2fv(handle, value); public void set(float[] value) {
} glUniform2fv(handle, value);
}
public void set(FloatBuffer value) {
glUniform2fv(handle, value); public void set(FloatBuffer value) {
} glUniform2fv(handle, value);
}
public void set(Vec2 value) {
glUniform2f(handle, value.x, value.y); public void set(Vec2 value) {
} glUniform2f(handle, value.x, value.y);
}
}
}

View File

@ -1,48 +1,49 @@
/******************************************************************************* /*
* Progressia * Progressia
* Copyright (C) 2020 Wind Corporation * Copyright (C) 2020-2021 Wind Corporation and contributors
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/ */
package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms;
package ru.windcorp.progressia.client.graphics.backend.shaders.uniforms;
import static org.lwjgl.opengl.GL20.*;
import java.nio.IntBuffer; import static org.lwjgl.opengl.GL20.*;
import java.nio.IntBuffer;
import glm.vec._2.i.Vec2i;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program; import glm.vec._2.i.Vec2i;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
public class Uniform2Int extends Uniform {
public class Uniform2Int extends Uniform {
public Uniform2Int(int handle, Program program) {
super(handle, program); public Uniform2Int(int handle, Program program) {
} super(handle, program);
}
public void set(int x, int y) {
glUniform2i(handle, x, y); public void set(int x, int y) {
} glUniform2i(handle, x, y);
}
public void set(int[] value) {
glUniform2iv(handle, value); public void set(int[] value) {
} glUniform2iv(handle, value);
}
public void set(IntBuffer value) {
glUniform2iv(handle, value); public void set(IntBuffer value) {
} glUniform2iv(handle, value);
}
public void set(Vec2i value) {
glUniform2i(handle, value.x, value.y); public void set(Vec2i value) {
} glUniform2i(handle, value.x, value.y);
}
}
}

Some files were not shown because too many files have changed in this diff Show More