Skip to content

Commit

Permalink
Preventing pending effect flows
Browse files Browse the repository at this point in the history
- #28
  • Loading branch information
truj committed Mar 1, 2024
1 parent 588f3cb commit 83d2c86
Show file tree
Hide file tree
Showing 17 changed files with 142 additions and 21 deletions.
Binary file modified midica.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion src/org/midica/Midica.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class Midica {
private static final int VERSION_MINOR = 11;

/** UNIX timestamp of the last commit */
public static final int COMMIT_TIME = 1708970595;
public static final int COMMIT_TIME = 1709317508;

/** Branch name. Automatically changed by precommit.pl */
public static final String BRANCH = "sound-effects";
Expand Down
2 changes: 2 additions & 0 deletions src/org/midica/config/Dict.java
Original file line number Diff line number Diff line change
Expand Up @@ -1761,6 +1761,7 @@ public class Dict {
public static final String ERROR_FL_NOTE_NOT_SET = "error_fl_note_not_set";
public static final String ERROR_FL_NOTE_PAT_IDX_NAN = "error_fl_note_pat_idx_nan";
public static final String ERROR_FL_NOTE_PAT_IDX_TOO_HIGH = "error_fl_note_pat_idx_too_high";
public static final String ERROR_FL_PENDING = "error_fl_pending";
public static final String ERROR_FUNC_NOT_SUPPORTED_BY_EFF = "error_func_not_supported_by_eff";
public static final String ERROR_FUNC_VAL_LOWER_MIN = "error_func_val_lower_min";
public static final String ERROR_FUNC_VAL_GREATER_MAX = "error_func_val_greater_max";
Expand Down Expand Up @@ -3587,6 +3588,7 @@ private static void initLanguageEnglish() {
set( ERROR_FL_NOTE_NOT_SET, "The chosen effect needs a note to be set before you can use this function: " );
set( ERROR_FL_NOTE_PAT_IDX_NAN, "pattern index '%s' is not a number in this element: %s" );
set( ERROR_FL_NOTE_PAT_IDX_TOO_HIGH, "pattern index '%s' too high in this element: %s" );
set( ERROR_FL_PENDING, "Pending effect flow found before this line.<br>Delete the useless parts of the flow." );
set( ERROR_FUNC_NOT_SUPPORTED_BY_EFF, "The chosen effect does not support this function: " );
set( ERROR_FUNC_VAL_LOWER_MIN, "Parameter '%s' is smaller than the minimum value (%s)" );
set( ERROR_FUNC_VAL_GREATER_MAX, "Parameter '%s' is greater than the maximum value (%s)" );
Expand Down
27 changes: 26 additions & 1 deletion src/org/midica/file/read/Effect.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ public class Effect {
*/
public static void init(MidicaPLParser rootParser) {
parser = rootParser;
flow = null;

// create and initialize special structures
{
Expand Down Expand Up @@ -434,8 +435,29 @@ else if (numberStr != null) {

/**
* Closes the current flow, if there is an open flow.
*
* @throws ParseException if the current flow is pending.
*/
public static void closeFlowIfPossible() throws ParseException {

// check if there is a pending flow
if (flow != null && flow.isPending()) {
throw new ParseException(Dict.get(Dict.ERROR_FL_PENDING));
}

flow = null;
}

/**
* Closes the current flow, if there is an open flow.
*
* Does **not** check if the flow is pending or not.
*
* Called after all parsing runs are finished, no matter if an exception is thrown or not.
*
* Does **not** throw a further exception.
*/
public static void closeFlowIfPossible() {
public static void closeFlowAfterParsingFinished() {
flow = null;
}

Expand Down Expand Up @@ -546,6 +568,8 @@ private static int parseGenericNumber(String numberStr, String numberLsb, int ma
*/
private static void applyFlowElement(String elemName, int number, String paramStr) throws ParseException {

flow.setPending(true);

// check presence of params
if (functionNames.contains(elemName)) {
if (paramStr == null && ! MidicaPLParser.FUNC_WAIT.equals(elemName))
Expand Down Expand Up @@ -707,6 +731,7 @@ private static void applyFunction(String funcName, String[] params) throws Parse

// for all other functions we need the effect type
int valueType = flow.getValueType(funcName);
flow.setPending(false);

// note required but not set?
if (flow.needsNote() && flow.getNote() < 0)
Expand Down
27 changes: 27 additions & 0 deletions src/org/midica/file/read/EffectFlow.java
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ public class EffectFlow {
private long ticksPerAction;
private int effectType = 0;
private int effectNumber = -1;
private boolean isPending = true;
private boolean isDouble = false;
private int note = -1;

Expand Down Expand Up @@ -157,6 +158,32 @@ public int getEffectNumber() {
return effectNumber;
}

/**
* Marks the flow as pending or not pending.
*
* "Pending" means that the last called function was something like length(), wait(), note(), src(), dest() etc.
*
* "Not pending" means that the last called function was something like set(), on(), off(), line(), sin(), etc.
*
* @param isPending **true** for pending, **false** for not pending
*/
public void setPending(boolean isPending) {
this.isPending = isPending;
}

/**
* Indicates if the flow is pending.
*
* "Pending" means that the last called function was something like length(), wait(), note(), src(), dest() etc.
*
* "Not pending" means that the last called function was something like set(), on(), off(), line(), sin(), etc.
*
* @return **true** if the flow is pending, otherwise: **false**.
*/
public boolean isPending() {
return isPending;
}

/**
* Return all functions that are supported by the current effect type.
*
Expand Down
9 changes: 9 additions & 0 deletions src/org/midica/file/read/MidicaPLParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -717,6 +717,12 @@ public void parse(Object fileAsObj) throws ParseException {
e.printStackTrace();
throw new ParseException(e.toString());
}
finally {
// Close the flow.
// Avoids problems in the NEXT parsing attempt.
if (isRootParser)
Effect.closeFlowAfterParsingFinished();
}

// allow an empty sequence?
if (isRootParser) {
Expand Down Expand Up @@ -1017,6 +1023,9 @@ private void parsingRun(ArrayList<String> lines) throws ParseException, IOExcept
// In case of wrong block nesting make sure that the correct
// error message and line number is shown
nestableBlkDepth = 0;

// check if a pending flow was the last command
Effect.closeFlowIfPossible();
}
catch (ParseException e) {
// Add file name and line number to exception and throw it again
Expand Down
32 changes: 26 additions & 6 deletions test/org/midica/file/read/MidicaPLParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4116,32 +4116,32 @@ void testParseFilesFailing() {

e = assertThrows( ParseException.class, () -> parse(getFailingFile("eff-flow-broken-by-var")) );
assertEquals( 6, e.getLineNumber() );
assertEquals( "0: .set(50)", e.getLineContent() );
assertEquals( "0: .wait.set(50)", e.getLineContent() );
assertTrue( e.getMessage().startsWith(String.format(Dict.get(Dict.ERROR_FL_NOT_OPEN), ".")));

e = assertThrows( ParseException.class, () -> parse(getFailingFile("eff-flow-broken-by-const")) );
assertEquals( 6, e.getLineNumber() );
assertEquals( "0: .set(50)", e.getLineContent() );
assertEquals( "0: .wait.set(50)", e.getLineContent() );
assertTrue( e.getMessage().startsWith(String.format(Dict.get(Dict.ERROR_FL_NOT_OPEN), ".")));

e = assertThrows( ParseException.class, () -> parse(getFailingFile("eff-flow-broken-by-call")) );
assertEquals( 6, e.getLineNumber() );
assertEquals( "0: .set(50)", e.getLineContent() );
assertEquals( "0: .wait.set(50)", e.getLineContent() );
assertTrue( e.getMessage().startsWith(String.format(Dict.get(Dict.ERROR_FL_NOT_OPEN), ".")));

e = assertThrows( ParseException.class, () -> parse(getFailingFile("eff-flow-broken-by-function")) );
assertEquals( 7, e.getLineNumber() );
assertEquals( "0: .set(50)", e.getLineContent() );
assertEquals( "0: .wait.set(50)", e.getLineContent() );
assertTrue( e.getMessage().startsWith(String.format(Dict.get(Dict.ERROR_FL_NOT_OPEN), ".")));

e = assertThrows( ParseException.class, () -> parse(getFailingFile("eff-flow-broken-by-note")) );
assertEquals( 6, e.getLineNumber() );
assertEquals( "0: .set(50)", e.getLineContent() );
assertEquals( "0: .wait.set(50)", e.getLineContent() );
assertTrue( e.getMessage().startsWith(String.format(Dict.get(Dict.ERROR_FL_NOT_OPEN), ".")));

e = assertThrows( ParseException.class, () -> parse(getFailingFile("eff-flow-broken-by-other-channel")) );
assertEquals( 6, e.getLineNumber() );
assertEquals( "0: .set(50)", e.getLineContent() );
assertEquals( "0: .wait.set(50)", e.getLineContent() );
assertTrue( e.getMessage().startsWith(String.format(Dict.get(Dict.ERROR_FL_NOT_OPEN), ".")));

e = assertThrows( ParseException.class, () -> parse(getFailingFile("eff-flow-missing-dot-1")) );
Expand Down Expand Up @@ -4658,6 +4658,26 @@ void testParseFilesFailing() {
assertEquals( 4, e.getLineNumber() );
assertEquals( "0: mono_mode.set(+5)", e.getLineContent() );
assertTrue( e.getMessage().startsWith(Dict.get(Dict.ERROR_FUNC_SIGNED_FORBIDDEN) + "+5"));

e = assertThrows( ParseException.class, () -> parse(getFailingFile("eff-flow-pending-1")) );
assertEquals( 5, e.getLineNumber() );
assertEquals( "1: c", e.getLineContent() );
assertTrue( e.getMessage().startsWith(Dict.get(Dict.ERROR_FL_PENDING)));

e = assertThrows( ParseException.class, () -> parse(getFailingFile("eff-flow-pending-2")) );
assertEquals( 5, e.getLineNumber() );
assertEquals( "0: hold.wait", e.getLineContent() );
assertTrue( e.getMessage().startsWith(Dict.get(Dict.ERROR_FL_PENDING)));

e = assertThrows( ParseException.class, () -> parse(getFailingFile("eff-flow-pending-3")) );
assertEquals( 6, e.getLineNumber() );
assertEquals( "", e.getLineContent() );
assertTrue( e.getMessage().startsWith(Dict.get(Dict.ERROR_FL_PENDING)));

e = assertThrows( ParseException.class, () -> parse(getFailingFile("eff-flow-pending-4")) );
assertEquals( 23, e.getLineNumber() );
assertEquals( "0: c", e.getLineContent() );
assertTrue( e.getMessage().startsWith(Dict.get(Dict.ERROR_FL_PENDING)));
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
INCLUDE inc/instruments.midica


0: vol.wait()
0: vol.wait().set(50)
CALL func
0: .set(50)
0: .wait.set(50)

FUNCTION func
END
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
INCLUDE inc/instruments.midica


0: vol.wait()
0: vol.wait().set(50)
CONST $x = y
0: .set(50)
0: .wait.set(50)

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
INCLUDE inc/instruments.midica


0: vol.wait()
0: vol.wait().set(50)
FUNCTION func
END
0: .set(50)
0: .wait.set(50)

CALL func
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
INCLUDE inc/instruments.midica


0: vol.wait()
0: vol.wait().set(50)
0: c
0: .set(50)
0: .wait.set(50)

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
INCLUDE inc/instruments.midica


0: vol.wait()
1: balance.wait()
0: .set(50)
0: vol.wait().set(50)
1: balance.wait().set(+50)
0: .wait.set(50)

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
INCLUDE inc/instruments.midica


0: vol.double
0: vol.double.set(50)
VAR $x = y
0: .set(50)
0: .wait.set(50)

5 changes: 5 additions & 0 deletions test/org/midica/testfiles/failing/eff-flow-pending-1.midica
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
INCLUDE inc/instruments.midica


0: vol.wait
1: c
4 changes: 4 additions & 0 deletions test/org/midica/testfiles/failing/eff-flow-pending-2.midica
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
INCLUDE inc/instruments.midica


0: hold.wait
5 changes: 5 additions & 0 deletions test/org/midica/testfiles/failing/eff-flow-pending-3.midica
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
INCLUDE inc/instruments.midica


0: hold.wait

24 changes: 24 additions & 0 deletions test/org/midica/testfiles/failing/eff-flow-pending-4.midica
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
INCLUDE inc/instruments.midica



FUNCTION func
{
{
0: hold.wait

0: c

}
}
END

{
{

CALL func
0: a

}
}

0 comments on commit 83d2c86

Please sign in to comment.