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
#
# 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; }
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,
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
### 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.
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:
* - added a package declaration at line 1;
* - 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
* 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
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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/>.
*******************************************************************************/
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil;
import java.io.OutputStream;
@ -22,53 +23,53 @@ import java.io.PrintWriter;
import java.io.Writer;
public class CSVWriter {
private String columnSeparator = ";";
private String rowSeparator = "\n";
private boolean shouldAddSeparator = false;
private final PrintWriter parent;
public CSVWriter(PrintWriter output) {
this.parent = output;
}
public CSVWriter(Writer output) {
this(new PrintWriter(output));
}
public CSVWriter(OutputStream output) {
this(new PrintWriter(output));
}
public PrintWriter getParent() {
return parent;
}
public String getColumnSeparator() {
return columnSeparator;
}
public CSVWriter setColumnSeparator(String columnSeparator) {
this.columnSeparator = columnSeparator;
return this;
}
public String getRowSeparator() {
return rowSeparator;
}
public CSVWriter setRowSeparator(String rowSeparator) {
this.rowSeparator = rowSeparator;
return this;
}
public void print(Object object) {
skip();
getParent().print(String.valueOf(object));
}
public void skip() {
if (shouldAddSeparator) {
getParent().print(getColumnSeparator());
@ -76,27 +77,27 @@ public class CSVWriter {
shouldAddSeparator = true;
}
}
public void skip(int amount) {
for (int i = 0; i < amount; ++i) {
skip();
}
}
public void endRow() {
getParent().print(getRowSeparator());
shouldAddSeparator = false;
}
public void endRow(Object object) {
print(object);
endRow();
}
public void flush() {
getParent().flush();
}
public void close() {
getParent().close();
}

View File

@ -1,6 +1,6 @@
/*******************************************************************************
/*
* 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
* 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
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*******************************************************************************/
*/
package ru.windcorp.jputil;
import java.util.HashMap;
import java.util.Map;
public class PrimitiveUtil {
private PrimitiveUtil() {}
private PrimitiveUtil() {
}
private static final Map<Class<?>, Class<?>> PRIMITIVE_TO_BOXED = new HashMap<>();
private static final Map<Class<?>, Object> PRIMITIVE_TO_NULL = new HashMap<>();
static {
for (Class<?> boxed : new Class<?>[] {
Boolean.class, Byte.class, Short.class, Character.class,
Integer.class, Long.class, Float.class, Double.class
}) {
for (
Class<?> boxed : new Class<?>[] {
Boolean.class,
Byte.class,
Short.class,
Character.class,
Integer.class,
Long.class,
Float.class,
Double.class
}
) {
try {
PRIMITIVE_TO_BOXED.put((Class<?>) boxed.getField("TYPE").get(null), boxed);
} catch (Exception e) {
e.printStackTrace();
}
}
PRIMITIVE_TO_NULL.put(Boolean.TYPE, Boolean.FALSE);
PRIMITIVE_TO_NULL.put(Byte.TYPE, Byte.valueOf((byte) 0));
PRIMITIVE_TO_NULL.put(Short.TYPE, Short.valueOf((short) 0));
PRIMITIVE_TO_NULL.put(Integer.TYPE, Integer.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(Double.TYPE, Double.valueOf(Double.NaN));
PRIMITIVE_TO_NULL.put(Character.TYPE, Character.valueOf('\u0000'));
PRIMITIVE_TO_NULL.put(Boolean.TYPE, Boolean.FALSE);
PRIMITIVE_TO_NULL.put(Byte.TYPE, Byte.valueOf((byte) 0));
PRIMITIVE_TO_NULL.put(Short.TYPE, Short.valueOf((short) 0));
PRIMITIVE_TO_NULL.put(Integer.TYPE, Integer.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(Double.TYPE, Double.valueOf(Double.NaN));
PRIMITIVE_TO_NULL.put(Character.TYPE, Character.valueOf('\u0000'));
}
public static Class<?> getBoxedClass(Class<?> primitiveClass) {
return PRIMITIVE_TO_BOXED.getOrDefault(primitiveClass, primitiveClass);
}
public static Object getPrimitiveNull(Class<?> primitiveClass) {
return PRIMITIVE_TO_NULL.get(primitiveClass);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,44 +1,45 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil;
public class SyntaxException extends Exception {
private static final long serialVersionUID = -4052144233640072750L;
public SyntaxException() {
}
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) {
super(message);
}
public SyntaxException(Throwable cause) {
super(cause);
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil;
public class SyntaxException extends Exception {
private static final long serialVersionUID = -4052144233640072750L;
public SyntaxException() {
}
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) {
super(message);
}
public SyntaxException(Throwable cause) {
super(cause);
}
}

View File

@ -1,128 +1,132 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars;
import java.text.CharacterIterator;
public class CharArrayIterator implements CharacterIterator {
private final char[] array;
private int pos;
public CharArrayIterator(char[] array) {
this.array = array;
}
public CharArrayIterator(String src) {
this(src.toCharArray());
}
@Override
public char first() {
pos = 0;
if (array.length != 0) {
return array[pos];
}
return DONE;
}
@Override
public char last() {
pos = array.length;
if (array.length != 0) {
pos -= 1;
return array[pos];
}
return DONE;
}
@Override
public char current() {
if (array.length != 0 && pos < array.length) {
return array[pos];
}
return DONE;
}
@Override
public char next() {
pos += 1;
if (pos >= array.length) {
pos = array.length;
return DONE;
}
return current();
}
@Override
public char previous() {
if (pos == 0) {
return DONE;
}
pos -= 1;
return current();
}
@Override
public char setIndex(int position) {
if (position < 0 || position > array.length) {
throw new IllegalArgumentException("bad position: " + position);
}
pos = position;
if (pos != array.length && array.length != 0) {
return array[pos];
}
return DONE;
}
@Override
public int getBeginIndex() {
return 0;
}
@Override
public int getEndIndex() {
return array.length;
}
@Override
public int getIndex() {
return pos;
}
// @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 CharArrayIterator clone() {
try {
return (CharArrayIterator) super.clone();
} catch (CloneNotSupportedException cnse) {
// Impossible
return null;
}
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars;
import java.text.CharacterIterator;
public class CharArrayIterator implements CharacterIterator {
private final char[] array;
private int pos;
public CharArrayIterator(char[] array) {
this.array = array;
}
public CharArrayIterator(String src) {
this(src.toCharArray());
}
@Override
public char first() {
pos = 0;
if (array.length != 0) {
return array[pos];
}
return DONE;
}
@Override
public char last() {
pos = array.length;
if (array.length != 0) {
pos -= 1;
return array[pos];
}
return DONE;
}
@Override
public char current() {
if (array.length != 0 && pos < array.length) {
return array[pos];
}
return DONE;
}
@Override
public char next() {
pos += 1;
if (pos >= array.length) {
pos = array.length;
return DONE;
}
return current();
}
@Override
public char previous() {
if (pos == 0) {
return DONE;
}
pos -= 1;
return current();
}
@Override
public char setIndex(int position) {
if (position < 0 || position > array.length) {
throw new IllegalArgumentException("bad position: " + position);
}
pos = position;
if (pos != array.length && array.length != 0) {
return array[pos];
}
return DONE;
}
@Override
public int getBeginIndex() {
return 0;
}
@Override
public int getEndIndex() {
return array.length;
}
@Override
public int getIndex() {
return pos;
}
// @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 CharArrayIterator clone() {
try {
return (CharArrayIterator) super.clone();
} catch (CloneNotSupportedException cnse) {
// Impossible
return null;
}
}
}

View File

@ -1,42 +1,43 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars;
import java.util.function.IntConsumer;
@FunctionalInterface
public interface CharConsumer {
void accept(char c);
public static CharConsumer andThen(CharConsumer first, CharConsumer second) {
return c -> {
first.accept(c);
second.accept(c);
};
}
public static IntConsumer toInt(CharConsumer consumer) {
return i -> consumer.accept((char) i);
}
public static CharConsumer toChar(IntConsumer consumer) {
return consumer::accept;
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars;
import java.util.function.IntConsumer;
@FunctionalInterface
public interface CharConsumer {
void accept(char c);
public static CharConsumer andThen(CharConsumer first, CharConsumer second) {
return c -> {
first.accept(c);
second.accept(c);
};
}
public static IntConsumer toInt(CharConsumer consumer) {
return i -> consumer.accept((char) i);
}
public static CharConsumer toChar(IntConsumer consumer) {
return consumer::accept;
}
}

View File

@ -1,69 +1,70 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars;
import java.util.Objects;
import ru.windcorp.jputil.ArrayUtil;
/**
* @author Javapony
*
*/
public class 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) {
return fillArray(array, 0, -1);
}
private static class ArrayFiller implements CharConsumer {
final char[] array;
int i;
final int end;
/**
* @param array
* @param offset
* @param length
*/
ArrayFiller(char[] array, int offset, int length) {
this.array = Objects.requireNonNull(array, "array");
this.end = ArrayUtil.checkArrayStartEnd(array, offset, offset + length);
this.i = offset;
}
/**
* @see ru.windcorp.jputil.chars.CharConsumer#accept(char)
*/
@Override
public void accept(char c) {
if (i == end)
throw new ArrayIndexOutOfBoundsException(end);
array[i++] = c;
}
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars;
import java.util.Objects;
import ru.windcorp.jputil.ArrayUtil;
/**
* @author Javapony
*/
public class 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) {
return fillArray(array, 0, -1);
}
private static class ArrayFiller implements CharConsumer {
final char[] array;
int i;
final int end;
/**
* @param array
* @param offset
* @param length
*/
ArrayFiller(char[] array, int offset, int length) {
this.array = Objects.requireNonNull(array, "array");
this.end = ArrayUtil.checkArrayStartEnd(array, offset, offset + length);
this.i = offset;
}
/**
* @see ru.windcorp.jputil.chars.CharConsumer#accept(char)
*/
@Override
public void accept(char c) {
if (i == end)
throw new ArrayIndexOutOfBoundsException(end);
array[i++] = c;
}
}
}

View File

@ -1,84 +1,85 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars;
import java.util.Arrays;
import java.util.function.IntPredicate;
import ru.windcorp.jputil.ArrayUtil;
@FunctionalInterface
public interface CharPredicate {
boolean test(char 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 negate(CharPredicate predicate) {
return c -> !predicate.test(c);
}
public static IntPredicate toInt(CharPredicate predicate) {
return i -> predicate.test((char) i);
}
public static CharPredicate toChar(IntPredicate predicate) {
return predicate::test;
}
public static CharPredicate forArray(char... chars) {
if (chars.length == 0) {
return c -> false;
}
if (chars.length == 1) {
return forChar(chars[0]);
}
if (chars.length < 16) {
return c -> ArrayUtil.firstIndexOf(chars, c) >= 0;
} else {
final char[] sorted = Arrays.copyOf(chars, chars.length);
Arrays.sort(sorted);
return c -> Arrays.binarySearch(chars, c) >= 0;
}
}
public static CharPredicate forChar(final char c) {
return given -> given == c;
}
public static CharPredicate forRange(final char minInclusive, final char maxExclusive) {
if (minInclusive > maxExclusive) {
throw new IllegalArgumentException("min > max: " + minInclusive + " > " + maxExclusive);
}
if (minInclusive == maxExclusive) {
return c -> false;
}
return c -> c >= minInclusive && c < maxExclusive;
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars;
import java.util.Arrays;
import java.util.function.IntPredicate;
import ru.windcorp.jputil.ArrayUtil;
@FunctionalInterface
public interface CharPredicate {
boolean test(char 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 negate(CharPredicate predicate) {
return c -> !predicate.test(c);
}
public static IntPredicate toInt(CharPredicate predicate) {
return i -> predicate.test((char) i);
}
public static CharPredicate toChar(IntPredicate predicate) {
return predicate::test;
}
public static CharPredicate forArray(char... chars) {
if (chars.length == 0) {
return c -> false;
}
if (chars.length == 1) {
return forChar(chars[0]);
}
if (chars.length < 16) {
return c -> ArrayUtil.firstIndexOf(chars, c) >= 0;
} else {
final char[] sorted = Arrays.copyOf(chars, chars.length);
Arrays.sort(sorted);
return c -> Arrays.binarySearch(chars, c) >= 0;
}
}
public static CharPredicate forChar(final char c) {
return given -> given == c;
}
public static CharPredicate forRange(final char minInclusive, final char maxExclusive) {
if (minInclusive > maxExclusive) {
throw new IllegalArgumentException("min > max: " + minInclusive + " > " + maxExclusive);
}
if (minInclusive == maxExclusive) {
return c -> false;
}
return c -> c >= minInclusive && c < maxExclusive;
}
}

View File

@ -1,35 +1,36 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars;
import java.util.function.IntSupplier;
@FunctionalInterface
public interface CharSupplier {
char getAsChar();
public static IntSupplier toInt(CharSupplier consumer) {
return consumer::getAsChar;
}
public static CharSupplier toChar(IntSupplier consumer) {
return () -> (char) consumer.getAsInt();
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars;
import java.util.function.IntSupplier;
@FunctionalInterface
public interface CharSupplier {
char getAsChar();
public static IntSupplier toInt(CharSupplier consumer) {
return consumer::getAsChar;
}
public static CharSupplier toChar(IntSupplier consumer) {
return () -> (char) consumer.getAsInt();
}
}

View File

@ -1,44 +1,45 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars;
public class EscapeException extends Exception {
private static final long serialVersionUID = -3647188859290365053L;
public EscapeException() {
super();
}
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) {
super(message);
}
public EscapeException(Throwable cause) {
super(cause);
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars;
public class EscapeException extends Exception {
private static final long serialVersionUID = -3647188859290365053L;
public EscapeException() {
super();
}
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) {
super(message);
}
public EscapeException(Throwable cause) {
super(cause);
}
}

View File

@ -1,474 +1,514 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars;
import java.text.CharacterIterator;
import ru.windcorp.jputil.ArrayUtil;
import ru.windcorp.jputil.chars.reader.CharReader;
import ru.windcorp.jputil.chars.reader.CharReaders;
public class Escaper {
public static class EscaperBuilder {
private char escapeChar = '\\';
private char unicodeEscapeChar = 'u';
private char[] safes = null;
private char[] unsafes = null;
private boolean preferUnicode = false;
private boolean strict = true;
public EscaperBuilder withEscapeChar(char escapeChar) {
this.escapeChar = escapeChar;
return this;
}
public EscaperBuilder withUnicodeEscapeChar(char unicodeEscapeChar) {
this.unicodeEscapeChar = unicodeEscapeChar;
return this;
}
public EscaperBuilder withChars(char[] safes, char[] unsafes) {
this.safes = safes;
this.unsafes = unsafes;
return this;
}
public EscaperBuilder withChars(String safes, String unsafes) {
this.safes = safes.toCharArray();
this.unsafes = unsafes.toCharArray();
return this;
}
public EscaperBuilder withChars(char[] chars) {
this.safes = this.unsafes = chars;
return this;
}
public EscaperBuilder withChars(String chars) {
this.safes = this.unsafes = chars.toCharArray();
return this;
}
public EscaperBuilder withSafes(char[] safes) {
this.safes = safes;
return this;
}
public EscaperBuilder withSafes(String safes) {
this.safes = safes.toCharArray();
return this;
}
public EscaperBuilder withUnsafes(char[] unsafes) {
this.unsafes = unsafes;
return this;
}
public EscaperBuilder withUnsafes(String unsafes) {
this.unsafes = unsafes.toCharArray();
return this;
}
public EscaperBuilder preferUnicode(boolean preferUnicode) {
this.preferUnicode = preferUnicode;
return this;
}
public EscaperBuilder strict(boolean strict) {
this.strict = strict;
return this;
}
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);
private final char escapeChar;
private final char unicodeEscapeChar;
private final char[] safes;
private final char[] unsafes;
private final boolean preferUnicode;
private final boolean strict;
protected Escaper(
char escapeChar, char unicodeEscapeChar,
char[] safes, char[] unsafes,
boolean preferUnicode, boolean strict) {
this.escapeChar = escapeChar;
this.unicodeEscapeChar = unicodeEscapeChar;
this.safes = safes;
this.unsafes = unsafes;
this.preferUnicode = preferUnicode;
this.strict = strict;
int duplicate;
if ((duplicate = ArrayUtil.hasDuplicates(safes)) != -1)
throw new IllegalArgumentException("Duplicate safe character '" + safes[duplicate] + "'");
if ((duplicate = ArrayUtil.hasDuplicates(unsafes)) != -1)
throw new IllegalArgumentException("Duplicate unsafe character '" + unsafes[duplicate] + "'");
for (char c : safes) {
if (c == escapeChar) throw new IllegalArgumentException("Safe characters contain escape chatacter");
if (c == unicodeEscapeChar) throw new IllegalArgumentException("Safe characters contain Unicode escape chatacter");
}
for (char c : unsafes) {
if (c == escapeChar) throw new IllegalArgumentException("Unsafe characters contain escape chatacter (escape character is escaped automatically)");
if (c == unicodeEscapeChar) throw new IllegalArgumentException("Unsafe characters contain Unicode escape chatacter");
}
}
public static EscaperBuilder create() {
return new EscaperBuilder();
}
/*
* Logic - escape
*/
public void escape(CharReader src, int length, CharPredicate until, CharConsumer output) {
int end;
if (length < 0) end = Integer.MAX_VALUE;
else end = src.getPosition() + length;
while (src.has() &&
src.getPosition() < end &&
(until == null || !until.test(src.current())))
escape(src.consume(), output);
}
public void escape(char c, CharConsumer output) {
if (c == escapeChar) {
output.accept(escapeChar);
output.accept(escapeChar);
return;
}
int index = ArrayUtil.firstIndexOf(unsafes, c);
if (index >= 0) {
output.accept(escapeChar);
output.accept(safes[index]);
} else {
if (preferUnicode && !isRegular(c)) {
escapeAsHex(c, output);
} else {
output.accept(c);
}
}
}
// SonarLint: Assignments should not be made from within sub-expressions (java:S1121)
// Seems self-evident enough
@SuppressWarnings("squid:S1121")
private void escapeAsHex(char c, CharConsumer output) {
output.accept(escapeChar);
output.accept(unicodeEscapeChar);
output.accept(StringUtil.hexDigit(c >>= (4 * 3)));
output.accept(StringUtil.hexDigit(c >>= (4 * 2)));
output.accept(StringUtil.hexDigit(c >>= (4 * 1)));
output.accept(StringUtil.hexDigit(c >> (4 * 0)));
}
public int getEscapedLength(CharReader src, int length, CharPredicate until) {
int end;
if (length < 0) end = Integer.MAX_VALUE;
else end = src.getPosition() + length;
int result = 0;
while (src.has() &&
src.getPosition() < end &&
(until == null || !until.test(src.current()))) {
result += getEscapedLength(src.consume());
}
return result;
}
public int getEscapedLength(char c) {
if (c == escapeChar || ArrayUtil.firstIndexOf(unsafes, c) >= 0)
return 2;
else {
if (preferUnicode && !isRegular(c))
return 6;
else
return 1;
}
}
/*
* Logic - unescape
*/
public void unescape(CharReader src, int length, CharPredicate until, CharConsumer output) throws EscapeException {
int end;
if (length < 0) end = Integer.MAX_VALUE;
else end = src.getPosition() + length;
while (src.has() &&
src.getPosition() < end &&
(until == null || !until.test(src.current()))) {
output.accept(unescapeOneSequence(src));
}
}
public char unescapeOneSequence(CharReader src) throws EscapeException {
int resetPos = src.getPosition();
try {
if (src.current() == escapeChar) {
src.next();
if (src.isEnd())
throw new EscapeException("Incomplete escape sequence at the end");
if (src.current() == escapeChar) {
src.next();
return escapeChar;
}
if (src.current() == unicodeEscapeChar) {
src.next();
return (char) (
hexValue(src.consume()) << (4 * 3) |
hexValue(src.consume()) << (4 * 2) |
hexValue(src.consume()) << (4 * 1) |
hexValue(src.consume()) << (4 * 0)
);
}
int index = ArrayUtil.firstIndexOf(safes, src.current());
if (index >= 0) {
src.next();
return unsafes[index];
}
if (strict)
throw new EscapeException("Unknown escape sequence \"" + escapeChar + src.current() + "\"");
else
return src.consume();
} else
return src.consume();
} catch (EscapeException | RuntimeException e) {
src.setPosition(resetPos);
throw e;
}
}
public int getUnescapedLength(CharReader src, int length, CharPredicate until) {
int end;
if (length < 0) end = Integer.MAX_VALUE;
else end = src.getPosition() + length;
int result = 0;
while (src.has() &&
src.getPosition() < end &&
(until == null || !until.test(src.current()))) {
skipOneSequence(src);
result++;
}
return result;
}
public void skipOneSequence(CharReader src) {
if (
src.current() == escapeChar
&&
src.next() == unicodeEscapeChar
) {
src.advance(4);
}
src.next();
}
/*
* Utility
*/
public void escape(CharReader src, int length, CharConsumer output) {
escape(src, length, null, output);
}
public void escape(CharReader src, CharPredicate until, CharConsumer output) {
escape(src, -1, until, output);
}
public void escape(CharReader src, CharConsumer output) {
escape(src, -1, null, output);
}
public int getEscapedLength(CharReader src, int length) {
return getEscapedLength(src, length, null);
}
public int getEscapedLength(CharReader src, CharPredicate until) {
return getEscapedLength(src, -1, until);
}
public int getEscapedLength(CharReader src) {
return getEscapedLength(src, -1, null);
}
public char[] escape(CharReader src, int length, CharPredicate until) {
src.mark();
char[] result = new char[getEscapedLength(src, length, until)];
src.reset();
escape(src, length, until, CharConsumers.fillArray(result));
return result;
}
public char[] escape(CharReader src, int length) {
return escape(src, length, (CharPredicate) null);
}
public char[] escape(CharReader src, CharPredicate until) {
return escape(src, -1, until);
}
public char[] escape(CharReader src) {
return escape(src, -1, (CharPredicate) null);
}
public void unescape(CharReader src, int length, CharConsumer output) throws EscapeException {
unescape(src, length, null, output);
}
public void unescape(CharReader src, CharPredicate until, CharConsumer output) throws EscapeException {
unescape(src, -1, until, output);
}
public void unescape(CharReader src, CharConsumer output) throws EscapeException {
unescape(src, -1, null, output);
}
public int getUnescapedLength(CharReader src, int length) {
return getUnescapedLength(src, length, null);
}
public int getUnescapedLength(CharReader src, CharPredicate until) {
return getUnescapedLength(src, -1, until);
}
public int getUnescapedLength(CharReader src) {
return getUnescapedLength(src, -1, null);
}
public char[] unescape(CharReader src, int length, CharPredicate until) throws EscapeException {
src.mark();
char[] result = new char[getUnescapedLength(src, length, until)];
src.reset();
unescape(src, length, until, CharConsumers.fillArray(result));
return result;
}
public char[] unescape(CharReader src, int length) throws EscapeException {
return unescape(src, length, (CharPredicate) null);
}
public char[] unescape(CharReader src, CharPredicate until) throws EscapeException {
return unescape(src, -1, until);
}
public char[] unescape(CharReader src) throws EscapeException {
return unescape(src, -1, (CharPredicate) null);
}
@Deprecated()
public char[] unescape(CharacterIterator src, char until) throws EscapeException {
int index = src.getIndex();
CharReader reader = CharReaders.wrap(src);
char[] result = unescape(reader, -1, CharPredicate.forChar(until));
src.setIndex(index + reader.getPosition());
return result;
}
public String escape(String src) {
StringBuilder result = new StringBuilder(src.length());
escape(CharReaders.wrap(src), (CharConsumer) result::append);
return result.toString();
}
public String unescape(String src) throws EscapeException {
StringBuilder result = new StringBuilder(src.length());
unescape(CharReaders.wrap(src), (CharConsumer) result::append);
return result.toString();
}
/*
* Misc
*/
private static int hexValue(char c) throws EscapeException {
if (c < '0') throw thisIsNotAHexDigit(c);
if (c <= '9') return c - '0';
if (c < 'A') throw thisIsNotAHexDigit(c);
if (c <= 'F') return c - 'A';
if (c < 'a') throw thisIsNotAHexDigit(c);
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;
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars;
import java.text.CharacterIterator;
import ru.windcorp.jputil.ArrayUtil;
import ru.windcorp.jputil.chars.reader.CharReader;
import ru.windcorp.jputil.chars.reader.CharReaders;
public class Escaper {
public static class EscaperBuilder {
private char escapeChar = '\\';
private char unicodeEscapeChar = 'u';
private char[] safes = null;
private char[] unsafes = null;
private boolean preferUnicode = false;
private boolean strict = true;
public EscaperBuilder withEscapeChar(char escapeChar) {
this.escapeChar = escapeChar;
return this;
}
public EscaperBuilder withUnicodeEscapeChar(char unicodeEscapeChar) {
this.unicodeEscapeChar = unicodeEscapeChar;
return this;
}
public EscaperBuilder withChars(char[] safes, char[] unsafes) {
this.safes = safes;
this.unsafes = unsafes;
return this;
}
public EscaperBuilder withChars(String safes, String unsafes) {
this.safes = safes.toCharArray();
this.unsafes = unsafes.toCharArray();
return this;
}
public EscaperBuilder withChars(char[] chars) {
this.safes = this.unsafes = chars;
return this;
}
public EscaperBuilder withChars(String chars) {
this.safes = this.unsafes = chars.toCharArray();
return this;
}
public EscaperBuilder withSafes(char[] safes) {
this.safes = safes;
return this;
}
public EscaperBuilder withSafes(String safes) {
this.safes = safes.toCharArray();
return this;
}
public EscaperBuilder withUnsafes(char[] unsafes) {
this.unsafes = unsafes;
return this;
}
public EscaperBuilder withUnsafes(String unsafes) {
this.unsafes = unsafes.toCharArray();
return this;
}
public EscaperBuilder preferUnicode(boolean preferUnicode) {
this.preferUnicode = preferUnicode;
return this;
}
public EscaperBuilder strict(boolean strict) {
this.strict = strict;
return this;
}
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
);
private final char escapeChar;
private final char unicodeEscapeChar;
private final char[] safes;
private final char[] unsafes;
private final boolean preferUnicode;
private final boolean strict;
protected Escaper(
char escapeChar,
char unicodeEscapeChar,
char[] safes,
char[] unsafes,
boolean preferUnicode,
boolean strict
) {
this.escapeChar = escapeChar;
this.unicodeEscapeChar = unicodeEscapeChar;
this.safes = safes;
this.unsafes = unsafes;
this.preferUnicode = preferUnicode;
this.strict = strict;
int duplicate;
if ((duplicate = ArrayUtil.hasDuplicates(safes)) != -1)
throw new IllegalArgumentException("Duplicate safe character '" + safes[duplicate] + "'");
if ((duplicate = ArrayUtil.hasDuplicates(unsafes)) != -1)
throw new IllegalArgumentException("Duplicate unsafe character '" + unsafes[duplicate] + "'");
for (char c : safes) {
if (c == escapeChar)
throw new IllegalArgumentException("Safe characters contain escape chatacter");
if (c == unicodeEscapeChar)
throw new IllegalArgumentException("Safe characters contain Unicode escape chatacter");
}
for (char c : unsafes) {
if (c == escapeChar)
throw new IllegalArgumentException(
"Unsafe characters contain escape chatacter (escape character is escaped automatically)"
);
if (c == unicodeEscapeChar)
throw new IllegalArgumentException("Unsafe characters contain Unicode escape chatacter");
}
}
public static EscaperBuilder create() {
return new EscaperBuilder();
}
/*
* Logic - escape
*/
public void escape(CharReader src, int length, CharPredicate until, CharConsumer output) {
int end;
if (length < 0)
end = Integer.MAX_VALUE;
else
end = src.getPosition() + length;
while (
src.has() &&
src.getPosition() < end &&
(until == null || !until.test(src.current()))
)
escape(src.consume(), output);
}
public void escape(char c, CharConsumer output) {
if (c == escapeChar) {
output.accept(escapeChar);
output.accept(escapeChar);
return;
}
int index = ArrayUtil.firstIndexOf(unsafes, c);
if (index >= 0) {
output.accept(escapeChar);
output.accept(safes[index]);
} else {
if (preferUnicode && !isRegular(c)) {
escapeAsHex(c, output);
} else {
output.accept(c);
}
}
}
// SonarLint: Assignments should not be made from within sub-expressions
// (java:S1121)
// Seems self-evident enough
@SuppressWarnings("squid:S1121")
private void escapeAsHex(char c, CharConsumer output) {
output.accept(escapeChar);
output.accept(unicodeEscapeChar);
output.accept(StringUtil.hexDigit(c >>= (4 * 3)));
output.accept(StringUtil.hexDigit(c >>= (4 * 2)));
output.accept(StringUtil.hexDigit(c >>= (4 * 1)));
output.accept(StringUtil.hexDigit(c >> (4 * 0)));
}
public int getEscapedLength(CharReader src, int length, CharPredicate until) {
int end;
if (length < 0)
end = Integer.MAX_VALUE;
else
end = src.getPosition() + length;
int result = 0;
while (
src.has() &&
src.getPosition() < end &&
(until == null || !until.test(src.current()))
) {
result += getEscapedLength(src.consume());
}
return result;
}
public int getEscapedLength(char c) {
if (c == escapeChar || ArrayUtil.firstIndexOf(unsafes, c) >= 0)
return 2;
else {
if (preferUnicode && !isRegular(c))
return 6;
else
return 1;
}
}
/*
* Logic - unescape
*/
public void unescape(CharReader src, int length, CharPredicate until, CharConsumer output) throws EscapeException {
int end;
if (length < 0)
end = Integer.MAX_VALUE;
else
end = src.getPosition() + length;
while (
src.has() &&
src.getPosition() < end &&
(until == null || !until.test(src.current()))
) {
output.accept(unescapeOneSequence(src));
}
}
public char unescapeOneSequence(CharReader src) throws EscapeException {
int resetPos = src.getPosition();
try {
if (src.current() == escapeChar) {
src.next();
if (src.isEnd())
throw new EscapeException("Incomplete escape sequence at the end");
if (src.current() == escapeChar) {
src.next();
return escapeChar;
}
if (src.current() == unicodeEscapeChar) {
src.next();
return (char) (hexValue(src.consume()) << (4 * 3) |
hexValue(src.consume()) << (4 * 2) |
hexValue(src.consume()) << (4 * 1) |
hexValue(src.consume()) << (4 * 0));
}
int index = ArrayUtil.firstIndexOf(safes, src.current());
if (index >= 0) {
src.next();
return unsafes[index];
}
if (strict)
throw new EscapeException("Unknown escape sequence \"" + escapeChar + src.current() + "\"");
else
return src.consume();
} else
return src.consume();
} catch (EscapeException | RuntimeException e) {
src.setPosition(resetPos);
throw e;
}
}
public int getUnescapedLength(CharReader src, int length, CharPredicate until) {
int end;
if (length < 0)
end = Integer.MAX_VALUE;
else
end = src.getPosition() + length;
int result = 0;
while (
src.has() &&
src.getPosition() < end &&
(until == null || !until.test(src.current()))
) {
skipOneSequence(src);
result++;
}
return result;
}
public void skipOneSequence(CharReader src) {
if (
src.current() == escapeChar
&&
src.next() == unicodeEscapeChar
) {
src.advance(4);
}
src.next();
}
/*
* Utility
*/
public void escape(CharReader src, int length, CharConsumer output) {
escape(src, length, null, output);
}
public void escape(CharReader src, CharPredicate until, CharConsumer output) {
escape(src, -1, until, output);
}
public void escape(CharReader src, CharConsumer output) {
escape(src, -1, null, output);
}
public int getEscapedLength(CharReader src, int length) {
return getEscapedLength(src, length, null);
}
public int getEscapedLength(CharReader src, CharPredicate until) {
return getEscapedLength(src, -1, until);
}
public int getEscapedLength(CharReader src) {
return getEscapedLength(src, -1, null);
}
public char[] escape(CharReader src, int length, CharPredicate until) {
src.mark();
char[] result = new char[getEscapedLength(src, length, until)];
src.reset();
escape(src, length, until, CharConsumers.fillArray(result));
return result;
}
public char[] escape(CharReader src, int length) {
return escape(src, length, (CharPredicate) null);
}
public char[] escape(CharReader src, CharPredicate until) {
return escape(src, -1, until);
}
public char[] escape(CharReader src) {
return escape(src, -1, (CharPredicate) null);
}
public void unescape(CharReader src, int length, CharConsumer output) throws EscapeException {
unescape(src, length, null, output);
}
public void unescape(CharReader src, CharPredicate until, CharConsumer output) throws EscapeException {
unescape(src, -1, until, output);
}
public void unescape(CharReader src, CharConsumer output) throws EscapeException {
unescape(src, -1, null, output);
}
public int getUnescapedLength(CharReader src, int length) {
return getUnescapedLength(src, length, null);
}
public int getUnescapedLength(CharReader src, CharPredicate until) {
return getUnescapedLength(src, -1, until);
}
public int getUnescapedLength(CharReader src) {
return getUnescapedLength(src, -1, null);
}
public char[] unescape(CharReader src, int length, CharPredicate until) throws EscapeException {
src.mark();
char[] result = new char[getUnescapedLength(src, length, until)];
src.reset();
unescape(src, length, until, CharConsumers.fillArray(result));
return result;
}
public char[] unescape(CharReader src, int length) throws EscapeException {
return unescape(src, length, (CharPredicate) null);
}
public char[] unescape(CharReader src, CharPredicate until) throws EscapeException {
return unescape(src, -1, until);
}
public char[] unescape(CharReader src) throws EscapeException {
return unescape(src, -1, (CharPredicate) null);
}
@Deprecated()
public char[] unescape(CharacterIterator src, char until) throws EscapeException {
int index = src.getIndex();
CharReader reader = CharReaders.wrap(src);
char[] result = unescape(reader, -1, CharPredicate.forChar(until));
src.setIndex(index + reader.getPosition());
return result;
}
public String escape(String src) {
StringBuilder result = new StringBuilder(src.length());
escape(CharReaders.wrap(src), (CharConsumer) result::append);
return result.toString();
}
public String unescape(String src) throws EscapeException {
StringBuilder result = new StringBuilder(src.length());
unescape(CharReaders.wrap(src), (CharConsumer) result::append);
return result.toString();
}
/*
* Misc
*/
private static int hexValue(char c) throws EscapeException {
if (c < '0')
throw thisIsNotAHexDigit(c);
if (c <= '9')
return c - '0';
if (c < 'A')
throw thisIsNotAHexDigit(c);
if (c <= 'F')
return c - 'A';
if (c < 'a')
throw thisIsNotAHexDigit(c);
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
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars;
import java.text.CharacterIterator;
@ -26,77 +30,81 @@ public class FancyCharacterIterator implements CharacterIterator {
this.data = data;
}
@Override
@Override
public char first() {
return obj.first();
}
@Override
@Override
public char last() {
return obj.last();
}
@Override
@Override
public char setIndex(int p) {
return obj.setIndex(p);
}
@Override
@Override
public char current() {
return obj.current();
}
@Override
@Override
public char next() {
return obj.next();
}
@Override
@Override
public char previous() {
return obj.previous();
}
@Override
@Override
public int getBeginIndex() {
return obj.getBeginIndex();
}
@Override
@Override
public int getEndIndex() {
return obj.getEndIndex();
}
@Override
@Override
public int getIndex() {
return obj.getIndex();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("\"");
sb.append(data);
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.");
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
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars;
public class IndentedStringBuilder {
private final StringBuilder sb = new StringBuilder();
private int indentLevel = 0;
private boolean indentApplied = false;
private String[] indentCache = new String[16];
private String indent = "";
private final char[] indentFill;
public IndentedStringBuilder(char[] indentFill) {
this.indentFill = indentFill;
}
public IndentedStringBuilder(String indentFill) {
this(indentFill.toCharArray());
}
public IndentedStringBuilder(char indentChar, int length) {
this(StringUtil.sequence(indentChar, length));
}
public IndentedStringBuilder() {
this(new char[] {' '});
}
@Override
public String toString() {
return sb.toString();
}
public int getIndentLevel() {
return indentLevel;
}
public void setIndentLevel(int level) {
this.indentLevel = level;
updateIndent();
}
public char[] getIndentFill() {
return indentFill;
}
protected void updateIndent() {
if (indentLevel < indentCache.length) {
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)
System.arraycopy(fill, 0, array, i, fill.length);
indent = new String(array);
if (indentLevel < indentCache.length) {
indentCache[indentLevel] = indent;
}
}
public IndentedStringBuilder indent() {
setIndentLevel(getIndentLevel() + 1);
return this;
}
public IndentedStringBuilder unindent() {
setIndentLevel(getIndentLevel() - 1);
return this;
}
public IndentedStringBuilder append(Object x) {
if (x == null) {
appendRaw("null");
return this;
}
String str = x.toString();
int newLines = StringUtil.count(str, '\n');
if (newLines == 0) {
appendRaw(str);
return this;
}
String[] lines = StringUtil.split(str, '\n', newLines + 1);
appendRaw(lines[0]);
for (int i = 1; i < lines.length; ++i) {
newLine();
appendRaw(lines[i]);
}
return this;
}
public IndentedStringBuilder appendRaw(String str) {
if (str.isEmpty()) return this; // Do not append indent
if (!indentApplied) {
sb.append(indent);
indentApplied = true;
}
sb.append(str);
return this;
}
public IndentedStringBuilder newLine() {
sb.append('\n');
indentApplied = false;
return this;
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars;
public class IndentedStringBuilder {
private final StringBuilder sb = new StringBuilder();
private int indentLevel = 0;
private boolean indentApplied = false;
private String[] indentCache = new String[16];
private String indent = "";
private final char[] indentFill;
public IndentedStringBuilder(char[] indentFill) {
this.indentFill = indentFill;
}
public IndentedStringBuilder(String indentFill) {
this(indentFill.toCharArray());
}
public IndentedStringBuilder(char indentChar, int length) {
this(StringUtil.sequence(indentChar, length));
}
public IndentedStringBuilder() {
this(new char[] { ' ' });
}
@Override
public String toString() {
return sb.toString();
}
public int getIndentLevel() {
return indentLevel;
}
public void setIndentLevel(int level) {
this.indentLevel = level;
updateIndent();
}
public char[] getIndentFill() {
return indentFill;
}
protected void updateIndent() {
if (indentLevel < indentCache.length) {
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)
System.arraycopy(fill, 0, array, i, fill.length);
indent = new String(array);
if (indentLevel < indentCache.length) {
indentCache[indentLevel] = indent;
}
}
public IndentedStringBuilder indent() {
setIndentLevel(getIndentLevel() + 1);
return this;
}
public IndentedStringBuilder unindent() {
setIndentLevel(getIndentLevel() - 1);
return this;
}
public IndentedStringBuilder append(Object x) {
if (x == null) {
appendRaw("null");
return this;
}
String str = x.toString();
int newLines = StringUtil.count(str, '\n');
if (newLines == 0) {
appendRaw(str);
return this;
}
String[] lines = StringUtil.split(str, '\n', newLines + 1);
appendRaw(lines[0]);
for (int i = 1; i < lines.length; ++i) {
newLine();
appendRaw(lines[i]);
}
return this;
}
public IndentedStringBuilder appendRaw(String str) {
if (str.isEmpty())
return this; // Do not append indent
if (!indentApplied) {
sb.append(indent);
indentApplied = true;
}
sb.append(str);
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
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars;
public class UncheckedEscapeException extends RuntimeException {
private static final long serialVersionUID = 5392628641744570926L;
public UncheckedEscapeException(String message, EscapeException cause) {
super(message, cause);
}
public UncheckedEscapeException(EscapeException cause) {
super(cause);
}
@Override
public synchronized EscapeException getCause() {
return (EscapeException) super.getCause();
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars;
public class UncheckedEscapeException extends RuntimeException {
private static final long serialVersionUID = 5392628641744570926L;
public UncheckedEscapeException(String message, EscapeException cause) {
super(message, cause);
}
public UncheckedEscapeException(EscapeException cause) {
super(cause);
}
@Override
public synchronized EscapeException getCause() {
return (EscapeException) super.getCause();
}
}

View File

@ -1,139 +1,143 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars;
import java.io.IOException;
import java.io.Reader;
import java.nio.CharBuffer;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class WordReader implements Iterator<String> {
private final Reader reader;
private char[] wordBuffer = new char[1024];
private final CharBuffer inputBuffer;
private String next = null;
private boolean isExhausted = false;
private IOException lastException = null;
public WordReader(Reader src, int bufferSize) {
this.reader = src;
this.inputBuffer = CharBuffer.allocate(bufferSize);
}
public WordReader(Reader src) {
this(src, 2048);
}
public WordReader(char[] array, int offset, int length) {
this.reader = null;
this.inputBuffer = CharBuffer.wrap(Arrays.copyOfRange(array, offset, length + offset));
}
public WordReader(char[] array) {
this.reader = null;
this.inputBuffer = CharBuffer.wrap(array);
}
public WordReader(String str) {
this(str.toCharArray());
}
@Override
public String next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
String result = next;
next = null;
return result;
}
@Override
public boolean hasNext() {
if (next != null) {
return true;
}
if (isExhausted) {
return false;
}
int length = 0;
char c;
while (true) {
c = nextChar();
if (isExhausted) break;
if (Character.isWhitespace(c)) {
if (length == 0) continue;
else break;
}
if (wordBuffer.length == length) {
char[] newBuf = new char[wordBuffer.length * 2];
System.arraycopy(wordBuffer, 0, newBuf, 0, wordBuffer.length);
wordBuffer = newBuf;
}
wordBuffer[length++] = c;
}
if (length == 0) {
return false;
}
next = new String(wordBuffer, 0, length);
return true;
}
private char nextChar() {
if (!inputBuffer.hasRemaining()) {
if (reader == null) {
isExhausted = true;
return 0;
}
inputBuffer.rewind();
try {
if (reader.read(inputBuffer) == -1) {
isExhausted = true;
}
} catch (IOException e) {
lastException = e;
isExhausted = true;
return 0;
}
}
return inputBuffer.get();
}
public IOException getLastException() {
return lastException;
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars;
import java.io.IOException;
import java.io.Reader;
import java.nio.CharBuffer;
import java.util.Arrays;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class WordReader implements Iterator<String> {
private final Reader reader;
private char[] wordBuffer = new char[1024];
private final CharBuffer inputBuffer;
private String next = null;
private boolean isExhausted = false;
private IOException lastException = null;
public WordReader(Reader src, int bufferSize) {
this.reader = src;
this.inputBuffer = CharBuffer.allocate(bufferSize);
}
public WordReader(Reader src) {
this(src, 2048);
}
public WordReader(char[] array, int offset, int length) {
this.reader = null;
this.inputBuffer = CharBuffer.wrap(Arrays.copyOfRange(array, offset, length + offset));
}
public WordReader(char[] array) {
this.reader = null;
this.inputBuffer = CharBuffer.wrap(array);
}
public WordReader(String str) {
this(str.toCharArray());
}
@Override
public String next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
String result = next;
next = null;
return result;
}
@Override
public boolean hasNext() {
if (next != null) {
return true;
}
if (isExhausted) {
return false;
}
int length = 0;
char c;
while (true) {
c = nextChar();
if (isExhausted)
break;
if (Character.isWhitespace(c)) {
if (length == 0)
continue;
else
break;
}
if (wordBuffer.length == length) {
char[] newBuf = new char[wordBuffer.length * 2];
System.arraycopy(wordBuffer, 0, newBuf, 0, wordBuffer.length);
wordBuffer = newBuf;
}
wordBuffer[length++] = c;
}
if (length == 0) {
return false;
}
next = new String(wordBuffer, 0, length);
return true;
}
private char nextChar() {
if (!inputBuffer.hasRemaining()) {
if (reader == null) {
isExhausted = true;
return 0;
}
inputBuffer.rewind();
try {
if (reader.read(inputBuffer) == -1) {
isExhausted = true;
}
} catch (IOException e) {
lastException = e;
isExhausted = true;
return 0;
}
}
return inputBuffer.get();
}
public IOException getLastException() {
return lastException;
}
}

View File

@ -1,104 +1,108 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars.reader;
/**
* @author Javapony
*
*/
public abstract class AbstractCharReader implements CharReader {
protected static final int DEFAULT_MARK_STACK_SIZE = 8;
/**
* Current position of this CharReader. The reader maps its input to positions starting from 0.
* Positions that are negative or lower than 0 are invalid. {@link #current()}
* will throw an exception if position is invalid.
*/
protected int position = 0;
private int[] marks = new int[DEFAULT_MARK_STACK_SIZE];
private int nextMark = 0;
protected static int closestGreaterPowerOf2(int x) {
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return x + 1;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#getPosition()
*/
@Override
public int getPosition() {
return position;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#setPosition(int)
*/
@Override
public int setPosition(int position) {
this.position = position;
return position;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#mark()
*/
@Override
public int mark() {
ensureMarksCapacity();
marks[nextMark++] = position;
return position;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#forget()
*/
@Override
public int forget() {
return marks[--nextMark];
}
private void ensureMarksCapacity() {
if (nextMark < marks.length) return;
int[] newMarks = new int[closestGreaterPowerOf2(nextMark)];
System.arraycopy(marks, 0, newMarks, 0, nextMark);
marks = newMarks;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("\"");
mark();
position = 0;
sb.append(getChars());
reset();
sb.append("\"\n ");
for (int i = 0; i < position; ++i) sb.append(' ');
sb.append("^ (pos " + position + ")");
return sb.toString();
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars.reader;
/**
* @author Javapony
*/
public abstract class AbstractCharReader implements CharReader {
protected static final int DEFAULT_MARK_STACK_SIZE = 8;
/**
* Current position of this CharReader. The reader maps its input to
* positions starting from 0.
* Positions that are negative or lower than 0 are invalid.
* {@link #current()}
* will throw an exception if position is invalid.
*/
protected int position = 0;
private int[] marks = new int[DEFAULT_MARK_STACK_SIZE];
private int nextMark = 0;
protected static int closestGreaterPowerOf2(int x) {
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
return x + 1;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#getPosition()
*/
@Override
public int getPosition() {
return position;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#setPosition(int)
*/
@Override
public int setPosition(int position) {
this.position = position;
return position;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#mark()
*/
@Override
public int mark() {
ensureMarksCapacity();
marks[nextMark++] = position;
return position;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#forget()
*/
@Override
public int forget() {
return marks[--nextMark];
}
private void ensureMarksCapacity() {
if (nextMark < marks.length)
return;
int[] newMarks = new int[closestGreaterPowerOf2(nextMark)];
System.arraycopy(marks, 0, newMarks, 0, nextMark);
marks = newMarks;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("\"");
mark();
position = 0;
sb.append(getChars());
reset();
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
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars.reader;
import java.util.Objects;
import ru.windcorp.jputil.ArrayUtil;
/**
* @author Javapony
*
*/
public class ArrayCharReader extends AbstractCharReader {
private final char[] array;
private final int offset;
private final int length;
public ArrayCharReader(char[] array, int offset, int length) {
this.array = Objects.requireNonNull(array, "array");
this.length = ArrayUtil.checkArrayOffsetLength(array, offset, length);
this.offset = offset;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#current()
*/
@Override
public char current() {
if (position >= length) return DONE;
if (position < 0)
throw new IllegalStateException("Position " + position + " is invalid");
return array[position + offset];
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#remaining()
*/
@Override
public int remaining() {
return length - position;
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars.reader;
import java.util.Objects;
import ru.windcorp.jputil.ArrayUtil;
/**
* @author Javapony
*/
public class ArrayCharReader extends AbstractCharReader {
private final char[] array;
private final int offset;
private final int length;
public ArrayCharReader(char[] array, int offset, int length) {
this.array = Objects.requireNonNull(array, "array");
this.length = ArrayUtil.checkArrayOffsetLength(array, offset, length);
this.offset = offset;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#current()
*/
@Override
public char current() {
if (position >= length)
return DONE;
if (position < 0)
throw new IllegalStateException("Position " + position + " is invalid");
return array[position + offset];
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#remaining()
*/
@Override
public int remaining() {
return length - position;
}
}

View File

@ -1,122 +1,128 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars.reader;
/**
* @author Javapony
*
*/
public abstract class BufferedCharReader extends AbstractCharReader {
protected static final int DEFAULT_BUFFER_SIZE = 256;
/**
* Buffer to store data acquired with {@link #pullChars(char[], int, int)}.
* Contains characters for positions <code>[0; bufferNextIndex)</code>.
*/
private char[] buffer = new char[DEFAULT_BUFFER_SIZE];
/**
* The index of the next character.
*/
private int bufferNextIndex = 0;
/**
* Whether this reader has been buffered completely.
*/
private boolean exhausted = false;
/**
* Acquires the next character.
* @return the character or {@link #DONE} if the end of the reader has been reached
*/
protected abstract char pullChar();
/**
* Acquires next characters and stores them in the array.
*
* @param buffer the output array
* @param offset index of the first character
* @param length maximum amount of characters to be pulled
* @return the amount of characters actually pulled
*/
protected int pullChars(char[] buffer, int offset, int length) {
for (int i = 0; i < length; ++i) {
if ((buffer[offset + i] = pullChar()) == DONE) {
return i;
}
}
return length;
}
private int pullChars(int offset, int length) {
if (exhausted || length == 0) return 0;
int pulled = pullChars(buffer, offset, length);
if (pulled != length) {
exhausted = true;
}
return pulled;
}
@Override
public char current() {
if (getPosition() < 0) {
throw new IllegalStateException("Position " + getPosition() + " is invalid");
}
if (getPosition() >= bufferNextIndex) {
if (exhausted) return DONE;
ensureBufferCapacity();
int needToPull = getPosition() - bufferNextIndex + 1;
assert needToPull <= buffer.length : "buffer size not ensured!";
int pulled = pullChars(bufferNextIndex, needToPull);
bufferNextIndex += pulled;
if (exhausted) return DONE;
}
// TODO test the shit out of current()
return buffer[getPosition()];
}
private void ensureBufferCapacity() {
if (getPosition() < buffer.length) return;
char[] newBuffer = new char[closestGreaterPowerOf2(getPosition())];
System.arraycopy(buffer, 0, newBuffer, 0, bufferNextIndex);
buffer = newBuffer;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#remaining()
*/
@Override
public int remaining() {
if (exhausted) {
return Math.max(bufferNextIndex - getPosition(), 0);
}
return super.remaining();
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars.reader;
/**
* @author Javapony
*/
public abstract class BufferedCharReader extends AbstractCharReader {
protected static final int DEFAULT_BUFFER_SIZE = 256;
/**
* Buffer to store data acquired with {@link #pullChars(char[], int, int)}.
* Contains characters for positions <code>[0; bufferNextIndex)</code>.
*/
private char[] buffer = new char[DEFAULT_BUFFER_SIZE];
/**
* The index of the next character.
*/
private int bufferNextIndex = 0;
/**
* Whether this reader has been buffered completely.
*/
private boolean exhausted = false;
/**
* Acquires the next character.
*
* @return the character or {@link #DONE} if the end of the reader has been
* reached
*/
protected abstract char pullChar();
/**
* Acquires next characters and stores them in the array.
*
* @param buffer the output array
* @param offset index of the first character
* @param length maximum amount of characters to be pulled
* @return the amount of characters actually pulled
*/
protected int pullChars(char[] buffer, int offset, int length) {
for (int i = 0; i < length; ++i) {
if ((buffer[offset + i] = pullChar()) == DONE) {
return i;
}
}
return length;
}
private int pullChars(int offset, int length) {
if (exhausted || length == 0)
return 0;
int pulled = pullChars(buffer, offset, length);
if (pulled != length) {
exhausted = true;
}
return pulled;
}
@Override
public char current() {
if (getPosition() < 0) {
throw new IllegalStateException("Position " + getPosition() + " is invalid");
}
if (getPosition() >= bufferNextIndex) {
if (exhausted)
return DONE;
ensureBufferCapacity();
int needToPull = getPosition() - bufferNextIndex + 1;
assert needToPull <= buffer.length : "buffer size not ensured!";
int pulled = pullChars(bufferNextIndex, needToPull);
bufferNextIndex += pulled;
if (exhausted)
return DONE;
}
// TODO test the shit out of current()
return buffer[getPosition()];
}
private void ensureBufferCapacity() {
if (getPosition() < buffer.length)
return;
char[] newBuffer = new char[closestGreaterPowerOf2(getPosition())];
System.arraycopy(buffer, 0, newBuffer, 0, bufferNextIndex);
buffer = newBuffer;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#remaining()
*/
@Override
public int remaining() {
if (exhausted) {
return Math.max(bufferNextIndex - getPosition(), 0);
}
return super.remaining();
}
}

View File

@ -1,270 +1,284 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars.reader;
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.Escaper;
/**
* @author Javapony
*
*/
// SonarLint: Constants should not be defined in interfaces (java:S1214)
// DONE is an essential part of the interface
@SuppressWarnings("squid:S1214")
public interface CharReader {
char DONE = '\uFFFF';
char current();
int getPosition();
int setPosition(int position);
default char next() {
return advance(1);
}
default char previous() {
return rollBack(1);
}
default char consume() {
char c = current();
advance(1);
return c;
}
default char advance(int forward) {
setPosition(getPosition() + forward);
return current();
}
default char rollBack(int backward) {
return advance(-backward);
}
default boolean isEnd() {
return current() == DONE;
}
default boolean has() {
return current() != DONE;
}
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) {
return i;
}
next();
}
return 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);
if (from != length) Arrays.fill(result, from, length, DONE);
return result;
}
default char[] getChars() {
return getChars(remaining());
}
default String getString(int length) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length && !isEnd(); ++i) sb.append(consume());
return sb.toString();
}
default String getString() {
return getString(Integer.MAX_VALUE);
}
default boolean match(CharSequence seq) {
for (int i = 0; i < seq.length(); ++i) {
if (isEnd()) return false;
if (current() != seq.charAt(i)) return false;
next();
}
return true;
}
default boolean matchOrReset(CharSequence seq) {
mark();
if (match(seq)) {
forget();
return true;
} else {
reset();
return false;
}
}
default boolean match(char[] array) {
for (int i = 0; i < array.length; ++i) {
if (isEnd()) return false;
if (current() != array[i]) return false;
next();
}
return true;
}
default boolean matchOrReset(char[] array) {
mark();
if (match(array)) {
forget();
return true;
} else {
reset();
return false;
}
}
default int skip(CharPredicate condition) {
int i = 0;
while (has() && condition.test(current())) {
i++;
next();
}
return i;
}
default int skipWhitespace() {
return skip(Character::isWhitespace);
}
/**
* Skips to the end of the current line. Both <code>"\n"</code>, <code>"\r"</code>
* and <code>"\r\n"</code> are considered line separators.
* @return the amount of characters in the skipped line
*/
default int skipLine() {
int i = 0;
while (!isEnd()) {
if (current() == '\r') {
if (next() == '\n') {
next();
}
break;
} else if (current() == '\n') {
next();
break;
}
i++;
next();
}
return i;
}
default char[] readWhile(CharPredicate condition) {
return readUntil(CharPredicate.negate(condition));
}
default char[] readUntil(CharPredicate condition) {
mark();
int length = 0;
while (!isEnd() && !condition.test(current())) {
length++;
next();
}
reset();
char[] result = new char[length];
for (int i = 0; i < length; ++i) result[i] = consume();
return result;
}
default char[] readWord() {
skipWhitespace();
return readUntil(Character::isWhitespace);
}
default char[] readWord(Escaper escaper, char quotes) throws EscapeException {
skipWhitespace();
if (current() == quotes) {
return escaper.unescape(this, quotes);
} else {
return readWord();
}
}
default char[] readLine() {
mark();
int length = skipLine();
reset();
char[] result = new char[length];
for (int i = 0; i < result.length; ++i) result[i] = consume();
return result;
}
default int remaining() {
mark();
int result = 0;
while (consume() != DONE) result++;
reset();
return result;
}
int mark();
int forget();
default int reset() {
return setPosition(forget());
}
default IOException getLastException() {
return null;
}
default void resetLastException() {
// Do nothing
}
default boolean hasErrored() {
return getLastException() != null;
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars.reader;
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.Escaper;
/**
* @author Javapony
*/
// SonarLint: Constants should not be defined in interfaces (java:S1214)
// DONE is an essential part of the interface
@SuppressWarnings("squid:S1214")
public interface CharReader {
char DONE = '\uFFFF';
char current();
int getPosition();
int setPosition(int position);
default char next() {
return advance(1);
}
default char previous() {
return rollBack(1);
}
default char consume() {
char c = current();
advance(1);
return c;
}
default char advance(int forward) {
setPosition(getPosition() + forward);
return current();
}
default char rollBack(int backward) {
return advance(-backward);
}
default boolean isEnd() {
return current() == DONE;
}
default boolean has() {
return current() != DONE;
}
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) {
return i;
}
next();
}
return 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);
if (from != length)
Arrays.fill(result, from, length, DONE);
return result;
}
default char[] getChars() {
return getChars(remaining());
}
default String getString(int length) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length && !isEnd(); ++i)
sb.append(consume());
return sb.toString();
}
default String getString() {
return getString(Integer.MAX_VALUE);
}
default boolean match(CharSequence seq) {
for (int i = 0; i < seq.length(); ++i) {
if (isEnd())
return false;
if (current() != seq.charAt(i))
return false;
next();
}
return true;
}
default boolean matchOrReset(CharSequence seq) {
mark();
if (match(seq)) {
forget();
return true;
} else {
reset();
return false;
}
}
default boolean match(char[] array) {
for (int i = 0; i < array.length; ++i) {
if (isEnd())
return false;
if (current() != array[i])
return false;
next();
}
return true;
}
default boolean matchOrReset(char[] array) {
mark();
if (match(array)) {
forget();
return true;
} else {
reset();
return false;
}
}
default int skip(CharPredicate condition) {
int i = 0;
while (has() && condition.test(current())) {
i++;
next();
}
return i;
}
default int skipWhitespace() {
return skip(Character::isWhitespace);
}
/**
* Skips to the end of the current line. Both <code>"\n"</code>,
* <code>"\r"</code>
* and <code>"\r\n"</code> are considered line separators.
*
* @return the amount of characters in the skipped line
*/
default int skipLine() {
int i = 0;
while (!isEnd()) {
if (current() == '\r') {
if (next() == '\n') {
next();
}
break;
} else if (current() == '\n') {
next();
break;
}
i++;
next();
}
return i;
}
default char[] readWhile(CharPredicate condition) {
return readUntil(CharPredicate.negate(condition));
}
default char[] readUntil(CharPredicate condition) {
mark();
int length = 0;
while (!isEnd() && !condition.test(current())) {
length++;
next();
}
reset();
char[] result = new char[length];
for (int i = 0; i < length; ++i)
result[i] = consume();
return result;
}
default char[] readWord() {
skipWhitespace();
return readUntil(Character::isWhitespace);
}
default char[] readWord(Escaper escaper, char quotes) throws EscapeException {
skipWhitespace();
if (current() == quotes) {
return escaper.unescape(this, quotes);
} else {
return readWord();
}
}
default char[] readLine() {
mark();
int length = skipLine();
reset();
char[] result = new char[length];
for (int i = 0; i < result.length; ++i)
result[i] = consume();
return result;
}
default int remaining() {
mark();
int result = 0;
while (consume() != DONE)
result++;
reset();
return result;
}
int mark();
int forget();
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
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars.reader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.CharacterIterator;
import java.util.function.IntSupplier;
import ru.windcorp.jputil.chars.CharSupplier;
/**
* @author Javapony
*
*/
public class 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) {
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) {
return wrap(str, 0, str.length());
}
public static CharReader wrap(CharSupplier supplier) {
return new BufferedCharReader() {
@Override
protected char pullChar() {
try {
return supplier.getAsChar();
} catch (Exception e) {
return DONE;
}
}
};
}
public static CharReader wrap(IntSupplier supplier) {
return new BufferedCharReader() {
@Override
protected char pullChar() {
try {
int i = supplier.getAsInt();
if (i < 0 || i > Character.MAX_VALUE) {
return DONE;
} else {
return (char) i;
}
} catch (Exception e) {
return DONE;
}
}
};
}
public static CharReader wrap(CharacterIterator it) {
return new BufferedCharReader() {
@Override
protected char pullChar() {
char result = it.current();
it.next();
return result;
}
};
}
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 wrapDefaultCS(InputStream is) {
return wrap(new InputStreamReader(is));
}
public static CharReader wrapUTF8(InputStream is) {
return wrap(new InputStreamReader(is, StandardCharsets.UTF_8));
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars.reader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.CharacterIterator;
import java.util.function.IntSupplier;
import ru.windcorp.jputil.chars.CharSupplier;
/**
* @author Javapony
*/
public class 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) {
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) {
return wrap(str, 0, str.length());
}
public static CharReader wrap(CharSupplier supplier) {
return new BufferedCharReader() {
@Override
protected char pullChar() {
try {
return supplier.getAsChar();
} catch (Exception e) {
return DONE;
}
}
};
}
public static CharReader wrap(IntSupplier supplier) {
return new BufferedCharReader() {
@Override
protected char pullChar() {
try {
int i = supplier.getAsInt();
if (i < 0 || i > Character.MAX_VALUE) {
return DONE;
} else {
return (char) i;
}
} catch (Exception e) {
return DONE;
}
}
};
}
public static CharReader wrap(CharacterIterator it) {
return new BufferedCharReader() {
@Override
protected char pullChar() {
char result = it.current();
it.next();
return result;
}
};
}
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 wrapDefaultCS(InputStream is) {
return wrap(new InputStreamReader(is));
}
public static CharReader wrapUTF8(InputStream is) {
return wrap(new InputStreamReader(is, StandardCharsets.UTF_8));
}
}

View File

@ -1,70 +1,71 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars.reader;
import java.io.IOException;
import java.io.Reader;
/**
* @author Javapony
*
*/
public class ReaderCharReader extends BufferedCharReader {
private final Reader src;
private IOException lastException = null;
public ReaderCharReader(Reader src) {
this.src = src;
}
/**
* @see ru.windcorp.jputil.chars.reader.BufferedCharReader#pullChar()
*/
@Override
protected char pullChar() {
try {
return (char) src.read(); // Handles DONE correctly
} catch (IOException e) {
lastException = e;
return DONE;
}
}
/**
* @see ru.windcorp.jputil.chars.reader.BufferedCharReader#pullChars(char[], int, int)
*/
@Override
protected int pullChars(char[] buffer, int offset, int length) {
try {
return src.read(buffer, offset, length);
} catch (IOException e) {
lastException = e;
return 0;
}
}
/**
* @return the exception
*/
@Override
public IOException getLastException() {
return lastException;
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars.reader;
import java.io.IOException;
import java.io.Reader;
/**
* @author Javapony
*/
public class ReaderCharReader extends BufferedCharReader {
private final Reader src;
private IOException lastException = null;
public ReaderCharReader(Reader src) {
this.src = src;
}
/**
* @see ru.windcorp.jputil.chars.reader.BufferedCharReader#pullChar()
*/
@Override
protected char pullChar() {
try {
return (char) src.read(); // Handles DONE correctly
} catch (IOException e) {
lastException = e;
return DONE;
}
}
/**
* @see ru.windcorp.jputil.chars.reader.BufferedCharReader#pullChars(char[],
* int, int)
*/
@Override
protected int pullChars(char[] buffer, int offset, int length) {
try {
return src.read(buffer, offset, length);
} catch (IOException e) {
lastException = e;
return 0;
}
}
/**
* @return the exception
*/
@Override
public IOException getLastException() {
return lastException;
}
}

View File

@ -1,65 +1,68 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.chars.reader;
import java.util.Objects;
/**
* @author Javapony
*
*/
public class StringCharReader extends AbstractCharReader {
private final String str;
private final int offset;
private final int length;
public StringCharReader(String str, int offset, int length) {
this.str = Objects.requireNonNull(str, "str");
if (length < 0)
length = str.length();
int end = offset + length;
if (end > str.length() || offset < 0)
throw new IllegalArgumentException("String contains [0; " + str.length() + "), requested [" + offset + "; " + end + ")");
this.offset = offset;
this.length = length;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#current()
*/
@Override
public char current() {
if (position >= length) 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() {
return length - position;
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.chars.reader;
import java.util.Objects;
/**
* @author Javapony
*/
public class StringCharReader extends AbstractCharReader {
private final String str;
private final int offset;
private final int length;
public StringCharReader(String str, int offset, int length) {
this.str = Objects.requireNonNull(str, "str");
if (length < 0)
length = str.length();
int end = offset + length;
if (end > str.length() || offset < 0)
throw new IllegalArgumentException(
"String contains [0; " + str.length() + "), requested [" + offset + "; " + end + ")"
);
this.offset = offset;
this.length = length;
}
/**
* @see ru.windcorp.jputil.chars.reader.CharReader#current()
*/
@Override
public char current() {
if (position >= length)
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() {
return length - position;
}
}

View File

@ -1,8 +1,26 @@
package ru.windcorp.jputil.functions;
@FunctionalInterface
public interface FloatSupplier {
float getAsFloat();
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.functions;
@FunctionalInterface
public interface FloatSupplier {
float getAsFloat();
}

View File

@ -1,72 +1,76 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.functions;
import java.util.function.BiConsumer;
@FunctionalInterface
public interface ThrowingBiConsumer<T, U, E extends Exception> {
@FunctionalInterface
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;
@SuppressWarnings("unchecked")
default BiConsumer<T, U> withHandler(BiConsumerHandler<? super T, ? super U, ? super E> handler) {
return (t, u) -> {
try {
accept(t, u);
} catch (RuntimeException e) {
throw 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,
ThrowingBiConsumer<? super T, ? super U, ? extends E> second) {
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) {
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) -> {
first.accept(t, u);
second.accept(t, u);
};
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.functions;
import java.util.function.BiConsumer;
@FunctionalInterface
public interface ThrowingBiConsumer<T, U, E extends Exception> {
@FunctionalInterface
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;
@SuppressWarnings("unchecked")
default BiConsumer<T, U> withHandler(BiConsumerHandler<? super T, ? super U, ? super E> handler) {
return (t, u) -> {
try {
accept(t, u);
} catch (RuntimeException e) {
throw 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,
ThrowingBiConsumer<? super T, ? super U, ? extends E> second
) {
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
) {
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) -> {
first.accept(t, u);
second.accept(t, u);
};
}
}

View File

@ -1,62 +1,72 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.functions;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@FunctionalInterface
public interface ThrowingConsumer<T, E extends Exception> {
void accept(T t) throws E;
@SuppressWarnings("unchecked")
default Consumer<T> withHandler(BiConsumer<? super T, ? super E> handler) {
return t -> {
try {
accept(t);
} catch (RuntimeException e) {
throw 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 -> {
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) {
return t -> {
first.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);
};
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.functions;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
@FunctionalInterface
public interface ThrowingConsumer<T, E extends Exception> {
void accept(T t) throws E;
@SuppressWarnings("unchecked")
default Consumer<T> withHandler(BiConsumer<? super T, ? super E> handler) {
return t -> {
try {
accept(t);
} catch (RuntimeException e) {
throw 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 -> {
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
) {
return t -> {
first.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
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.functions;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
@FunctionalInterface
public interface ThrowingFunction<T, R, E extends Exception> {
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) {
return t -> {
try {
return apply(t);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
if (handler != null) handler.accept(t, (E) e);
return value == null ? null : value.apply(t);
}
};
}
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, R value) {
return withHandler(handler, t -> value);
}
default Function<T, R> withHandler(BiConsumer<? super T, ? super E> handler) {
return withHandler(handler, (Function<T, R>) null);
}
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
ThrowingFunction<? super T, I, ? extends E> first,
ThrowingFunction<? super I, ? extends R, ? extends E> second) {
return t -> second.apply(first.apply(t));
}
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
Function<? super T, I> first,
ThrowingFunction<? super I, ? extends R, E> second) {
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));
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.functions;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Supplier;
@FunctionalInterface
public interface ThrowingFunction<T, R, E extends Exception> {
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
) {
return t -> {
try {
return apply(t);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
if (handler != null)
handler.accept(t, (E) e);
return value == null ? null : value.apply(t);
}
};
}
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, R value) {
return withHandler(handler, t -> value);
}
default Function<T, R> withHandler(BiConsumer<? super T, ? super E> handler) {
return withHandler(handler, (Function<T, R>) null);
}
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
ThrowingFunction<? super T, I, ? extends E> first,
ThrowingFunction<? super I, ? extends R, ? extends E> second
) {
return t -> second.apply(first.apply(t));
}
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
Function<? super T, I> first,
ThrowingFunction<? super I, ? extends R, E> second
) {
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
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.functions;
import java.util.function.Consumer;
@FunctionalInterface
public interface ThrowingRunnable<E extends Exception> {
void run() throws E;
@SuppressWarnings("unchecked")
default Runnable withHandler(Consumer<? super E> handler) {
return () -> {
try {
run();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
handler.accept((E) e);
}
};
}
public static <E extends Exception> ThrowingRunnable<E> concat(
ThrowingRunnable<? extends E> first,
ThrowingRunnable<? extends E> second
) {
return () -> {
first.run();
second.run();
};
}
public static <E extends Exception> ThrowingRunnable<E> concat(Runnable first, ThrowingRunnable<E> second) {
return () -> {
first.run();
second.run();
};
}
public static <E extends Exception> ThrowingRunnable<E> concat(ThrowingRunnable<E> first, Runnable second) {
return () -> {
first.run();
second.run();
};
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.functions;
import java.util.function.Consumer;
@FunctionalInterface
public interface ThrowingRunnable<E extends Exception> {
void run() throws E;
@SuppressWarnings("unchecked")
default Runnable withHandler(Consumer<? super E> handler) {
return () -> {
try {
run();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
handler.accept((E) e);
}
};
}
public static <E extends Exception> ThrowingRunnable<E> concat(
ThrowingRunnable<? extends E> first,
ThrowingRunnable<? extends E> second
) {
return () -> {
first.run();
second.run();
};
}
public static <E extends Exception> ThrowingRunnable<E> concat(Runnable first, ThrowingRunnable<E> second) {
return () -> {
first.run();
second.run();
};
}
public static <E extends Exception> ThrowingRunnable<E> concat(ThrowingRunnable<E> first, Runnable second) {
return () -> {
first.run();
second.run();
};
}
}

View File

@ -1,50 +1,52 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.functions;
import java.util.function.Consumer;
import java.util.function.Supplier;
@FunctionalInterface
public interface ThrowingSupplier<T, E extends Exception> {
T get() throws E;
@SuppressWarnings("unchecked")
default Supplier<T> withHandler(Consumer<? super E> handler, Supplier<? extends T> value) {
return () -> {
try {
return get();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
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) {
return withHandler(handler, (Supplier<T>) null);
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.functions;
import java.util.function.Consumer;
import java.util.function.Supplier;
@FunctionalInterface
public interface ThrowingSupplier<T, E extends Exception> {
T get() throws E;
@SuppressWarnings("unchecked")
default Supplier<T> withHandler(Consumer<? super E> handler, Supplier<? extends T> value) {
return () -> {
try {
return get();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
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) {
return withHandler(handler, (Supplier<T>) null);
}
}

View File

@ -1,47 +1,48 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.iterators;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class ArrayIterator<E> implements Iterator<E> {
private final E[] array;
private int next;
@SafeVarargs
public ArrayIterator(E... array) {
this.array = array;
}
@Override
public boolean hasNext() {
return next < array.length;
}
@Override
public E next() {
try {
return array[next++];
} catch (ArrayIndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.iterators;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class ArrayIterator<E> implements Iterator<E> {
private final E[] array;
private int next;
@SafeVarargs
public ArrayIterator(E... array) {
this.array = array;
}
@Override
public boolean hasNext() {
return next < array.length;
}
@Override
public E next() {
try {
return array[next++];
} catch (ArrayIndexOutOfBoundsException e) {
throw new NoSuchElementException();
}
}
}

View File

@ -1,61 +1,61 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.iterators;
import java.util.Iterator;
import java.util.function.Function;
/**
* @author Javapony
*
*/
public class FunctionIterator<T, E> implements Iterator<E> {
private final Iterator<T> parent;
private final Function<T, E> function;
public FunctionIterator(Iterator<T> parent, Function<T, E> function) {
this.parent = parent;
this.function = function;
}
/**
* @see java.util.Iterator#hasNext()
*/
@Override
public boolean hasNext() {
return parent.hasNext();
}
/**
* @see java.util.Iterator#next()
*/
@Override
public E next() {
return function.apply(parent.next());
}
/**
* @see java.util.Iterator#remove()
*/
@Override
public void remove() {
parent.remove();
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.iterators;
import java.util.Iterator;
import java.util.function.Function;
/**
* @author Javapony
*/
public class FunctionIterator<T, E> implements Iterator<E> {
private final Iterator<T> parent;
private final Function<T, E> function;
public FunctionIterator(Iterator<T> parent, Function<T, E> function) {
this.parent = parent;
this.function = function;
}
/**
* @see java.util.Iterator#hasNext()
*/
@Override
public boolean hasNext() {
return parent.hasNext();
}
/**
* @see java.util.Iterator#next()
*/
@Override
public E next() {
return function.apply(parent.next());
}
/**
* @see java.util.Iterator#remove()
*/
@Override
public void remove() {
parent.remove();
}
}

View File

@ -1,60 +1,62 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.iterators;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class PeekingIterator<E> implements Iterator<E> {
private final Iterator<? extends E> source;
private E next = null;
public PeekingIterator(Iterator<? extends E> source) {
this.source = source;
}
@Override
public boolean hasNext() {
return next != null || source.hasNext();
}
public E peek() {
if (next == null) {
if (source.hasNext()) {
next = source.next();
} else {
throw new NoSuchElementException();
}
}
return next;
}
// SonarLint: "Iterator.next()" methods should throw "NoSuchElementException" (java:S2272)
// peek() throws NoSuchElementException as expected
@SuppressWarnings("squid:S2272")
@Override
public E next() {
E element = peek();
next = null;
return element;
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.iterators;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class PeekingIterator<E> implements Iterator<E> {
private final Iterator<? extends E> source;
private E next = null;
public PeekingIterator(Iterator<? extends E> source) {
this.source = source;
}
@Override
public boolean hasNext() {
return next != null || source.hasNext();
}
public E peek() {
if (next == null) {
if (source.hasNext()) {
next = source.next();
} else {
throw new NoSuchElementException();
}
}
return next;
}
// SonarLint: "Iterator.next()" methods should throw
// "NoSuchElementException" (java:S2272)
// peek() throws NoSuchElementException as expected
@SuppressWarnings("squid:S2272")
@Override
public E next() {
E element = peek();
next = null;
return element;
}
}

View File

@ -1,67 +1,70 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.iterators;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class RangeIterator<E> implements Iterator<E> {
private final Iterator<E> parent;
private final int from;
private final int amount;
private int nextIndex = 0;
public RangeIterator(Iterator<E> iterator, int from, int amount) {
this.parent = iterator;
this.from = from;
this.amount = amount < 0 ? Integer.MAX_VALUE : amount;
}
public RangeIterator(Iterator<E> iterator, int from) {
this(iterator, from, -1);
}
@Override
public boolean hasNext() {
update();
return nextIndex < from + amount && parent.hasNext();
}
@Override
public E next() {
update();
if (nextIndex >= from + amount) {
throw new NoSuchElementException("RangeIterator about to retrieve element " + nextIndex
+ " which exceeds upper boundary " + (from + amount));
}
E result = parent.next();
nextIndex++;
return result;
}
protected void update() {
while (nextIndex < from && parent.hasNext()) {
parent.next();
nextIndex++;
}
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.iterators;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class RangeIterator<E> implements Iterator<E> {
private final Iterator<E> parent;
private final int from;
private final int amount;
private int nextIndex = 0;
public RangeIterator(Iterator<E> iterator, int from, int amount) {
this.parent = iterator;
this.from = from;
this.amount = amount < 0 ? Integer.MAX_VALUE : amount;
}
public RangeIterator(Iterator<E> iterator, int from) {
this(iterator, from, -1);
}
@Override
public boolean hasNext() {
update();
return nextIndex < from + amount && parent.hasNext();
}
@Override
public E next() {
update();
if (nextIndex >= from + amount) {
throw new NoSuchElementException(
"RangeIterator about to retrieve element " + nextIndex
+ " which exceeds upper boundary " + (from + amount)
);
}
E result = parent.next();
nextIndex++;
return result;
}
protected void update() {
while (nextIndex < from && parent.hasNext()) {
parent.next();
nextIndex++;
}
}
}

View File

@ -1,70 +1,72 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.iterators;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Reiterator<E> implements Iterable<E> {
private class ReiteratorIterator implements Iterator<E> {
int index = 0;
@Override
public boolean hasNext() {
synchronized (source) {
if (index >= data.size()) {
if (!source.hasNext()) {
return false;
} else {
data.add(source.next());
}
}
return true;
}
}
@Override
public E next() {
E result;
synchronized (source) {
if (!hasNext()) throw new NoSuchElementException();
result = data.get(index);
}
index++;
return result;
}
}
private final Iterator<E> source;
private final ArrayList<E> data = new ArrayList<>();
public Reiterator(Iterator<E> source) {
this.source = source;
}
@Override
public Iterator<E> iterator() {
return new ReiteratorIterator();
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.iterators;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.NoSuchElementException;
public class Reiterator<E> implements Iterable<E> {
private class ReiteratorIterator implements Iterator<E> {
int index = 0;
@Override
public boolean hasNext() {
synchronized (source) {
if (index >= data.size()) {
if (!source.hasNext()) {
return false;
} else {
data.add(source.next());
}
}
return true;
}
}
@Override
public E next() {
E result;
synchronized (source) {
if (!hasNext())
throw new NoSuchElementException();
result = data.get(index);
}
index++;
return result;
}
}
private final Iterator<E> source;
private final ArrayList<E> data = new ArrayList<>();
public Reiterator(Iterator<E> source) {
this.source = source;
}
@Override
public Iterator<E> iterator() {
return new ReiteratorIterator();
}
}

View File

@ -1,39 +1,40 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.selectors;
public abstract class AbstractSelectorOperator implements SelectorOperator {
private final String[] names;
public AbstractSelectorOperator(String[] names) {
this.names = names;
}
@Override
public boolean matchesName(String name) {
for (String n : names) {
if (n.equals(name)) {
return true;
}
}
return false;
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.selectors;
public abstract class AbstractSelectorOperator implements SelectorOperator {
private final String[] names;
public AbstractSelectorOperator(String[] names) {
this.names = names;
}
@Override
public boolean matchesName(String name) {
for (String n : names) {
if (n.equals(name)) {
return true;
}
}
return false;
}
}

View File

@ -1,57 +1,58 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.selectors;
import ru.windcorp.jputil.SyntaxException;
import ru.windcorp.jputil.chars.StringUtil;
public abstract class NamedParameterizedSelector<T> extends NamedSelector<T> {
private final char separator;
private String givenName;
public NamedParameterizedSelector(char separator, String... names) {
super(names);
this.separator = separator;
}
@Override
public Selector<T> derive(String name) throws SyntaxException {
String[] parts = StringUtil.split(name, separator, 2);
if (parts[1] == null) {
return null;
}
if (!matchesName(parts[0])) {
return null;
}
NamedParameterizedSelector<T> selector = deriveImpl(parts[1]);
selector.givenName = name;
return selector;
}
protected abstract NamedParameterizedSelector<T> deriveImpl(String param) throws SyntaxException;
@Override
public String toString() {
return givenName;
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.selectors;
import ru.windcorp.jputil.SyntaxException;
import ru.windcorp.jputil.chars.StringUtil;
public abstract class NamedParameterizedSelector<T> extends NamedSelector<T> {
private final char separator;
private String givenName;
public NamedParameterizedSelector(char separator, String... names) {
super(names);
this.separator = separator;
}
@Override
public Selector<T> derive(String name) throws SyntaxException {
String[] parts = StringUtil.split(name, separator, 2);
if (parts[1] == null) {
return null;
}
if (!matchesName(parts[0])) {
return null;
}
NamedParameterizedSelector<T> selector = deriveImpl(parts[1]);
selector.givenName = name;
return selector;
}
protected abstract NamedParameterizedSelector<T> deriveImpl(String param) throws SyntaxException;
@Override
public String toString() {
return givenName;
}
}

View File

@ -1,50 +1,51 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.selectors;
import ru.windcorp.jputil.SyntaxException;
public abstract class NamedSelector<T> implements Selector<T> {
private final String[] names;
public NamedSelector(String... names) {
this.names = names;
}
public boolean matchesName(String name) {
for (String n : names) {
if (n.equalsIgnoreCase(name)) {
return true;
}
}
return false;
}
@Override
public Selector<T> derive(String name) throws SyntaxException {
return matchesName(name) ? this : null;
}
@Override
public String toString() {
return names[0];
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.selectors;
import ru.windcorp.jputil.SyntaxException;
public abstract class NamedSelector<T> implements Selector<T> {
private final String[] names;
public NamedSelector(String... names) {
this.names = names;
}
public boolean matchesName(String name) {
for (String n : names) {
if (n.equalsIgnoreCase(name)) {
return true;
}
}
return false;
}
@Override
public Selector<T> derive(String name) throws SyntaxException {
return matchesName(name) ? this : null;
}
@Override
public String toString() {
return names[0];
}
}

View File

@ -1,36 +1,37 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate;
public class OperatorAnd extends AbstractSelectorOperator {
public OperatorAnd(String... names) {
super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) {
Predicate<T> arg2 = stack.pop();
Predicate<T> arg1 = stack.pop();
stack.push(obj -> arg1.test(obj) && arg2.test(obj));
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate;
public class OperatorAnd extends AbstractSelectorOperator {
public OperatorAnd(String... names) {
super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) {
Predicate<T> arg2 = stack.pop();
Predicate<T> arg1 = stack.pop();
stack.push(obj -> arg1.test(obj) && arg2.test(obj));
}
}

View File

@ -1,36 +1,37 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate;
public class OperatorExclude extends AbstractSelectorOperator {
public OperatorExclude(String... names) {
super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) {
Predicate<T> arg2 = stack.pop();
Predicate<T> arg1 = stack.pop();
stack.push(obj -> arg1.test(obj) && !arg2.test(obj));
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate;
public class OperatorExclude extends AbstractSelectorOperator {
public OperatorExclude(String... names) {
super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) {
Predicate<T> arg2 = stack.pop();
Predicate<T> arg1 = stack.pop();
stack.push(obj -> arg1.test(obj) && !arg2.test(obj));
}
}

View File

@ -1,34 +1,35 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate;
public class OperatorNot extends AbstractSelectorOperator {
public OperatorNot(String... names) {
super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) {
stack.push(stack.pop().negate());
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate;
public class OperatorNot extends AbstractSelectorOperator {
public OperatorNot(String... names) {
super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) {
stack.push(stack.pop().negate());
}
}

View File

@ -1,36 +1,37 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate;
public class OperatorOr extends AbstractSelectorOperator {
public OperatorOr(String... names) {
super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) {
Predicate<T> arg2 = stack.pop();
Predicate<T> arg1 = stack.pop();
stack.push(obj -> arg1.test(obj) || arg2.test(obj));
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate;
public class OperatorOr extends AbstractSelectorOperator {
public OperatorOr(String... names) {
super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) {
Predicate<T> arg2 = stack.pop();
Predicate<T> arg1 = stack.pop();
stack.push(obj -> arg1.test(obj) || arg2.test(obj));
}
}

View File

@ -1,36 +1,37 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate;
public class OperatorXor extends AbstractSelectorOperator {
public OperatorXor(String... names) {
super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) {
Predicate<T> arg2 = stack.pop();
Predicate<T> arg1 = stack.pop();
stack.push(obj -> arg1.test(obj) != arg2.test(obj));
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate;
public class OperatorXor extends AbstractSelectorOperator {
public OperatorXor(String... names) {
super(names);
}
@Override
public <T> void process(Deque<Predicate<T>> stack) {
Predicate<T> arg2 = stack.pop();
Predicate<T> arg1 = stack.pop();
stack.push(obj -> arg1.test(obj) != arg2.test(obj));
}
}

View File

@ -1,36 +1,37 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.selectors;
import java.util.function.Predicate;
public class PredicateWrapper<T> extends NamedSelector<T> {
private final Predicate<? super T> predicate;
public PredicateWrapper(String name, Predicate<? super T> predicate) {
super(name);
this.predicate = predicate;
}
@Override
public boolean test(T obj) {
return predicate.test(obj);
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.selectors;
import java.util.function.Predicate;
public class PredicateWrapper<T> extends NamedSelector<T> {
private final Predicate<? super T> predicate;
public PredicateWrapper(String name, Predicate<? super T> predicate) {
super(name);
this.predicate = predicate;
}
@Override
public boolean test(T obj) {
return predicate.test(obj);
}
}

View File

@ -1,28 +1,29 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.selectors;
import java.util.function.Predicate;
import ru.windcorp.jputil.SyntaxException;
public interface Selector<T> extends Predicate<T> {
public Selector<T> derive(String name) throws SyntaxException;
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.selectors;
import java.util.function.Predicate;
import ru.windcorp.jputil.SyntaxException;
public interface Selector<T> extends Predicate<T> {
public Selector<T> derive(String name) throws SyntaxException;
}

View File

@ -1,29 +1,30 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate;
public interface SelectorOperator {
public <T> void process(Deque<Predicate<T>> stack);
public boolean matchesName(String name);
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.selectors;
import java.util.Deque;
import java.util.function.Predicate;
public interface SelectorOperator {
public <T> void process(Deque<Predicate<T>> stack);
public boolean matchesName(String name);
}

View File

@ -1,176 +1,175 @@
/*******************************************************************************
* JPUtil
* Copyright (C) 2019 Javapony/OLEGSHA
*
* 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.jputil.selectors;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.function.Predicate;
import ru.windcorp.jputil.SyntaxException;
import ru.windcorp.jputil.iterators.PeekingIterator;
public class SelectorSystem<T> {
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<SelectorOperator> operators =
Collections.synchronizedCollection(new ArrayList<SelectorOperator>());
private String stackPrefix = null;
public Collection<Selector<T>> getSelectors() {
return this.selectors;
}
public Collection<SelectorOperator> getSelectorOperators() {
return this.operators;
}
public String getStackPrefix() {
return stackPrefix;
}
public SelectorSystem<T> setStackPrefix(String stackPrefix) {
this.stackPrefix = stackPrefix;
return this;
}
public SelectorSystem<T> add(Selector<T> selector) {
getSelectors().add(selector);
return this;
}
public SelectorSystem<T> add(SelectorOperator operator) {
getSelectorOperators().add(operator);
return this;
}
public Predicate<T> parse(Iterator<String> tokens) throws SyntaxException {
PeekingIterator<String> peeker = new PeekingIterator<>(tokens);
if (getStackPrefix() != null && peeker.hasNext() && getStackPrefix().equals(peeker.peek())) {
peeker.next();
return parseStack(peeker);
}
Deque<Predicate<T>> stack = new LinkedList<>();
synchronized (getSelectorOperators()) {
synchronized (getSelectors()) {
while (peeker.hasNext()) {
parseToken(stack, peeker);
}
}
}
return compress(stack);
}
private void parseToken(Deque<Predicate<T>> stack, Iterator<String> tokens) throws SyntaxException {
if (!tokens.hasNext()) {
throw new SyntaxException("Not enough tokens");
}
String token = tokens.next();
for (SelectorOperator operator : getSelectorOperators()) {
if (operator.matchesName(token.toLowerCase())) {
parseToken(stack, tokens);
operator.process(stack);
return;
}
}
Selector<T> tmp;
for (Selector<T> selector : getSelectors()) {
if ((tmp = selector.derive(token)) != null) {
stack.push(tmp);
return;
}
}
throw new SyntaxException("Unknown token \"" + token + "\"");
}
public Predicate<T> parseStack(Iterator<String> tokens) throws SyntaxException {
Deque<Predicate<T>> stack = new LinkedList<>();
String token;
synchronized (getSelectorOperators()) {
synchronized (getSelectors()) {
tokenCycle:
while (tokens.hasNext()) {
token = tokens.next();
for (SelectorOperator operator : getSelectorOperators()) {
if (operator.matchesName(token.toLowerCase())) {
operator.process(stack);
continue tokenCycle;
}
}
for (Selector<T> selector : getSelectors()) {
Selector<T> tmp;
if ((tmp = selector.derive(token)) != null) {
stack.push(tmp);
continue tokenCycle;
}
}
throw new SyntaxException("Unknown token \"" + token + "\"");
}
}
}
return compress(stack);
}
private Predicate<T> compress(Deque<Predicate<T>> stack) throws SyntaxException {
if (stack.isEmpty()) {
throw new SyntaxException("Stack is empty");
}
if (stack.size() == 1) {
return stack.pop();
}
return obj -> {
for (Predicate<? super T> predicate : stack) {
if (predicate.test(obj)) {
return true;
}
}
return false;
};
}
}
/*
* JPUtil
* Copyright (C) 2019-2021 OLEGSHA/Javapony 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.jputil.selectors;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Deque;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.function.Predicate;
import ru.windcorp.jputil.SyntaxException;
import ru.windcorp.jputil.iterators.PeekingIterator;
public class SelectorSystem<T> {
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<SelectorOperator> operators = Collections
.synchronizedCollection(new ArrayList<SelectorOperator>());
private String stackPrefix = null;
public Collection<Selector<T>> getSelectors() {
return this.selectors;
}
public Collection<SelectorOperator> getSelectorOperators() {
return this.operators;
}
public String getStackPrefix() {
return stackPrefix;
}
public SelectorSystem<T> setStackPrefix(String stackPrefix) {
this.stackPrefix = stackPrefix;
return this;
}
public SelectorSystem<T> add(Selector<T> selector) {
getSelectors().add(selector);
return this;
}
public SelectorSystem<T> add(SelectorOperator operator) {
getSelectorOperators().add(operator);
return this;
}
public Predicate<T> parse(Iterator<String> tokens) throws SyntaxException {
PeekingIterator<String> peeker = new PeekingIterator<>(tokens);
if (getStackPrefix() != null && peeker.hasNext() && getStackPrefix().equals(peeker.peek())) {
peeker.next();
return parseStack(peeker);
}
Deque<Predicate<T>> stack = new LinkedList<>();
synchronized (getSelectorOperators()) {
synchronized (getSelectors()) {
while (peeker.hasNext()) {
parseToken(stack, peeker);
}
}
}
return compress(stack);
}
private void parseToken(Deque<Predicate<T>> stack, Iterator<String> tokens) throws SyntaxException {
if (!tokens.hasNext()) {
throw new SyntaxException("Not enough tokens");
}
String token = tokens.next();
for (SelectorOperator operator : getSelectorOperators()) {
if (operator.matchesName(token.toLowerCase())) {
parseToken(stack, tokens);
operator.process(stack);
return;
}
}
Selector<T> tmp;
for (Selector<T> selector : getSelectors()) {
if ((tmp = selector.derive(token)) != null) {
stack.push(tmp);
return;
}
}
throw new SyntaxException("Unknown token \"" + token + "\"");
}
public Predicate<T> parseStack(Iterator<String> tokens) throws SyntaxException {
Deque<Predicate<T>> stack = new LinkedList<>();
String token;
synchronized (getSelectorOperators()) {
synchronized (getSelectors()) {
tokenCycle: while (tokens.hasNext()) {
token = tokens.next();
for (SelectorOperator operator : getSelectorOperators()) {
if (operator.matchesName(token.toLowerCase())) {
operator.process(stack);
continue tokenCycle;
}
}
for (Selector<T> selector : getSelectors()) {
Selector<T> tmp;
if ((tmp = selector.derive(token)) != null) {
stack.push(tmp);
continue tokenCycle;
}
}
throw new SyntaxException("Unknown token \"" + token + "\"");
}
}
}
return compress(stack);
}
private Predicate<T> compress(Deque<Predicate<T>> stack) throws SyntaxException {
if (stack.isEmpty()) {
throw new SyntaxException("Stack is empty");
}
if (stack.size() == 1) {
return stack.pop();
}
return obj -> {
for (Predicate<? super T> predicate : stack) {
if (predicate.test(obj)) {
return true;
}
}
return false;
};
}
}

View File

@ -1,22 +1,23 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
public class Progressia {
}
/*
* 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;
public class Progressia {
}

View File

@ -1,50 +1,51 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.common.util.crash.analyzers.OutOfMemoryAnalyzer;
import ru.windcorp.progressia.common.util.crash.providers.*;
public class ProgressiaLauncher {
public static String[] arguments;
public static void launch(String[] args, Proxy proxy) {
arguments = args.clone();
setupCrashReports();
proxy.initialize();
}
private static void setupCrashReports() {
// Context providers
CrashReports.registerProvider(new OSContextProvider());
CrashReports.registerProvider(new RAMContextProvider());
CrashReports.registerProvider(new JavaVersionContextProvider());
CrashReports.registerProvider(new OpenALContextProvider());
CrashReports.registerProvider(new ArgsContextProvider());
CrashReports.registerProvider(new LanguageContextProvider());
// Analyzers
CrashReports.registerAnalyzer(new OutOfMemoryAnalyzer());
Thread.setDefaultUncaughtExceptionHandler((Thread thread, Throwable t)-> {
CrashReports.crash(t, "Uncaught exception in thread %s", thread.getName());
});
}
}
/*
* 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;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.common.util.crash.analyzers.OutOfMemoryAnalyzer;
import ru.windcorp.progressia.common.util.crash.providers.*;
public class ProgressiaLauncher {
public static String[] arguments;
public static void launch(String[] args, Proxy proxy) {
arguments = args.clone();
setupCrashReports();
proxy.initialize();
}
private static void setupCrashReports() {
// Context providers
CrashReports.registerProvider(new OSContextProvider());
CrashReports.registerProvider(new RAMContextProvider());
CrashReports.registerProvider(new JavaVersionContextProvider());
CrashReports.registerProvider(new OpenALContextProvider());
CrashReports.registerProvider(new ArgsContextProvider());
CrashReports.registerProvider(new LanguageContextProvider());
// Analyzers
CrashReports.registerAnalyzer(new OutOfMemoryAnalyzer());
Thread.setDefaultUncaughtExceptionHandler((Thread thread, Throwable t) -> {
CrashReports.crash(t, "Uncaught exception in thread %s", thread.getName());
});
}
}

View File

@ -1,24 +1,25 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
public interface Proxy {
void initialize();
}
/*
* 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;
public interface Proxy {
void initialize();
}

View File

@ -1,59 +1,79 @@
package ru.windcorp.progressia.client;
import ru.windcorp.progressia.client.comms.DefaultClientCommsListener;
import ru.windcorp.progressia.client.comms.ServerCommsChannel;
import ru.windcorp.progressia.client.graphics.world.Camera;
import ru.windcorp.progressia.client.graphics.world.EntityAnchor;
import ru.windcorp.progressia.client.graphics.world.LocalPlayer;
import ru.windcorp.progressia.client.world.WorldRender;
import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.common.world.entity.EntityData;
public class Client {
private final WorldRender world;
private final LocalPlayer localPlayer = new LocalPlayer(this);
private final Camera camera = new Camera((float) Math.toRadians(70));
private final ServerCommsChannel comms;
public Client(WorldData world, ServerCommsChannel comms) {
this.world = new WorldRender(world, this);
this.comms = comms;
comms.addListener(new DefaultClientCommsListener(this));
}
public WorldRender getWorld() {
return world;
}
public LocalPlayer getLocalPlayer() {
return localPlayer;
}
public boolean isReady() {
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)
));
}
}
/*
* 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;
import ru.windcorp.progressia.client.comms.DefaultClientCommsListener;
import ru.windcorp.progressia.client.comms.ServerCommsChannel;
import ru.windcorp.progressia.client.graphics.world.Camera;
import ru.windcorp.progressia.client.graphics.world.EntityAnchor;
import ru.windcorp.progressia.client.graphics.world.LocalPlayer;
import ru.windcorp.progressia.client.world.WorldRender;
import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.common.world.entity.EntityData;
public class Client {
private final WorldRender world;
private final LocalPlayer localPlayer = new LocalPlayer(this);
private final Camera camera = new Camera((float) Math.toRadians(70));
private final ServerCommsChannel comms;
public Client(WorldData world, ServerCommsChannel comms) {
this.world = new WorldRender(world, this);
this.comms = comms;
comms.addListener(new DefaultClientCommsListener(this));
}
public WorldRender getWorld() {
return world;
}
public LocalPlayer getLocalPlayer() {
return localPlayer;
}
public boolean isReady() {
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
* Copyright (C) 2020 Wind Corporation
*
* 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;
import ru.windcorp.progressia.Proxy;
import ru.windcorp.progressia.client.audio.AudioSystem;
import ru.windcorp.progressia.client.graphics.backend.GraphicsBackend;
import ru.windcorp.progressia.client.graphics.backend.RenderTaskQueue;
import ru.windcorp.progressia.client.graphics.flat.FlatRenderProgram;
import ru.windcorp.progressia.client.graphics.font.GNUUnifontLoader;
import ru.windcorp.progressia.client.graphics.font.Typefaces;
import ru.windcorp.progressia.client.graphics.texture.Atlases;
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
import ru.windcorp.progressia.client.localization.Localizer;
import ru.windcorp.progressia.common.resource.ResourceManager;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.server.ServerState;
import ru.windcorp.progressia.test.TestContent;
public class ClientProxy implements Proxy {
@Override
public void initialize() {
GraphicsBackend.initialize();
try {
RenderTaskQueue.waitAndInvoke(FlatRenderProgram::init);
RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init);
RenderTaskQueue.waitAndInvoke(() -> Typefaces.setDefault(GNUUnifontLoader.load(ResourceManager.getResource("assets/unifont-13.0.03.hex.gz"))));
} catch (InterruptedException e) {
throw CrashReports.report(e, "ClientProxy failed");
}
Localizer.getInstance().setLanguage("en-US");
TestContent.registerContent();
Atlases.loadAllAtlases();
AudioSystem.initialize();
ServerState.startServer();
ClientState.connectToLocalServer();
}
}
/*
* 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;
import ru.windcorp.progressia.Proxy;
import ru.windcorp.progressia.client.audio.AudioSystem;
import ru.windcorp.progressia.client.graphics.backend.GraphicsBackend;
import ru.windcorp.progressia.client.graphics.backend.RenderTaskQueue;
import ru.windcorp.progressia.client.graphics.flat.FlatRenderProgram;
import ru.windcorp.progressia.client.graphics.font.GNUUnifontLoader;
import ru.windcorp.progressia.client.graphics.font.Typefaces;
import ru.windcorp.progressia.client.graphics.texture.Atlases;
import ru.windcorp.progressia.client.graphics.world.WorldRenderProgram;
import ru.windcorp.progressia.client.localization.Localizer;
import ru.windcorp.progressia.common.resource.ResourceManager;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.server.ServerState;
import ru.windcorp.progressia.test.TestContent;
public class ClientProxy implements Proxy {
@Override
public void initialize() {
GraphicsBackend.initialize();
try {
RenderTaskQueue.waitAndInvoke(FlatRenderProgram::init);
RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init);
RenderTaskQueue.waitAndInvoke(
() -> Typefaces
.setDefault(GNUUnifontLoader.load(ResourceManager.getResource("assets/unifont-13.0.03.hex.gz")))
);
} catch (InterruptedException e) {
throw CrashReports.report(e, "ClientProxy failed");
}
Localizer.getInstance().setLanguage("en-US");
TestContent.registerContent();
Atlases.loadAllAtlases();
AudioSystem.initialize();
ServerState.startServer();
ClientState.connectToLocalServer();
}
}

View File

@ -1,46 +1,65 @@
package ru.windcorp.progressia.client;
import ru.windcorp.progressia.client.comms.localhost.LocalServerCommsChannel;
import ru.windcorp.progressia.client.graphics.GUI;
import ru.windcorp.progressia.client.graphics.world.LayerWorld;
import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.server.ServerState;
import ru.windcorp.progressia.test.LayerAbout;
import ru.windcorp.progressia.test.LayerTestUI;
import ru.windcorp.progressia.test.TestContent;
public class ClientState {
private static Client instance;
public static Client getInstance() {
return instance;
}
public static void setInstance(Client instance) {
ClientState.instance = instance;
}
public static void connectToLocalServer() {
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() {}
}
/*
* 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;
import ru.windcorp.progressia.client.comms.localhost.LocalServerCommsChannel;
import ru.windcorp.progressia.client.graphics.GUI;
import ru.windcorp.progressia.client.graphics.world.LayerWorld;
import ru.windcorp.progressia.common.world.WorldData;
import ru.windcorp.progressia.server.ServerState;
import ru.windcorp.progressia.test.LayerAbout;
import ru.windcorp.progressia.test.LayerTestUI;
import ru.windcorp.progressia.test.TestContent;
public class ClientState {
private static Client instance;
public static Client getInstance() {
return instance;
}
public static void setInstance(Client instance) {
ClientState.instance = instance;
}
public static void connectToLocalServer() {
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
* Copyright (C) 2020 Wind Corporation
*
* 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;
import ru.windcorp.progressia.ProgressiaLauncher;
public class ProgressiaClientMain {
public static void main(String[] args) {
ProgressiaLauncher.launch(args, new ClientProxy());
}
}
/*
* 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;
import ru.windcorp.progressia.ProgressiaLauncher;
public class ProgressiaClientMain {
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;
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;
import org.lwjgl.openal.*;
@ -26,8 +44,8 @@ public class AudioManager {
public static void initAL() {
String defaultDeviceName = alcGetString(
0,
ALC_DEFAULT_DEVICE_SPECIFIER
0,
ALC_DEFAULT_DEVICE_SPECIFIER
);
device = alcOpenDevice(defaultDeviceName);
@ -57,27 +75,30 @@ public class AudioManager {
lastSoundIndex = 0;
}
speaker = soundSpeakers.get(lastSoundIndex);
} while (speaker.getState()
.equals(Speaker.State.PLAYING_LOOP));
} while (
speaker.getState()
.equals(Speaker.State.PLAYING_LOOP)
);
return speaker;
}
private static SoundType findSoundType(String soundID) throws Exception {
private static SoundType findSoundType(String soundID) throws Exception {
for (SoundType s : soundsBuffer) {
if (s.getId().equals(soundID)) {
return s;
}
}
throw new Exception("ERROR: The selected sound is not loaded or" +
" not exists");
throw new Exception(
"ERROR: The selected sound is not loaded or" +
" not exists"
);
}
public static Speaker initSpeaker(String soundID) {
Speaker speaker = getLastSpeaker();
try {
findSoundType(soundID).initSpeaker(speaker);
} catch (Exception ex)
{
} catch (Exception ex) {
throw new RuntimeException();
}
return speaker;
@ -86,8 +107,7 @@ public class AudioManager {
public static Speaker initMusicSpeaker(String soundID) {
try {
findSoundType(soundID).initSpeaker(musicSpeaker);
} catch (Exception ex)
{
} catch (Exception ex) {
throw new RuntimeException();
}
return musicSpeaker;
@ -103,8 +123,7 @@ public class AudioManager {
public static void loadSound(String path, String id, AudioFormat format) {
if (format == AudioFormat.MONO) {
soundsBuffer.add(AudioReader.readAsMono(path, id));
} else
{
} else {
soundsBuffer.add(AudioReader.readAsStereo(path, id));
}
}
@ -128,8 +147,7 @@ public class AudioManager {
return deviceCapabilities;
}
public static void createBuffers()
{
public static void createBuffers() {
for (int i = 0; i < SOUNDS_NUM; ++i) {
soundSpeakers.add(new Speaker());
}
@ -141,4 +159,4 @@ public class AudioManager {
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;
public class AudioSystem {
@ -9,8 +27,10 @@ public class AudioSystem {
}
static void loadAudioData() {
AudioManager.loadSound("assets/sounds/block_destroy_clap.ogg",
"Progressia:BlockDestroy",
AudioFormat.MONO);
AudioManager.loadSound(
"assets/sounds/block_destroy_clap.ogg",
"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;
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;
public class Music extends Namespaced {
private Vec3 position = new Vec3();
private Vec3 velocity = new Vec3();
private float pitch = 1.0f;
private float gain = 1.0f;
private Vec3 position = new Vec3();
private Vec3 velocity = new Vec3();
private float pitch = 1.0f;
private float gain = 1.0f;
public Music(String id) {
super(id);
}
public Music(String id)
{
super(id);
}
public Music(
String 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,
Vec3 position,
Vec3 velocity,
float pitch,
float gain)
{
this(id);
this.position = position;
this.velocity = velocity;
this.pitch = pitch;
this.gain = gain;
}
public void play(boolean loop) {
Speaker speaker = AudioManager.initMusicSpeaker(this.getId());
speaker.setGain(gain);
speaker.setPitch(pitch);
speaker.setPosition(position);
speaker.setVelocity(velocity);
public void play(boolean loop)
{
Speaker speaker = AudioManager.initMusicSpeaker(this.getId());
speaker.setGain(gain);
speaker.setPitch(pitch);
speaker.setPosition(position);
speaker.setVelocity(velocity);
if (loop) {
speaker.playLoop();
} else {
speaker.play();
}
}
if (loop) {
speaker.playLoop();
} else {
speaker.play();
}
}
public void setGain(float gain) {
this.gain = gain;
}
public void setGain(float gain) {
this.gain = gain;
}
public void setPitch(float pitch) {
this.pitch = pitch;
}
public void setPitch(float pitch) { this.pitch = pitch; }
public void setVelocity(Vec3 velocity) {
this.velocity = velocity;
}
public void setVelocity(Vec3 velocity) {
this.velocity = velocity;
}
public Vec3 getPosition() {
return position;
}
public Vec3 getPosition() { return position; }
public float getGain() {
return gain;
}
public float getGain() {
return gain;
}
public Vec3 getVelocity() {
return velocity;
}
public Vec3 getVelocity() {
return velocity;
}
public float getPitch() {
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;
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;
public class SoundEffect
extends Namespaced {
extends Namespaced {
private Vec3 position = new Vec3();
private Vec3 velocity = new Vec3();
private float pitch = 1.0f;
private float gain = 1.0f;
private Vec3 position = new Vec3();
private Vec3 velocity = new Vec3();
private float pitch = 1.0f;
private float gain = 1.0f;
public SoundEffect(String id) {
super(id);
}
public SoundEffect(String id)
{
super(id);
}
public SoundEffect(
String 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,
Vec3 position,
Vec3 velocity,
float pitch,
float gain)
{
this(id);
this.position = position;
this.velocity = velocity;
this.pitch = pitch;
this.gain = gain;
}
public void play(boolean loop) {
Speaker speaker = AudioManager.initSpeaker(this.getId());
speaker.setGain(gain);
speaker.setPitch(pitch);
speaker.setPosition(position);
speaker.setVelocity(velocity);
public void play(boolean loop)
{
Speaker speaker = AudioManager.initSpeaker(this.getId());
speaker.setGain(gain);
speaker.setPitch(pitch);
speaker.setPosition(position);
speaker.setVelocity(velocity);
if (loop) {
speaker.playLoop();
} else {
speaker.play();
}
}
if (loop) {
speaker.playLoop();
} else {
speaker.play();
}
}
public void setGain(float gain) {
this.gain = gain;
}
public void setGain(float gain) {
this.gain = gain;
}
public void setPitch(float pitch) {
this.pitch = pitch;
}
public void setPitch(float pitch) { this.pitch = pitch; }
public void setPosition(Vec3 position) {
this.position = position;
}
public void setPosition(Vec3 position) {
this.position = position;
}
public void setVelocity(Vec3 velocity) {
this.velocity = velocity;
}
public void setVelocity(Vec3 velocity) {
this.velocity = velocity;
}
public Vec3 getPosition() {
return position;
}
public Vec3 getPosition() {
return position;
}
public float getGain() {
return gain;
}
public float getGain() {
return gain;
}
public Vec3 getVelocity() {
return velocity;
}
public Vec3 getVelocity() {
return velocity;
}
public float getPitch() {
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;
import org.lwjgl.BufferUtils;
@ -11,7 +29,8 @@ import static org.lwjgl.openal.AL10.*;
public class AudioReader {
private AudioReader() {}
private AudioReader() {
}
// TODO fix converting from mono-stereo
private static SoundType readAsSpecified(String path, String id, int format) {
@ -22,27 +41,31 @@ public class AudioReader {
ShortBuffer rawAudio = decodeVorbis(res, channelBuffer, rateBuffer);
return new SoundType(id, rawAudio, format,
rateBuffer.get(0));
return new SoundType(
id,
rawAudio,
format,
rateBuffer.get(0)
);
}
public static SoundType readAsMono(String path, String id) {
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);
}
private static ShortBuffer decodeVorbis(
Resource dataToDecode,
IntBuffer channelsBuffer,
IntBuffer rateBuffer
Resource dataToDecode,
IntBuffer channelsBuffer,
IntBuffer rateBuffer
) {
return stb_vorbis_decode_memory(
dataToDecode.readAsBytes(),
channelsBuffer,
rateBuffer
dataToDecode.readAsBytes(),
channelsBuffer,
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;
import glm.vec._3.Vec3;
@ -12,7 +30,8 @@ public class Listener {
private static final Listener INSTANCE = new Listener();
private Listener() {}
private Listener() {
}
public static Listener getInstance() {
return INSTANCE;
@ -37,7 +56,7 @@ public class Listener {
if (wasInWorld) {
velocity.set(camera.getLastAnchorPosition()).sub(position).div(
(float) GraphicsInterface.getFrameLength()
(float) GraphicsInterface.getFrameLength()
);
} else {
// If !wasInWorld, previous position is nonsence. Assume 0.
@ -72,9 +91,17 @@ public class Listener {
private void applyParams() {
alListener3f(AL_POSITION, position.x, position.y, position.z);
alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z);
alListenerfv(AL_ORIENTATION, new float[] {
oriAt.x, oriAt.y, oriAt.z, oriUp.x, oriUp.y, oriUp.z
});
alListenerfv(
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;
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
@ -12,8 +30,12 @@ public class SoundType extends Namespaced {
private int format;
private int audioBuffer;
public SoundType(String id, ShortBuffer rawAudio,
int format, int sampleRate) {
public SoundType(
String id,
ShortBuffer rawAudio,
int format,
int sampleRate
) {
super(id);
this.rawAudio = rawAudio;
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;
import glm.vec._3.Vec3;
@ -5,147 +23,145 @@ import static org.lwjgl.openal.AL11.*;
public class Speaker {
public enum State {
NOT_PLAYING,
PLAYING,
PLAYING_LOOP
}
public enum State {
NOT_PLAYING,
PLAYING,
PLAYING_LOOP
}
// Buffers
private int audioData;
private int sourceData;
// Buffers
private int audioData;
private int sourceData;
// Characteristics
private Vec3 position = new Vec3();
private Vec3 velocity = new Vec3();
private float pitch = 1.0f;
private float gain = 1.0f;
private State state = State.NOT_PLAYING;
// Characteristics
private Vec3 position = new Vec3();
private Vec3 velocity = new Vec3();
private float pitch = 1.0f;
private float gain = 1.0f;
private State state = State.NOT_PLAYING;
public Speaker() {
sourceData = alGenSources();
}
public Speaker() {
sourceData = alGenSources();
}
public Speaker(int audioData) {
this();
setAudioData(audioData);
}
public Speaker(int audioData) {
this();
setAudioData(audioData);
}
public Speaker(
int audioData,
Vec3 position,
Vec3 velocity,
float pitch,
float gain
) {
setAudioData(audioData);
setPosition(position);
setVelocity(velocity);
setPitch(pitch);
setGain(gain);
}
public Speaker(
int audioData,
Vec3 position,
Vec3 velocity,
float pitch,
float gain
) {
setAudioData(audioData);
setPosition(position);
setVelocity(velocity);
setPitch(pitch);
setGain(gain);
}
public Speaker(
Vec3 position,
Vec3 velocity,
float pitch,
float gain
) {
setPosition(position);
setVelocity(velocity);
setPitch(pitch);
setGain(gain);
}
public Speaker(
Vec3 position,
Vec3 velocity,
float pitch,
float gain
) {
setPosition(position);
setVelocity(velocity);
setPitch(pitch);
setGain(gain);
}
public void play() {
alSourcePlay(sourceData);
state = State.PLAYING;
}
public void play() {
alSourcePlay(sourceData);
state = State.PLAYING;
}
public void playLoop() {
alSourcei(sourceData, AL_LOOPING, AL_TRUE);
alSourcePlay(sourceData);
state = State.PLAYING_LOOP;
}
public void playLoop() {
alSourcei(sourceData, AL_LOOPING, AL_TRUE);
alSourcePlay(sourceData);
state = State.PLAYING_LOOP;
}
public void stop() {
alSourceStop(sourceData);
if (state == State.PLAYING_LOOP) {
alSourcei(sourceData, AL_LOOPING, AL_FALSE);
}
state = State.NOT_PLAYING;
}
public void stop() {
alSourceStop(sourceData);
if (state == State.PLAYING_LOOP) {
alSourcei(sourceData, AL_LOOPING, AL_FALSE);
}
state = State.NOT_PLAYING;
}
public void pause() {
alSourcePause(sourceData);
state = State.NOT_PLAYING;
}
public void pause() {
alSourcePause(sourceData);
state = State.NOT_PLAYING;
}
public boolean isPlaying() {
final int speakerState = alGetSourcei(sourceData, AL_SOURCE_STATE);
if (speakerState == AL_PLAYING) {
return true;
}
else {
state = State.NOT_PLAYING;
return false;
}
}
public boolean isPlaying() {
final int speakerState = alGetSourcei(sourceData, AL_SOURCE_STATE);
if (speakerState == AL_PLAYING) {
return true;
} else {
state = State.NOT_PLAYING;
return false;
}
}
// GETTERS & SETTERS
// GETTERS & SETTERS
public int getAudioData() {
return audioData;
}
public int getAudioData() {
return audioData;
}
public int getSourceData() {
return sourceData;
}
public int getSourceData() {
return sourceData;
}
public void setAudioData(int audioData) {
this.audioData = audioData;
alSourcei(this.sourceData, AL_BUFFER, audioData);
}
public void setAudioData(int audioData) {
this.audioData = audioData;
alSourcei(this.sourceData, AL_BUFFER, audioData);
}
public void setPosition(Vec3 position) {
this.position = position;
alSource3f(sourceData, AL_POSITION, position.x, position.y, position.z);
}
public void setPosition(Vec3 position) {
this.position = position;
alSource3f(sourceData, AL_POSITION, position.x, position.y, position.z);
}
public Vec3 getPosition() {
return position;
}
public Vec3 getPosition() {
return position;
}
public void setVelocity(Vec3 velocity) {
alSource3f(sourceData, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
this.velocity = velocity;
}
public void setVelocity(Vec3 velocity) {
alSource3f(sourceData, AL_VELOCITY, velocity.x, velocity.y, velocity.z);
this.velocity = velocity;
}
public Vec3 getVelocity() {
return velocity;
}
public Vec3 getVelocity() {
return velocity;
}
public void setPitch(float pitch) {
alSourcef(sourceData, AL_PITCH, pitch);
this.pitch = pitch;
}
public void setPitch(float pitch) {
alSourcef(sourceData, AL_PITCH, pitch);
this.pitch = pitch;
}
public float getPitch() {
return pitch;
}
public float getPitch() {
return pitch;
}
public void setGain(float gain) {
alSourcef(sourceData, AL_GAIN, gain);
this.gain = gain;
}
public void setGain(float gain) {
alSourcef(sourceData, AL_GAIN, gain);
this.gain = gain;
}
public float getGain() {
return gain;
}
public float getGain() {
return gain;
}
public State getState()
{
return state;
}
public State getState() {
return state;
}
}
}

View File

@ -1,46 +1,64 @@
package ru.windcorp.progressia.client.comms;
import java.io.IOException;
import ru.windcorp.progressia.client.Client;
import ru.windcorp.progressia.common.comms.CommsListener;
import ru.windcorp.progressia.common.comms.packets.Packet;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.common.world.PacketSetLocalPlayer;
import ru.windcorp.progressia.common.world.PacketAffectWorld;
// TODO refactor with no mercy
public class DefaultClientCommsListener implements CommsListener {
private final Client client;
public DefaultClientCommsListener(Client client) {
this.client = client;
}
@Override
public void onPacketReceived(Packet packet) {
if (packet instanceof PacketAffectWorld) {
((PacketAffectWorld) packet).apply(
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;
}
}
/*
* 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;
import java.io.IOException;
import ru.windcorp.progressia.client.Client;
import ru.windcorp.progressia.common.comms.CommsListener;
import ru.windcorp.progressia.common.comms.packets.Packet;
import ru.windcorp.progressia.common.util.crash.CrashReports;
import ru.windcorp.progressia.common.world.PacketSetLocalPlayer;
import ru.windcorp.progressia.common.world.PacketAffectWorld;
// TODO refactor with no mercy
public class DefaultClientCommsListener implements CommsListener {
private final Client client;
public DefaultClientCommsListener(Client client) {
this.client = client;
}
@Override
public void onPacketReceived(Packet packet) {
if (packet instanceof PacketAffectWorld) {
((PacketAffectWorld) packet).apply(
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;
import ru.windcorp.progressia.common.comms.CommsChannel;
public abstract class ServerCommsChannel extends CommsChannel {
}
/*
* 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;
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;
import ru.windcorp.progressia.common.util.namespaces.Namespaced;
public abstract class ControlTrigger extends Namespaced {
public ControlTrigger(String id) {
super(id);
}
}
/*
* 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;
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;
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);
}
/*
* 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;
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;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import ru.windcorp.progressia.client.graphics.input.InputEvent;
import ru.windcorp.progressia.common.comms.controls.ControlData;
import ru.windcorp.progressia.common.comms.controls.ControlDataRegistry;
import ru.windcorp.progressia.common.comms.controls.PacketControl;
import ru.windcorp.progressia.common.util.namespaces.NamespacedUtil;
public class ControlTriggerLambda extends ControlTriggerInputBased {
private final String packetId;
private final Predicate<InputEvent> predicate;
private final BiConsumer<InputEvent, ControlData> dataWriter;
public ControlTriggerLambda(
String id,
Predicate<InputEvent> predicate,
BiConsumer<InputEvent, ControlData> dataWriter
) {
super(id);
this.packetId = NamespacedUtil.getId(
NamespacedUtil.getNamespace(id),
"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;
}
}
/*
* 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;
import java.util.function.BiConsumer;
import java.util.function.Predicate;
import ru.windcorp.progressia.client.graphics.input.InputEvent;
import ru.windcorp.progressia.common.comms.controls.ControlData;
import ru.windcorp.progressia.common.comms.controls.ControlDataRegistry;
import ru.windcorp.progressia.common.comms.controls.PacketControl;
import ru.windcorp.progressia.common.util.namespaces.NamespacedUtil;
public class ControlTriggerLambda extends ControlTriggerInputBased {
private final String packetId;
private final Predicate<InputEvent> predicate;
private final BiConsumer<InputEvent, ControlData> dataWriter;
public ControlTriggerLambda(
String id,
Predicate<InputEvent> predicate,
BiConsumer<InputEvent, ControlData> dataWriter
) {
super(id);
this.packetId = NamespacedUtil.getId(
NamespacedUtil.getNamespace(id),
"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;
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;
}
}
/*
* 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;
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;
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;
public class ControlTriggers {
public static ControlTriggerInputBased of(
String id,
BiConsumer<InputEvent, ControlData> dataWriter,
Predicate<InputEvent> predicate
String id,
BiConsumer<InputEvent, ControlData> dataWriter,
Predicate<InputEvent> predicate
) {
return new ControlTriggerLambda(id, predicate, dataWriter);
}
public static ControlTriggerInputBased of(
String id,
Consumer<ControlData> dataWriter,
Predicate<InputEvent> predicate
String id,
Consumer<ControlData> dataWriter,
Predicate<InputEvent> predicate
) {
return of(
id,
(input, control) -> dataWriter.accept(control),
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
id,
(input, control) -> dataWriter.accept(control),
predicate
);
}
private static
<I extends InputEvent>
BiConsumer<InputEvent, ControlData>
createCheckedDataWriter(
Class<I> inputType,
BiConsumer<I, ControlData> dataWriter
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 <I extends InputEvent> BiConsumer<InputEvent, ControlData> createCheckedDataWriter(
Class<I> inputType,
BiConsumer<I, ControlData> dataWriter
) {
return (inputEvent, control) -> dataWriter.accept(inputType.cast(inputEvent), control);
}
private static
<I extends InputEvent>
Predicate<InputEvent>
createCheckedCompoundPredicate(
Class<I> inputType,
Predicate<I>[] predicates
private static <I extends InputEvent> Predicate<InputEvent> createCheckedCompoundPredicate(
Class<I> inputType,
Predicate<I>[] predicates
) {
return new CompoundCastPredicate<>(inputType, predicates);
}
private static class CompoundCastPredicate<I extends InputEvent> implements Predicate<InputEvent> {
private final Class<I> inputType;
private final Predicate<I>[] predicates;
public CompoundCastPredicate(Class<I> inputType, Predicate<I>[] predicates) {
this.inputType = inputType;
this.predicates = predicates;
@ -157,20 +172,21 @@ public class ControlTriggers {
if (!inputType.isInstance(inputEvent)) {
return false;
}
I castEvent = inputType.cast(inputEvent);
for (Predicate<I> predicate : predicates) {
if (!predicate.test(castEvent)) {
return false;
}
}
return true;
}
}
private ControlTriggers() {}
private ControlTriggers() {
}
}

View File

@ -1,33 +1,51 @@
package ru.windcorp.progressia.client.comms.controls;
import ru.windcorp.progressia.client.Client;
import ru.windcorp.progressia.client.graphics.input.bus.Input;
import ru.windcorp.progressia.common.comms.packets.Packet;
public class InputBasedControls {
private final Client client;
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;
}
}
}
}
/*
* 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;
import ru.windcorp.progressia.client.Client;
import ru.windcorp.progressia.client.graphics.input.bus.Input;
import ru.windcorp.progressia.common.comms.packets.Packet;
public class InputBasedControls {
private final Client client;
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;
import java.io.IOException;
import ru.windcorp.progressia.common.comms.packets.Packet;
import ru.windcorp.progressia.server.comms.ClientPlayer;
public class LocalClient extends ClientPlayer {
private final LocalServerCommsChannel serverComms;
private final String login;
public LocalClient(int id, String login, LocalServerCommsChannel serverComms) {
super(id);
setState(State.CONNECTED);
this.serverComms = serverComms;
this.login = login;
}
@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
}
}
/*
* 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.localhost;
import java.io.IOException;
import ru.windcorp.progressia.common.comms.packets.Packet;
import ru.windcorp.progressia.server.comms.ClientPlayer;
public class LocalClient extends ClientPlayer {
private final LocalServerCommsChannel serverComms;
private final String login;
public LocalClient(int id, String login, LocalServerCommsChannel serverComms) {
super(id);
setState(State.CONNECTED);
this.serverComms = serverComms;
this.login = login;
}
@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;
import ru.windcorp.progressia.client.comms.ServerCommsChannel;
import ru.windcorp.progressia.common.comms.packets.Packet;
import ru.windcorp.progressia.server.Server;
public class LocalServerCommsChannel extends ServerCommsChannel {
private LocalClient localClient;
private final Server server;
public LocalServerCommsChannel(Server server) {
this.server = server;
}
public void connect(String login) {
setState(State.CONNECTED);
this.localClient = new LocalClient(
server.getClientManager().grabClientId(),
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
}
}
/*
* 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.localhost;
import ru.windcorp.progressia.client.comms.ServerCommsChannel;
import ru.windcorp.progressia.common.comms.packets.Packet;
import ru.windcorp.progressia.server.Server;
public class LocalServerCommsChannel extends ServerCommsChannel {
private LocalClient localClient;
private final Server server;
public LocalServerCommsChannel(Server server) {
this.server = server;
}
public void connect(String login) {
setState(State.CONNECTED);
this.localClient = new LocalClient(
server.getClientManager().grabClientId(),
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
* Copyright (C) 2020 Wind Corporation
*
* 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;
import glm.vec._4.Vec4;
public class Colors {
public static final Vec4
WHITE = toVector(0xFFFFFFFF),
BLACK = toVector(0xFF000000),
GRAY_4 = toVector(0xFF444444),
GRAY = toVector(0xFF888888),
GRAY_A = toVector(0xFFAAAAAA),
DEBUG_RED = toVector(0xFFFF0000),
DEBUG_GREEN = toVector(0xFF00FF00),
DEBUG_BLUE = toVector(0xFF0000FF),
DEBUG_CYAN = toVector(0xFF00FFFF),
DEBUG_MAGENTA = toVector(0xFFFF00FF),
DEBUG_YELLOW = toVector(0xFFFFFF00);
public static Vec4 toVector(int argb) {
return toVector(argb, new Vec4());
}
public static Vec4 multiplyRGB(Vec4 color, float multiplier) {
return color.mul(multiplier, multiplier, multiplier, 1);
}
public static Vec4 multiplyRGB(Vec4 color, float multiplier, Vec4 output) {
if (output == null) 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
output.x = ((argb & 0x00FF0000) >>> 16) / (float) 0xFF; // Red
output.y = ((argb & 0x0000FF00) >>> 8) / (float) 0xFF; // Green
output.z = ((argb & 0x000000FF) ) / (float) 0xFF; // Blue
return output;
}
}
/*
* 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;
import glm.vec._4.Vec4;
public class Colors {
public static final Vec4 WHITE = toVector(0xFFFFFFFF),
BLACK = toVector(0xFF000000),
GRAY_4 = toVector(0xFF444444),
GRAY = toVector(0xFF888888),
GRAY_A = toVector(0xFFAAAAAA),
DEBUG_RED = toVector(0xFFFF0000),
DEBUG_GREEN = toVector(0xFF00FF00),
DEBUG_BLUE = toVector(0xFF0000FF),
DEBUG_CYAN = toVector(0xFF00FFFF),
DEBUG_MAGENTA = toVector(0xFFFF00FF),
DEBUG_YELLOW = toVector(0xFFFFFF00);
public static Vec4 toVector(int argb) {
return toVector(argb, new Vec4());
}
public static Vec4 multiplyRGB(Vec4 color, float multiplier) {
return color.mul(multiplier, multiplier, multiplier, 1);
}
public static Vec4 multiplyRGB(Vec4 color, float multiplier, Vec4 output) {
if (output == null)
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
output.x = ((argb & 0x00FF0000) >>> 16) / (float) 0xFF; // Red
output.y = ((argb & 0x0000FF00) >>> 8) / (float) 0xFF; // Green
output.z = ((argb & 0x000000FF)) / (float) 0xFF; // Blue
return output;
}
}

View File

@ -1,130 +1,133 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
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.InputEvent;
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
import ru.windcorp.progressia.client.graphics.input.WheelEvent;
import ru.windcorp.progressia.client.graphics.input.bus.Input;
public class GUI {
private static final List<Layer> LAYERS = Collections.synchronizedList(new ArrayList<>());
private static final List<Layer> UNMODIFIABLE_LAYERS = Collections.unmodifiableList(LAYERS);
@FunctionalInterface
private interface LayerStackModification {
void affect(List<Layer> layers);
}
private static final List<LayerStackModification> MODIFICATION_QUEUE = Collections.synchronizedList(new ArrayList<>());
private static class ModifiableInput extends Input {
@Override
public void initialize(InputEvent event, Target target) {
super.initialize(event, target);
}
}
private static final ModifiableInput THE_INPUT = new ModifiableInput();
private GUI() {}
public static void addBottomLayer(Layer layer) {
modify(layers -> layers.add(layer));
}
public static void addTopLayer(Layer layer) {
modify(layers -> layers.add(0, layer));
}
public static void removeLayer(Layer layer) {
modify(layers -> layers.remove(layer));
}
private static void modify(LayerStackModification mod) {
MODIFICATION_QUEUE.add(mod);
}
public static List<Layer> getLayers() {
return UNMODIFIABLE_LAYERS;
}
public static void render() {
synchronized (LAYERS) {
MODIFICATION_QUEUE.forEach(action -> action.affect(LAYERS));
MODIFICATION_QUEUE.clear();
for (int i = LAYERS.size() - 1; i >= 0; --i) {
LAYERS.get(i).render();
}
}
}
public static void invalidateEverything() {
LAYERS.forEach(Layer::invalidate);
}
private static void dispatchInputEvent(InputEvent event) {
Input.Target target;
if (event instanceof KeyEvent) {
if (((KeyEvent) event).isMouse()) {
target = Input.Target.HOVERED;
} else {
target = Input.Target.FOCUSED;
}
} else if (event instanceof CursorEvent) {
target = Input.Target.HOVERED;
} else if (event instanceof WheelEvent) {
target = Input.Target.HOVERED;
} else if (event instanceof FrameResizeEvent) {
return;
} else {
target = Input.Target.ALL;
}
THE_INPUT.initialize(event, target);
LAYERS.forEach(l -> l.handleInput(THE_INPUT));
}
public static Object getEventSubscriber() {
return new Object() {
@Subscribe
public void onFrameResized(FrameResizeEvent event) {
GUI.invalidateEverything();
}
@Subscribe
public void onInput(InputEvent event) {
dispatchInputEvent(event);
}
};
}
}
/*
* 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;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
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.InputEvent;
import ru.windcorp.progressia.client.graphics.input.KeyEvent;
import ru.windcorp.progressia.client.graphics.input.WheelEvent;
import ru.windcorp.progressia.client.graphics.input.bus.Input;
public class GUI {
private static final List<Layer> LAYERS = Collections.synchronizedList(new ArrayList<>());
private static final List<Layer> UNMODIFIABLE_LAYERS = Collections.unmodifiableList(LAYERS);
@FunctionalInterface
private interface LayerStackModification {
void affect(List<Layer> layers);
}
private static final List<LayerStackModification> MODIFICATION_QUEUE = Collections
.synchronizedList(new ArrayList<>());
private static class ModifiableInput extends Input {
@Override
public void initialize(InputEvent event, Target target) {
super.initialize(event, target);
}
}
private static final ModifiableInput THE_INPUT = new ModifiableInput();
private GUI() {
}
public static void addBottomLayer(Layer layer) {
modify(layers -> layers.add(layer));
}
public static void addTopLayer(Layer layer) {
modify(layers -> layers.add(0, layer));
}
public static void removeLayer(Layer layer) {
modify(layers -> layers.remove(layer));
}
private static void modify(LayerStackModification mod) {
MODIFICATION_QUEUE.add(mod);
}
public static List<Layer> getLayers() {
return UNMODIFIABLE_LAYERS;
}
public static void render() {
synchronized (LAYERS) {
MODIFICATION_QUEUE.forEach(action -> action.affect(LAYERS));
MODIFICATION_QUEUE.clear();
for (int i = LAYERS.size() - 1; i >= 0; --i) {
LAYERS.get(i).render();
}
}
}
public static void invalidateEverything() {
LAYERS.forEach(Layer::invalidate);
}
private static void dispatchInputEvent(InputEvent event) {
Input.Target target;
if (event instanceof KeyEvent) {
if (((KeyEvent) event).isMouse()) {
target = Input.Target.HOVERED;
} else {
target = Input.Target.FOCUSED;
}
} else if (event instanceof CursorEvent) {
target = Input.Target.HOVERED;
} else if (event instanceof WheelEvent) {
target = Input.Target.HOVERED;
} else if (event instanceof FrameResizeEvent) {
return;
} else {
target = Input.Target.ALL;
}
THE_INPUT.initialize(event, target);
LAYERS.forEach(l -> l.handleInput(THE_INPUT));
}
public static Object getEventSubscriber() {
return new Object() {
@Subscribe
public void onFrameResized(FrameResizeEvent event) {
GUI.invalidateEverything();
}
@Subscribe
public void onInput(InputEvent event) {
dispatchInputEvent(event);
}
};
}
}

View File

@ -1,81 +1,82 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
import java.util.concurrent.atomic.AtomicBoolean;
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
import ru.windcorp.progressia.client.graphics.input.bus.Input;
public abstract class Layer {
private final String name;
private boolean hasInitialized = false;
private final AtomicBoolean isValid = new AtomicBoolean(false);
public Layer(String name) {
this.name = name;
}
@Override
public String toString() {
return "Layer " + name;
}
void render() {
GraphicsInterface.startNextLayer();
validate();
if (!hasInitialized) {
initialize();
hasInitialized = true;
}
doRender();
}
void validate() {
if (isValid.compareAndSet(false, true)) {
doValidate();
}
}
public void invalidate() {
isValid.set(false);
}
protected abstract void initialize();
protected abstract void doValidate();
protected abstract void doRender();
protected abstract void handleInput(Input input);
protected int getWidth() {
return GraphicsInterface.getFrameWidth();
}
protected int getHeight() {
return GraphicsInterface.getFrameHeight();
}
}
/*
* 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;
import java.util.concurrent.atomic.AtomicBoolean;
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
import ru.windcorp.progressia.client.graphics.input.bus.Input;
public abstract class Layer {
private final String name;
private boolean hasInitialized = false;
private final AtomicBoolean isValid = new AtomicBoolean(false);
public Layer(String name) {
this.name = name;
}
@Override
public String toString() {
return "Layer " + name;
}
void render() {
GraphicsInterface.startNextLayer();
validate();
if (!hasInitialized) {
initialize();
hasInitialized = true;
}
doRender();
}
void validate() {
if (isValid.compareAndSet(false, true)) {
doValidate();
}
}
public void invalidate() {
isValid.set(false);
}
protected abstract void initialize();
protected abstract void doValidate();
protected abstract void doRender();
protected abstract void handleInput(Input input);
protected int getWidth() {
return GraphicsInterface.getFrameWidth();
}
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;
import java.util.ArrayDeque;
import java.util.Deque;
public class FaceCulling {
private static final Deque<Boolean> STACK = new ArrayDeque<>();
public static void push(boolean useFaceCulling) {
GraphicsBackend.setFaceCulling(useFaceCulling);
STACK.push(Boolean.valueOf(useFaceCulling));
}
public static void pop() {
STACK.pop();
if (STACK.isEmpty()) {
GraphicsBackend.setFaceCulling(false);
} else {
GraphicsBackend.setFaceCulling(STACK.getFirst());
}
}
private FaceCulling() {}
private FaceCulling() {
}
}

View File

@ -1,127 +1,131 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
import static org.lwjgl.opengl.GL11.*;
import glm.vec._2.i.Vec2i;
import static org.lwjgl.glfw.GLFW.*;
public class GraphicsBackend {
private static RenderThread renderThread;
private static long windowHandle;
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 frameStart = Double.NaN;
private static boolean faceCullingEnabled = false;
private GraphicsBackend() {}
public static void initialize() {
startRenderThread();
}
private static void startRenderThread() {
renderThread = new RenderThread();
renderThread.start();
}
public static Thread getRenderThread() {
return renderThread;
}
static void setWindowHandle(long windowHandle) {
GraphicsBackend.windowHandle = windowHandle;
}
public static long getWindowHandle() {
return windowHandle;
}
public static int getFrameWidth() {
return FRAME_SIZE.x;
}
public static int getFrameHeight() {
return FRAME_SIZE.y;
}
public static Vec2i getFrameSize() {
return FRAME_SIZE;
}
static void onFrameResized(long window, int newWidth, int newHeight) {
if (window != windowHandle) return;
InputHandler.handleFrameResize(newWidth, newHeight);
FRAME_SIZE.set(newWidth, newHeight);
glViewport(0, 0, newWidth, newHeight);
}
static void startFrame() {
double now = glfwGetTime();
if (Double.isNaN(frameStart)) {
frameStart = now;
} else {
frameLength = now - frameStart;
frameStart = now;
}
}
static void endFrame() {
framesRendered++;
}
public static double getFrameStart() {
return frameStart;
}
public static double getFrameLength() {
return frameLength;
}
public static long getFramesRendered() {
return framesRendered;
}
public static void startNextLayer() {
glClear(GL_DEPTH_BUFFER_BIT);
}
public static void setFaceCulling(boolean useFaceCulling) {
if (useFaceCulling == faceCullingEnabled) return;
if (useFaceCulling) {
glEnable(GL_CULL_FACE);
} else {
glDisable(GL_CULL_FACE);
}
faceCullingEnabled = useFaceCulling;
}
}
/*
* 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;
import static org.lwjgl.opengl.GL11.*;
import glm.vec._2.i.Vec2i;
import static org.lwjgl.glfw.GLFW.*;
public class GraphicsBackend {
private static RenderThread renderThread;
private static long windowHandle;
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 frameStart = Double.NaN;
private static boolean faceCullingEnabled = false;
private GraphicsBackend() {
}
public static void initialize() {
startRenderThread();
}
private static void startRenderThread() {
renderThread = new RenderThread();
renderThread.start();
}
public static Thread getRenderThread() {
return renderThread;
}
static void setWindowHandle(long windowHandle) {
GraphicsBackend.windowHandle = windowHandle;
}
public static long getWindowHandle() {
return windowHandle;
}
public static int getFrameWidth() {
return FRAME_SIZE.x;
}
public static int getFrameHeight() {
return FRAME_SIZE.y;
}
public static Vec2i getFrameSize() {
return FRAME_SIZE;
}
static void onFrameResized(long window, int newWidth, int newHeight) {
if (window != windowHandle)
return;
InputHandler.handleFrameResize(newWidth, newHeight);
FRAME_SIZE.set(newWidth, newHeight);
glViewport(0, 0, newWidth, newHeight);
}
static void startFrame() {
double now = glfwGetTime();
if (Double.isNaN(frameStart)) {
frameStart = now;
} else {
frameLength = now - frameStart;
frameStart = now;
}
}
static void endFrame() {
framesRendered++;
}
public static double getFrameStart() {
return frameStart;
}
public static double getFrameLength() {
return frameLength;
}
public static long getFramesRendered() {
return framesRendered;
}
public static void startNextLayer() {
glClear(GL_DEPTH_BUFFER_BIT);
}
public static void setFaceCulling(boolean useFaceCulling) {
if (useFaceCulling == faceCullingEnabled)
return;
if (useFaceCulling) {
glEnable(GL_CULL_FACE);
} else {
glDisable(GL_CULL_FACE);
}
faceCullingEnabled = useFaceCulling;
}
}

View File

@ -1,74 +1,76 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
import glm.vec._2.i.Vec2i;
public class GraphicsInterface {
private GraphicsInterface() {}
public static Thread getRenderThread() {
return GraphicsBackend.getRenderThread();
}
public static boolean isRenderThread() {
return Thread.currentThread() == getRenderThread();
}
public static int getFrameWidth() {
return GraphicsBackend.getFrameWidth();
}
public static int getFrameHeight() {
return GraphicsBackend.getFrameHeight();
}
public static Vec2i getFrameSize() {
return GraphicsBackend.getFrameSize();
}
public static float getAspectRatio() {
return ((float) getFrameWidth()) / getFrameHeight();
}
public static double getTime() {
return GraphicsBackend.getFrameStart();
}
public static double getFrameLength() {
return GraphicsBackend.getFrameLength();
}
public static double getFPS() {
return 1 / GraphicsBackend.getFrameLength();
}
public static long getFramesRendered() {
return GraphicsBackend.getFramesRendered();
}
public static void subscribeToInputEvents(Object listener) {
InputHandler.register(listener);
}
public static void startNextLayer() {
GraphicsBackend.startNextLayer();
}
}
/*
* 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;
import glm.vec._2.i.Vec2i;
public class GraphicsInterface {
private GraphicsInterface() {
}
public static Thread getRenderThread() {
return GraphicsBackend.getRenderThread();
}
public static boolean isRenderThread() {
return Thread.currentThread() == getRenderThread();
}
public static int getFrameWidth() {
return GraphicsBackend.getFrameWidth();
}
public static int getFrameHeight() {
return GraphicsBackend.getFrameHeight();
}
public static Vec2i getFrameSize() {
return GraphicsBackend.getFrameSize();
}
public static float getAspectRatio() {
return ((float) getFrameWidth()) / getFrameHeight();
}
public static double getTime() {
return GraphicsBackend.getFrameStart();
}
public static double getFrameLength() {
return GraphicsBackend.getFrameLength();
}
public static double getFPS() {
return 1 / GraphicsBackend.getFrameLength();
}
public static long getFramesRendered() {
return GraphicsBackend.getFramesRendered();
}
public static void subscribeToInputEvents(Object listener) {
InputHandler.register(listener);
}
public static void startNextLayer() {
GraphicsBackend.startNextLayer();
}
}

View File

@ -1,182 +1,183 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
import org.lwjgl.glfw.GLFW;
import com.google.common.eventbus.EventBus;
import ru.windcorp.progressia.client.graphics.input.*;
import ru.windcorp.progressia.common.util.crash.ReportingEventBus;
public class InputHandler {
private static final EventBus INPUT_EVENT_BUS = ReportingEventBus.create("Input");
// KeyEvent
private static class ModifiableKeyEvent extends KeyEvent {
protected ModifiableKeyEvent() {
super(0, 0, 0, 0, Double.NaN);
}
public void initialize(int key, int scancode, int action, int mods) {
this.setTime(GraphicsInterface.getTime());
this.key = key;
this.scancode = scancode;
this.action = action;
this.mods = mods;
}
}
private static final ModifiableKeyEvent THE_KEY_EVENT =
new ModifiableKeyEvent();
static void handleKeyInput(
long window,
int key,
int scancode,
int action,
int mods
) {
if (GraphicsBackend.getWindowHandle() != window) return;
THE_KEY_EVENT.initialize(key, scancode, action, mods);
dispatch(THE_KEY_EVENT);
switch (action) {
case GLFW.GLFW_PRESS:
InputTracker.setKeyState(key, true);
break;
case GLFW.GLFW_RELEASE:
InputTracker.setKeyState(key, false);
break;
}
}
static void handleMouseButtonInput(
long window,
int key,
int action,
int mods
) {
handleKeyInput(window, key, Integer.MAX_VALUE - key, action, mods);
}
// CursorMoveEvent
private static class ModifiableCursorMoveEvent extends CursorMoveEvent {
protected ModifiableCursorMoveEvent() {
super(0, 0, Double.NaN);
}
public void initialize(double x, double y) {
this.setTime(GraphicsInterface.getTime());
getNewPosition().set(x, y);
}
}
private static final ModifiableCursorMoveEvent THE_CURSOR_MOVE_EVENT =
new ModifiableCursorMoveEvent();
static void handleMouseMoveInput(
long window,
double x, double y
) {
if (GraphicsBackend.getWindowHandle() != window) return;
y = GraphicsInterface.getFrameHeight() - y; // Flip y axis
InputTracker.initializeCursorPosition(x, y);
THE_CURSOR_MOVE_EVENT.initialize(x, y);
dispatch(THE_CURSOR_MOVE_EVENT);
InputTracker.getCursorPosition().set(x, y);
}
// ScrollEvent
private static class ModifiableWheelScrollEvent extends WheelScrollEvent {
public ModifiableWheelScrollEvent() {
super(0, 0, Double.NaN);
}
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();
static void handleWheelScroll(
long window,
double xoffset,
double yoffset
) {
if (GraphicsBackend.getWindowHandle() != window) return;
THE_WHEEL_SCROLL_EVENT.initialize(xoffset, yoffset);
dispatch(THE_WHEEL_SCROLL_EVENT);
}
// FrameResizeEvent
private static class ModifiableFrameResizeEvent extends FrameResizeEvent {
public ModifiableFrameResizeEvent() {
super(0, 0, Double.NaN);
}
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();
/*
* NB: this is NOT a GLFW callback, the raw callback is in GraphicsBackend
*/
static void handleFrameResize(
int width,
int height
) {
THE_FRAME_RESIZE_EVENT.initialize(width, height);
dispatch(THE_FRAME_RESIZE_EVENT);
}
// Misc
private static void dispatch(InputEvent event) {
INPUT_EVENT_BUS.post(event);
}
public static void register(Object listener) {
INPUT_EVENT_BUS.register(listener);
}
}
/*
* 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;
import org.lwjgl.glfw.GLFW;
import com.google.common.eventbus.EventBus;
import ru.windcorp.progressia.client.graphics.input.*;
import ru.windcorp.progressia.common.util.crash.ReportingEventBus;
public class InputHandler {
private static final EventBus INPUT_EVENT_BUS = ReportingEventBus.create("Input");
// KeyEvent
private static class ModifiableKeyEvent extends KeyEvent {
protected ModifiableKeyEvent() {
super(0, 0, 0, 0, Double.NaN);
}
public void initialize(int key, int scancode, int action, int mods) {
this.setTime(GraphicsInterface.getTime());
this.key = key;
this.scancode = scancode;
this.action = action;
this.mods = mods;
}
}
private static final ModifiableKeyEvent THE_KEY_EVENT = new ModifiableKeyEvent();
static void handleKeyInput(
long window,
int key,
int scancode,
int action,
int mods
) {
if (GraphicsBackend.getWindowHandle() != window)
return;
THE_KEY_EVENT.initialize(key, scancode, action, mods);
dispatch(THE_KEY_EVENT);
switch (action) {
case GLFW.GLFW_PRESS:
InputTracker.setKeyState(key, true);
break;
case GLFW.GLFW_RELEASE:
InputTracker.setKeyState(key, false);
break;
}
}
static void handleMouseButtonInput(
long window,
int key,
int action,
int mods
) {
handleKeyInput(window, key, Integer.MAX_VALUE - key, action, mods);
}
// CursorMoveEvent
private static class ModifiableCursorMoveEvent extends CursorMoveEvent {
protected ModifiableCursorMoveEvent() {
super(0, 0, Double.NaN);
}
public void initialize(double x, double y) {
this.setTime(GraphicsInterface.getTime());
getNewPosition().set(x, y);
}
}
private static final ModifiableCursorMoveEvent THE_CURSOR_MOVE_EVENT = new ModifiableCursorMoveEvent();
static void handleMouseMoveInput(
long window,
double x,
double y
) {
if (GraphicsBackend.getWindowHandle() != window)
return;
y = GraphicsInterface.getFrameHeight() - y; // Flip y axis
InputTracker.initializeCursorPosition(x, y);
THE_CURSOR_MOVE_EVENT.initialize(x, y);
dispatch(THE_CURSOR_MOVE_EVENT);
InputTracker.getCursorPosition().set(x, y);
}
// ScrollEvent
private static class ModifiableWheelScrollEvent extends WheelScrollEvent {
public ModifiableWheelScrollEvent() {
super(0, 0, Double.NaN);
}
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();
static void handleWheelScroll(
long window,
double xoffset,
double yoffset
) {
if (GraphicsBackend.getWindowHandle() != window)
return;
THE_WHEEL_SCROLL_EVENT.initialize(xoffset, yoffset);
dispatch(THE_WHEEL_SCROLL_EVENT);
}
// FrameResizeEvent
private static class ModifiableFrameResizeEvent extends FrameResizeEvent {
public ModifiableFrameResizeEvent() {
super(0, 0, Double.NaN);
}
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();
/*
* NB: this is NOT a GLFW callback, the raw callback is in GraphicsBackend
*/
static void handleFrameResize(
int width,
int height
) {
THE_FRAME_RESIZE_EVENT.initialize(width, height);
dispatch(THE_FRAME_RESIZE_EVENT);
}
// Misc
private static void dispatch(InputEvent event) {
INPUT_EVENT_BUS.post(event);
}
public static void register(Object listener) {
INPUT_EVENT_BUS.register(listener);
}
}

View File

@ -1,72 +1,75 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
import glm.vec._2.d.Vec2d;
import gnu.trove.set.TIntSet;
import gnu.trove.set.hash.TIntHashSet;
public class InputTracker {
private static final Vec2d CURSOR_POSITION = new Vec2d(
Double.NaN, Double.NaN
);
private static final TIntSet PRESSED_KEYS = new TIntHashSet(256);
private InputTracker() {}
public static double getCursorX() {
return CURSOR_POSITION.x;
}
public static double getCursorY() {
return CURSOR_POSITION.y;
}
public static Vec2d getCursorPosition() {
return CURSOR_POSITION;
}
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);
}
static void setKeyState(int glfwCode, boolean isPressed) {
if (isPressed) {
PRESSED_KEYS.add(glfwCode);
} else {
PRESSED_KEYS.remove(glfwCode);
}
}
public static TIntSet getPressedKeys() {
return PRESSED_KEYS;
}
static void releaseEverything() {
PRESSED_KEYS.clear();
}
}
/*
* 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;
import glm.vec._2.d.Vec2d;
import gnu.trove.set.TIntSet;
import gnu.trove.set.hash.TIntHashSet;
public class InputTracker {
private static final Vec2d CURSOR_POSITION = new Vec2d(
Double.NaN,
Double.NaN
);
private static final TIntSet PRESSED_KEYS = new TIntHashSet(256);
private InputTracker() {
}
public static double getCursorX() {
return CURSOR_POSITION.x;
}
public static double getCursorY() {
return CURSOR_POSITION.y;
}
public static Vec2d getCursorPosition() {
return CURSOR_POSITION;
}
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);
}
static void setKeyState(int glfwCode, boolean isPressed) {
if (isPressed) {
PRESSED_KEYS.add(glfwCode);
} else {
PRESSED_KEYS.remove(glfwCode);
}
}
public static TIntSet getPressedKeys() {
return PRESSED_KEYS;
}
static void releaseEverything() {
PRESSED_KEYS.clear();
}
}

View File

@ -1,107 +1,113 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.system.MemoryUtil.*;
import org.lwjgl.opengl.GL;
import ru.windcorp.progressia.client.graphics.GUI;
class LWJGLInitializer {
private LWJGLInitializer() {}
public static void initialize() {
checkEnvironment();
initializeGLFW();
createWindow();
positionWindow();
createWindowIcons();
initializeOpenGL();
setupWindowCallbacks();
glfwShowWindow(GraphicsBackend.getWindowHandle());
}
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 createWindow() {
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
long handle = glfwCreateWindow(900, 900, "ProgressiaTest", NULL, NULL);
// TODO Check that handle != NULL
GraphicsBackend.setWindowHandle(handle);
glfwSetInputMode(handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwMakeContextCurrent(handle);
glfwSwapInterval(0);
}
private static void positionWindow() {
// TODO Auto-generated method stub
}
private static void createWindowIcons() {
// TODO Auto-generated method stub
}
private static void initializeOpenGL() {
GL.createCapabilities();
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
RenderTaskQueue.schedule(OpenGLObjectTracker::deleteEnqueuedObjects);
}
private static void setupWindowCallbacks() {
long handle = GraphicsBackend.getWindowHandle();
glfwSetFramebufferSizeCallback(handle,
GraphicsBackend::onFrameResized);
glfwSetKeyCallback(handle, InputHandler::handleKeyInput);
glfwSetMouseButtonCallback(handle,
InputHandler::handleMouseButtonInput);
glfwSetCursorPosCallback(handle, InputHandler::handleMouseMoveInput);
glfwSetScrollCallback(handle, InputHandler::handleWheelScroll);
GraphicsInterface.subscribeToInputEvents(GUI.getEventSubscriber());
}
}
/*
* 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;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.system.MemoryUtil.*;
import org.lwjgl.opengl.GL;
import ru.windcorp.progressia.client.graphics.GUI;
class LWJGLInitializer {
private LWJGLInitializer() {
}
public static void initialize() {
checkEnvironment();
initializeGLFW();
createWindow();
positionWindow();
createWindowIcons();
initializeOpenGL();
setupWindowCallbacks();
glfwShowWindow(GraphicsBackend.getWindowHandle());
}
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 createWindow() {
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE);
glfwWindowHint(GLFW_FOCUSED, GLFW_TRUE);
glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE);
long handle = glfwCreateWindow(900, 900, "ProgressiaTest", NULL, NULL);
// TODO Check that handle != NULL
GraphicsBackend.setWindowHandle(handle);
glfwSetInputMode(handle, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
glfwMakeContextCurrent(handle);
glfwSwapInterval(0);
}
private static void positionWindow() {
// TODO Auto-generated method stub
}
private static void createWindowIcons() {
// TODO Auto-generated method stub
}
private static void initializeOpenGL() {
GL.createCapabilities();
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
RenderTaskQueue.schedule(OpenGLObjectTracker::deleteEnqueuedObjects);
}
private static void setupWindowCallbacks() {
long handle = GraphicsBackend.getWindowHandle();
glfwSetFramebufferSizeCallback(
handle,
GraphicsBackend::onFrameResized
);
glfwSetKeyCallback(handle, InputHandler::handleKeyInput);
glfwSetMouseButtonCallback(
handle,
InputHandler::handleMouseButtonInput
);
glfwSetCursorPosCallback(handle, InputHandler::handleMouseMoveInput);
glfwSetScrollCallback(handle, InputHandler::handleWheelScroll);
GraphicsInterface.subscribeToInputEvents(GUI.getEventSubscriber());
}
}

View File

@ -1,92 +1,101 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.IntConsumer;
public class OpenGLObjectTracker {
public interface OpenGLDeletable {
int getHandle();
}
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 =
new GLPhantomReference<>(object, DELETE_QUEUE, object.getHandle(), glDeleter);
TO_DELETE.add(glRef);
}
public static void deleteAllObjects() {
for (GLPhantomReference<OpenGLDeletable> glRef
: TO_DELETE
) {
glRef.clear();
}
}
public static void deleteEnqueuedObjects() {
while (true) {
GLPhantomReference<?> glRef;
glRef = (GLPhantomReference<?>) DELETE_QUEUE.poll();
if (glRef == null) {
break;
} else {
glRef.delete();
}
}
}
private static class GLPhantomReference<T> extends PhantomReference<T> {
private final int referentGLhandle;
private final IntConsumer GLDeleter;
/**
* Creates a new phantom reference that refers to the given object and
* is registered with the given queue.
*
* <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,
* it will never be enqueued.
*
* @param referent the object the new phantom reference will refer to
* @param q the queue with which the reference is to be registered,
* or {@code null} if registration is not required
*/
public GLPhantomReference(T referent,
ReferenceQueue<? super T> q,
int referentGLhandle,
IntConsumer GLDeleter) {
super(referent, q);
this.referentGLhandle = referentGLhandle;
this.GLDeleter = GLDeleter;
}
public void delete() {
GLDeleter.accept(referentGLhandle);
}
}
}
/*
* 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;
import java.lang.ref.PhantomReference;
import java.lang.ref.ReferenceQueue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.function.IntConsumer;
public class OpenGLObjectTracker {
public interface OpenGLDeletable {
int getHandle();
}
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 = new GLPhantomReference<>(
object,
DELETE_QUEUE,
object.getHandle(),
glDeleter
);
TO_DELETE.add(glRef);
}
public static void deleteAllObjects() {
for (
GLPhantomReference<OpenGLDeletable> glRef : TO_DELETE
) {
glRef.clear();
}
}
public static void deleteEnqueuedObjects() {
while (true) {
GLPhantomReference<?> glRef;
glRef = (GLPhantomReference<?>) DELETE_QUEUE.poll();
if (glRef == null) {
break;
} else {
glRef.delete();
}
}
}
private static class GLPhantomReference<T> extends PhantomReference<T> {
private final int referentGLhandle;
private final IntConsumer GLDeleter;
/**
* Creates a new phantom reference that refers to the given object and
* is registered with the given queue.
* <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,
* it will never be enqueued.
*
* @param referent the object the new phantom reference will refer to
* @param q the queue with which the reference is to be
* registered,
* or {@code null} if registration is not required
*/
public GLPhantomReference(
T referent,
ReferenceQueue<? super T> q,
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
* Copyright (C) 2020 Wind Corporation
*
* 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;
import ru.windcorp.jputil.functions.ThrowingRunnable;
import ru.windcorp.progressia.common.util.TaskQueue;
public class RenderTaskQueue {
private static final TaskQueue HANDLER =
new TaskQueue(GraphicsInterface::isRenderThread);
public static void schedule(Runnable task) {
HANDLER.schedule(task);
}
public static void removeScheduled(Runnable task) {
HANDLER.removeScheduled(task);
}
public static void invokeLater(Runnable task) {
HANDLER.invokeLater(task);
}
public static void invokeNow(Runnable task) {
HANDLER.invokeNow(task);
}
public static <E extends Exception> void waitAndInvoke(
ThrowingRunnable<E> task
) throws InterruptedException, E {
HANDLER.waitAndInvoke(task);
}
public static void runTasks() {
HANDLER.runTasks();
}
}
/*
* 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;
import ru.windcorp.jputil.functions.ThrowingRunnable;
import ru.windcorp.progressia.common.util.TaskQueue;
public class RenderTaskQueue {
private static final TaskQueue HANDLER = new TaskQueue(GraphicsInterface::isRenderThread);
public static void schedule(Runnable task) {
HANDLER.schedule(task);
}
public static void removeScheduled(Runnable task) {
HANDLER.removeScheduled(task);
}
public static void invokeLater(Runnable task) {
HANDLER.invokeLater(task);
}
public static void invokeNow(Runnable task) {
HANDLER.invokeNow(task);
}
public static <E extends Exception> void waitAndInvoke(
ThrowingRunnable<E> task
)
throws InterruptedException,
E {
HANDLER.waitAndInvoke(task);
}
public static void runTasks() {
HANDLER.runTasks();
}
}

View File

@ -1,79 +1,80 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
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;
class RenderThread extends Thread {
public RenderThread() {
super("Render");
}
@Override
public void run() {
LWJGLInitializer.initialize();
mainLoop();
freeResources();
}
private void mainLoop() {
while (shouldRun()) {
GraphicsBackend.startFrame();
RenderTaskQueue.runTasks();
render();
waitForFrame();
GraphicsBackend.endFrame();
}
System.exit(0);
}
private void render() {
clear();
doRender();
glfwPollEvents();
}
private void clear() {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
private void doRender() {
GUI.render();
AudioManager.update();
}
private void waitForFrame() {
glfwSwapBuffers(GraphicsBackend.getWindowHandle());
}
private void freeResources() {
OpenGLObjectTracker.deleteAllObjects();
}
private boolean shouldRun() {
return !glfwWindowShouldClose(GraphicsBackend.getWindowHandle());
}
}
/*
* 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;
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;
class RenderThread extends Thread {
public RenderThread() {
super("Render");
}
@Override
public void run() {
LWJGLInitializer.initialize();
mainLoop();
freeResources();
}
private void mainLoop() {
while (shouldRun()) {
GraphicsBackend.startFrame();
RenderTaskQueue.runTasks();
render();
waitForFrame();
GraphicsBackend.endFrame();
}
System.exit(0);
}
private void render() {
clear();
doRender();
glfwPollEvents();
}
private void clear() {
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
private void doRender() {
GUI.render();
AudioManager.update();
}
private void waitForFrame() {
glfwSwapBuffers(GraphicsBackend.getWindowHandle());
}
private void freeResources() {
OpenGLObjectTracker.deleteAllObjects();
}
private boolean shouldRun() {
return !glfwWindowShouldClose(GraphicsBackend.getWindowHandle());
}
}

View File

@ -1,38 +1,39 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
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_STREAM_DRAW;
public enum Usage { // TODO add _COPY and _READ, pref. as another enum
STATIC(GL_STATIC_DRAW),
DYNAMIC(GL_DYNAMIC_DRAW),
STREAM(GL_STREAM_DRAW);
private final int glCode;
private Usage(int glCode) {
this.glCode = glCode;
}
public int getGlCode() {
return glCode;
}
}
/*
* 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;
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_STREAM_DRAW;
public enum Usage { // TODO add _COPY and _READ, pref. as another enum
STATIC(GL_STATIC_DRAW),
DYNAMIC(GL_DYNAMIC_DRAW),
STREAM(GL_STREAM_DRAW);
private final int glCode;
private Usage(int glCode) {
this.glCode = glCode;
}
public int getGlCode() {
return glCode;
}
}

View File

@ -1,199 +1,200 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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;
import static org.lwjgl.opengl.GL20.*;
import java.nio.*;
import org.lwjgl.opengl.GL20;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable;
public class VertexBufferObject implements OpenGLDeletable {
public static enum BindTarget {
ARRAY(GL_ARRAY_BUFFER),
ELEMENT_ARRAY(GL_ELEMENT_ARRAY_BUFFER);
private final int glCode;
private BindTarget(int glCode) {
this.glCode = glCode;
}
public int getGlCode() {
return glCode;
}
}
private final int handle;
private long length = 0;
private final Usage usage;
public VertexBufferObject(Usage usage) {
handle = glGenBuffers();
OpenGLObjectTracker.register(this, GL20::glDeleteBuffers);
this.usage = usage;
}
public void setData(ByteBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.remaining();
}
public void setData(double[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.length * Double.BYTES;
}
public void setData(DoubleBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.remaining() * Double.BYTES;
}
public void setData(float[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.length * Float.BYTES;
}
public void setData(FloatBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.remaining() * Float.BYTES;
}
public void setData(int[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.length * Integer.BYTES;
}
public void setData(IntBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.remaining() * Integer.BYTES;
}
public void setData(long[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.length * Long.BYTES;
}
public void setData(LongBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.remaining() * Long.BYTES;
}
public void setData(short[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.length * Short.BYTES;
}
public void setData(ShortBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.remaining() * Short.BYTES;
}
public void initData(long length) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, length, usage.getGlCode());
this.length = length;
}
public void setData(int offset, ByteBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, double[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, DoubleBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, float[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, FloatBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, int[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, IntBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, long[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, LongBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, short[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, ShortBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void bind(BindTarget target) {
glBindBuffer(target.getGlCode(), handle);
}
public long getLength() {
return length;
}
public Usage getUsage() {
return usage;
}
@Override
public int getHandle() {
return handle;
}
}
/*
* 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;
import static org.lwjgl.opengl.GL20.*;
import java.nio.*;
import org.lwjgl.opengl.GL20;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable;
public class VertexBufferObject implements OpenGLDeletable {
public static enum BindTarget {
ARRAY(GL_ARRAY_BUFFER),
ELEMENT_ARRAY(GL_ELEMENT_ARRAY_BUFFER);
private final int glCode;
private BindTarget(int glCode) {
this.glCode = glCode;
}
public int getGlCode() {
return glCode;
}
}
private final int handle;
private long length = 0;
private final Usage usage;
public VertexBufferObject(Usage usage) {
handle = glGenBuffers();
OpenGLObjectTracker.register(this, GL20::glDeleteBuffers);
this.usage = usage;
}
public void setData(ByteBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.remaining();
}
public void setData(double[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.length * Double.BYTES;
}
public void setData(DoubleBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.remaining() * Double.BYTES;
}
public void setData(float[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.length * Float.BYTES;
}
public void setData(FloatBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.remaining() * Float.BYTES;
}
public void setData(int[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.length * Integer.BYTES;
}
public void setData(IntBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.remaining() * Integer.BYTES;
}
public void setData(long[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.length * Long.BYTES;
}
public void setData(LongBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.remaining() * Long.BYTES;
}
public void setData(short[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.length * Short.BYTES;
}
public void setData(ShortBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, data, usage.getGlCode());
length = data.remaining() * Short.BYTES;
}
public void initData(long length) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferData(GL_ARRAY_BUFFER, length, usage.getGlCode());
this.length = length;
}
public void setData(int offset, ByteBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, double[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, DoubleBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, float[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, FloatBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, int[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, IntBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, long[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, LongBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, short[] data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void setData(int offset, ShortBuffer data) {
glBindBuffer(GL_ARRAY_BUFFER, handle);
glBufferSubData(GL_ARRAY_BUFFER, offset, data);
}
public void bind(BindTarget target) {
glBindBuffer(target.getGlCode(), handle);
}
public long getLength() {
return length;
}
public Usage getUsage() {
return usage;
}
@Override
public int getHandle() {
return handle;
}
}

View File

@ -1,93 +1,95 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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.shaders;
import ru.windcorp.progressia.common.resource.Resource;
public class CombinedShader extends Shader {
public CombinedShader(String... resources) {
super(getTypeOf(resources), combine(resources));
}
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) {
throw new IllegalArgumentException(
"Deduced shader types of "
+ resources[0]
+ " and "
+ resources[i]
+ " differ"
);
}
}
return first;
}
private static String combine(String[] resources) {
StringBuilder accumulator = new StringBuilder("#version 120\n");
for (String resourceName : resources) {
Resource resource = getShaderResource(resourceName);
accumulator.append("\n// START " + resourceName);
accumulator.append(stripVersionAnnotations(resource));
accumulator.append('\n');
}
return accumulator.toString();
}
private static String stripVersionAnnotations(Resource resource) {
String contents = resource.readAsString();
int versionIndex;
for (versionIndex = 0; versionIndex < contents.length(); ++versionIndex)
{
if (!Character.isWhitespace(contents.codePointAt(versionIndex)))
break;
}
if (versionIndex < contents.length()) {
if (contents.codePointAt(versionIndex) == '#') {
final String versionAnnotation = "#version ";
if (contents.regionMatches(
versionIndex,
versionAnnotation,
0,
versionAnnotation.length()
)) {
contents = contents.substring(
versionIndex
+ versionAnnotation.length()
+ "120".length()
);
}
}
}
return contents;
}
}
/*
* 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.shaders;
import ru.windcorp.progressia.common.resource.Resource;
public class CombinedShader extends Shader {
public CombinedShader(String... resources) {
super(getTypeOf(resources), combine(resources));
}
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) {
throw new IllegalArgumentException(
"Deduced shader types of "
+ resources[0]
+ " and "
+ resources[i]
+ " differ"
);
}
}
return first;
}
private static String combine(String[] resources) {
StringBuilder accumulator = new StringBuilder("#version 120\n");
for (String resourceName : resources) {
Resource resource = getShaderResource(resourceName);
accumulator.append("\n// START " + resourceName);
accumulator.append(stripVersionAnnotations(resource));
accumulator.append('\n');
}
return accumulator.toString();
}
private static String stripVersionAnnotations(Resource resource) {
String contents = resource.readAsString();
int versionIndex;
for (versionIndex = 0; versionIndex < contents.length(); ++versionIndex) {
if (!Character.isWhitespace(contents.codePointAt(versionIndex)))
break;
}
if (versionIndex < contents.length()) {
if (contents.codePointAt(versionIndex) == '#') {
final String versionAnnotation = "#version ";
if (
contents.regionMatches(
versionIndex,
versionAnnotation,
0,
versionAnnotation.length()
)
) {
contents = contents.substring(
versionIndex
+ versionAnnotation.length()
+ "120".length()
);
}
}
}
return contents;
}
}

View File

@ -1,63 +1,66 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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.shaders;
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 ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable;
import ru.windcorp.progressia.client.graphics.backend.shaders.attributes.Attribute;
import ru.windcorp.progressia.client.graphics.backend.shaders.uniforms.Uniform;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Program implements OpenGLDeletable {
private int handle;
public Program(Shader vertexShader, Shader fragmentShader) {
handle = glCreateProgram();
OpenGLObjectTracker.register(this, GL20::glDeleteProgram);
glAttachShader(handle, vertexShader.getHandle());
glAttachShader(handle, fragmentShader.getHandle());
glLinkProgram(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 Uniform getUniform(String name) {
return new Uniform(glGetUniformLocation(handle, name), this);
}
public void use() {
glUseProgram(handle);
}
@Override
public int getHandle() { return handle; }
}
/*
* 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.shaders;
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 ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable;
import ru.windcorp.progressia.client.graphics.backend.shaders.attributes.Attribute;
import ru.windcorp.progressia.client.graphics.backend.shaders.uniforms.Uniform;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Program implements OpenGLDeletable {
private int handle;
public Program(Shader vertexShader, Shader fragmentShader) {
handle = glCreateProgram();
OpenGLObjectTracker.register(this, GL20::glDeleteProgram);
glAttachShader(handle, vertexShader.getHandle());
glAttachShader(handle, fragmentShader.getHandle());
glLinkProgram(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 Uniform getUniform(String name) {
return new Uniform(glGetUniformLocation(handle, name), this);
}
public void use() {
glUseProgram(handle);
}
@Override
public int getHandle() {
return handle;
}
}

View File

@ -1,103 +1,108 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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.shaders;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import java.util.Locale;
import org.lwjgl.opengl.GL20;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable;
import ru.windcorp.progressia.common.resource.Resource;
import ru.windcorp.progressia.common.resource.ResourceManager;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Shader implements OpenGLDeletable {
public static enum ShaderType {
VERTEX(GL_VERTEX_SHADER), FRAGMENT(GL_FRAGMENT_SHADER);
private final int glCode;
private ShaderType(int glCode) {
this.glCode = glCode;
}
public int getGlCode() {
return glCode;
}
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("vsh")) return VERTEX;
if (resource.contains("fsh")) return FRAGMENT;
throw new IllegalArgumentException(
"Cannot deduce shader type from resource name \"" +
resource + "\""
);
}
}
private static final String SHADER_ASSETS_PREFIX = "assets/shaders/";
protected static Resource getShaderResource(String name) {
return ResourceManager.getResource(SHADER_ASSETS_PREFIX + name);
}
private final int handle;
private final ShaderType type;
public Shader(ShaderType type, String source) {
handle = glCreateShader(type.getGlCode());
OpenGLObjectTracker.register(this, GL20::glDeleteShader);
this.type = type;
glShaderSource(handle, source);
glCompileShader(handle);
if (glGetShaderi(handle, GL_COMPILE_STATUS) == GL_FALSE) {
System.out.println("***************** ERROR ******************");
System.out.println(source);
throw CrashReports.report(null, "Bad shader:\n %s", glGetShaderInfoLog(handle));
}
}
public Shader(String resource) {
this(
ShaderType.guessByResourceName(resource),
getShaderResource(resource).readAsString()
);
}
@Override
public int getHandle() {
return handle;
}
public ShaderType getType() {
return type;
}
}
/*
* 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.shaders;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import java.util.Locale;
import org.lwjgl.opengl.GL20;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker;
import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGLDeletable;
import ru.windcorp.progressia.common.resource.Resource;
import ru.windcorp.progressia.common.resource.ResourceManager;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Shader implements OpenGLDeletable {
public static enum ShaderType {
VERTEX(GL_VERTEX_SHADER), FRAGMENT(GL_FRAGMENT_SHADER);
private final int glCode;
private ShaderType(int glCode) {
this.glCode = glCode;
}
public int getGlCode() {
return glCode;
}
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("vsh"))
return VERTEX;
if (resource.contains("fsh"))
return FRAGMENT;
throw new IllegalArgumentException(
"Cannot deduce shader type from resource name \"" +
resource + "\""
);
}
}
private static final String SHADER_ASSETS_PREFIX = "assets/shaders/";
protected static Resource getShaderResource(String name) {
return ResourceManager.getResource(SHADER_ASSETS_PREFIX + name);
}
private final int handle;
private final ShaderType type;
public Shader(ShaderType type, String source) {
handle = glCreateShader(type.getGlCode());
OpenGLObjectTracker.register(this, GL20::glDeleteShader);
this.type = type;
glShaderSource(handle, source);
glCompileShader(handle);
if (glGetShaderi(handle, GL_COMPILE_STATUS) == GL_FALSE) {
System.out.println("***************** ERROR ******************");
System.out.println(source);
throw CrashReports.report(null, "Bad shader:\n %s", glGetShaderInfoLog(handle));
}
}
public Shader(String resource) {
this(
ShaderType.guessByResourceName(resource),
getShaderResource(resource).readAsString()
);
}
@Override
public int getHandle() {
return handle;
}
public ShaderType getType() {
return type;
}
}

View File

@ -1,49 +1,50 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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.shaders.attributes;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Attribute {
protected final int handle;
private final Program program;
public Attribute(int handle, Program program) {
if (handle < 0) {
throw CrashReports.report(null, "Bad handle: %d", handle);
}
this.handle = handle;
this.program = program;
}
public int getHandle() {
return handle;
}
public Program getProgram() {
return program;
}
public AttributeVertexArray asVertexArray() {
return new AttributeVertexArray(handle, program);
}
}
/*
* 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.shaders.attributes;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Attribute {
protected final int handle;
private final Program program;
public Attribute(int handle, Program program) {
if (handle < 0) {
throw CrashReports.report(null, "Bad handle: %d", handle);
}
this.handle = handle;
this.program = program;
}
public int getHandle() {
return handle;
}
public Program getProgram() {
return program;
}
public AttributeVertexArray asVertexArray() {
return new AttributeVertexArray(handle, program);
}
}

View File

@ -1,114 +1,154 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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.shaders.attributes;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
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;
public class AttributeVertexArray extends Attribute {
private boolean isEnabled = false;
public AttributeVertexArray(int handle, Program program) {
super(handle, program);
}
public void enable() {
if (!isEnabled) {
glEnableVertexAttribArray(handle);
isEnabled = true;
}
}
public void disable() {
if (isEnabled) {
glDisableVertexAttribArray(handle);
isEnabled = false;
}
}
public void set(
int size, boolean normalized, int stride,
ByteBuffer pointer
) {
glVertexAttribPointer(
handle,
size, GL_BYTE, normalized, stride, pointer
);
}
public void set(
int size, boolean normalized, int stride,
FloatBuffer pointer
) {
glVertexAttribPointer(
handle,
size, GL_FLOAT, normalized, stride, pointer
);
}
public void set(
int size, boolean normalized, int stride,
IntBuffer pointer
) {
glVertexAttribPointer(
handle,
size, GL_INT, normalized, stride, pointer
);
}
public void set(
int size, boolean normalized, int stride,
ShortBuffer pointer
) {
glVertexAttribPointer(
handle,
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
);
}
}
/*
* 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.shaders.attributes;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL20.*;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
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;
public class AttributeVertexArray extends Attribute {
private boolean isEnabled = false;
public AttributeVertexArray(int handle, Program program) {
super(handle, program);
}
public void enable() {
if (!isEnabled) {
glEnableVertexAttribArray(handle);
isEnabled = true;
}
}
public void disable() {
if (isEnabled) {
glDisableVertexAttribArray(handle);
isEnabled = false;
}
}
public void set(
int size,
boolean normalized,
int stride,
ByteBuffer pointer
) {
glVertexAttribPointer(
handle,
size,
GL_BYTE,
normalized,
stride,
pointer
);
}
public void set(
int size,
boolean normalized,
int stride,
FloatBuffer pointer
) {
glVertexAttribPointer(
handle,
size,
GL_FLOAT,
normalized,
stride,
pointer
);
}
public void set(
int size,
boolean normalized,
int stride,
IntBuffer pointer
) {
glVertexAttribPointer(
handle,
size,
GL_INT,
normalized,
stride,
pointer
);
}
public void set(
int size,
boolean normalized,
int stride,
ShortBuffer pointer
) {
glVertexAttribPointer(
handle,
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
* Copyright (C) 2020 Wind Corporation
*
* 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.shaders.uniforms;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Uniform {
protected final int handle;
private final Program program;
public Uniform(int handle, Program program) {
if (handle < 0) {
throw CrashReports.report(null, "Bad handle: %d", handle);
}
this.handle = handle;
this.program = program;
}
public int getHandle() {
return handle;
}
public Program getProgram() {
return program;
}
public Uniform1Float as1Float() {
return new Uniform1Float(handle, program);
}
public Uniform1Int as1Int() {
return new Uniform1Int(handle, program);
}
public Uniform2Float as2Float() {
return new Uniform2Float(handle, program);
}
public Uniform2Int as2Int() {
return new Uniform2Int(handle, program);
}
public Uniform3Float as3Float() {
return new Uniform3Float(handle, program);
}
public Uniform3Int as3Int() {
return new Uniform3Int(handle, program);
}
public Uniform4Float as4Float() {
return new Uniform4Float(handle, program);
}
public Uniform4Int as4Int() {
return new Uniform4Int(handle, program);
}
public Uniform2Matrix as2Matrix() {
return new Uniform2Matrix(handle, program);
}
public Uniform3Matrix as3Matrix() {
return new Uniform3Matrix(handle, program);
}
public Uniform4Matrix as4Matrix() {
return new Uniform4Matrix(handle, program);
}
}
/*
* 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.shaders.uniforms;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
import ru.windcorp.progressia.common.util.crash.CrashReports;
public class Uniform {
protected final int handle;
private final Program program;
public Uniform(int handle, Program program) {
if (handle < 0) {
throw CrashReports.report(null, "Bad handle: %d", handle);
}
this.handle = handle;
this.program = program;
}
public int getHandle() {
return handle;
}
public Program getProgram() {
return program;
}
public Uniform1Float as1Float() {
return new Uniform1Float(handle, program);
}
public Uniform1Int as1Int() {
return new Uniform1Int(handle, program);
}
public Uniform2Float as2Float() {
return new Uniform2Float(handle, program);
}
public Uniform2Int as2Int() {
return new Uniform2Int(handle, program);
}
public Uniform3Float as3Float() {
return new Uniform3Float(handle, program);
}
public Uniform3Int as3Int() {
return new Uniform3Int(handle, program);
}
public Uniform4Float as4Float() {
return new Uniform4Float(handle, program);
}
public Uniform4Int as4Int() {
return new Uniform4Int(handle, program);
}
public Uniform2Matrix as2Matrix() {
return new Uniform2Matrix(handle, program);
}
public Uniform3Matrix as3Matrix() {
return new Uniform3Matrix(handle, program);
}
public Uniform4Matrix as4Matrix() {
return new Uniform4Matrix(handle, program);
}
}

View File

@ -1,43 +1,44 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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.shaders.uniforms;
import static org.lwjgl.opengl.GL20.*;
import java.nio.FloatBuffer;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
public class Uniform1Float extends Uniform {
public Uniform1Float(int handle, Program program) {
super(handle, program);
}
public void set(float value) {
glUniform1f(handle, value);
}
public void set(float[] value) {
glUniform1fv(handle, value);
}
public void set(FloatBuffer value) {
glUniform1fv(handle, value);
}
}
/*
* 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.shaders.uniforms;
import static org.lwjgl.opengl.GL20.*;
import java.nio.FloatBuffer;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
public class Uniform1Float extends Uniform {
public Uniform1Float(int handle, Program program) {
super(handle, program);
}
public void set(float value) {
glUniform1f(handle, value);
}
public void set(float[] value) {
glUniform1fv(handle, value);
}
public void set(FloatBuffer value) {
glUniform1fv(handle, value);
}
}

View File

@ -1,43 +1,44 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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.shaders.uniforms;
import static org.lwjgl.opengl.GL20.*;
import java.nio.IntBuffer;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
public class Uniform1Int extends Uniform {
public Uniform1Int(int handle, Program program) {
super(handle, program);
}
public void set(int value) {
glUniform1i(handle, value);
}
public void set(int[] value) {
glUniform1iv(handle, value);
}
public void set(IntBuffer value) {
glUniform1iv(handle, value);
}
}
/*
* 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.shaders.uniforms;
import static org.lwjgl.opengl.GL20.*;
import java.nio.IntBuffer;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
public class Uniform1Int extends Uniform {
public Uniform1Int(int handle, Program program) {
super(handle, program);
}
public void set(int value) {
glUniform1i(handle, value);
}
public void set(int[] value) {
glUniform1iv(handle, value);
}
public void set(IntBuffer value) {
glUniform1iv(handle, value);
}
}

View File

@ -1,48 +1,49 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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.shaders.uniforms;
import static org.lwjgl.opengl.GL20.*;
import java.nio.FloatBuffer;
import glm.vec._2.Vec2;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
public class Uniform2Float extends Uniform {
public Uniform2Float(int handle, Program program) {
super(handle, program);
}
public void set(float x, float y) {
glUniform2f(handle, x, y);
}
public void set(float[] value) {
glUniform2fv(handle, value);
}
public void set(FloatBuffer value) {
glUniform2fv(handle, value);
}
public void set(Vec2 value) {
glUniform2f(handle, value.x, value.y);
}
}
/*
* 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.shaders.uniforms;
import static org.lwjgl.opengl.GL20.*;
import java.nio.FloatBuffer;
import glm.vec._2.Vec2;
import ru.windcorp.progressia.client.graphics.backend.shaders.Program;
public class Uniform2Float extends Uniform {
public Uniform2Float(int handle, Program program) {
super(handle, program);
}
public void set(float x, float y) {
glUniform2f(handle, x, y);
}
public void set(float[] value) {
glUniform2fv(handle, value);
}
public void set(FloatBuffer value) {
glUniform2fv(handle, value);
}
public void set(Vec2 value) {
glUniform2f(handle, value.x, value.y);
}
}

View File

@ -1,48 +1,49 @@
/*******************************************************************************
* Progressia
* Copyright (C) 2020 Wind Corporation
*
* 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.shaders.uniforms;
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;
public class Uniform2Int extends Uniform {
public Uniform2Int(int handle, Program program) {
super(handle, program);
}
public void set(int x, int y) {
glUniform2i(handle, x, y);
}
public void set(int[] value) {
glUniform2iv(handle, value);
}
public void set(IntBuffer value) {
glUniform2iv(handle, value);
}
public void set(Vec2i value) {
glUniform2i(handle, value.x, value.y);
}
}
/*
* 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.shaders.uniforms;
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;
public class Uniform2Int extends Uniform {
public Uniform2Int(int handle, Program program) {
super(handle, program);
}
public void set(int x, int y) {
glUniform2i(handle, x, y);
}
public void set(int[] value) {
glUniform2iv(handle, value);
}
public void set(IntBuffer value) {
glUniform2iv(handle, value);
}
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