Skip to content

Commit

Permalink
Merge pull request #89 from jbunke/0_4_2-dev-branch
Browse files Browse the repository at this point in the history
v0.4.2
  • Loading branch information
jbunke authored May 25, 2024
2 parents 27e9f9c + 56d0ce6 commit e398ea2
Show file tree
Hide file tree
Showing 101 changed files with 1,798 additions and 812 deletions.
31 changes: 31 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
# Changelog

## **0.4.2** - 2024-05-26

### Added:
* Color scripts that encounter errors now display their errors

### Changed:
* Color action previews (HSV level shift, color script execution) now show transparency checkerboard behind previewed image

### API Changes:
**Note: This update completely redesigned the API and altered the syntax of every API function. Scripts that utilize API functions that were written for versions 0.4.0 or 0.4.1 will need to be rewritten in order to execute on subsequent versions of Stipple Effect.**

* Added:
* `palette` type
* Global namespace `$SE`
* `project` color action functions:
* ```js
P.palettize(palette pal, int scope, bool include_disabled);
```
* ```js
P.extract_to_pal(palette pal, int scope, bool include_disabled);
```
* ```js
P.hsv_shift(int scope, bool include_disabled, int h_shift, float s_shift, float v_shift);
```
* ```js
P.color_script(int scope, bool include_disabled, string script_path);
```
* Changed:
* Renamed `set_frame_content` to `set_frame`
* Renamed `get_frame_content` to `get_frame`

## **0.4.1** - 2024-05-22

### Changed:
Expand Down
28 changes: 28 additions & 0 deletions res/blurbs/__changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
{0.4.2} - 2024-05-26

Added:
> Color scripts that encounter errors now display their errors

Changed:
> Color action previews (HSV level shift, color script execution) now show transparency checkerboard
behind previewed image

API Changes:
{Note:}
This update completely redesigned the API and altered the syntax of every API function.
Scripts that utilize API functions that were written for versions 0.4.0 or 0.4.1 will need
to be rewritten in order to execute on subsequent versions of Stipple Effect.

Added:
> {palette} type
> Global namespace {$SE}
> {project} color action functions:
> P.{palettize}(palette pal, int scope, bool include_disabled);
> P.{extract_to_pal}(palette pal, int scope, bool include_disabled);
> P.{hsv_shift}(int scope, bool include_disabled, int h_shift, float s_shift, float v_shift);
> P.{color_script}(int scope, bool include_disabled, string script_path);

Changed:
> Renamed {set_frame_content} to {set_frame}
> Renamed {get_frame_content} to {get_frame}

{0.4.1} - 2024-05-22

Changed:
Expand Down
2 changes: 1 addition & 1 deletion res/program
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name:{Stipple Effect}
version:{0.4.1}
version:{0.4.2}
devbuild:{false}
native_standard:{1.1}
palette_standard:{1.0}
2 changes: 1 addition & 1 deletion src/com/jordanbunke/stipple_effect/layer/SELayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,7 @@ public SELayer returnAddedFrame(
public SELayer returnDuplicatedFrame(final int fromIndex) {
final List<GameImage> frames = new ArrayList<>(this.frames);

frames.add(fromIndex + 1, frames.get(fromIndex));
frames.add(fromIndex + 1, new GameImage(frames.get(fromIndex)));

return new SELayer(frames, frameLinkedContent, opacity, enabled,
framesLinked, onionSkinMode, name);
Expand Down
92 changes: 48 additions & 44 deletions src/com/jordanbunke/stipple_effect/project/SEContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -1143,57 +1143,61 @@ public ProjectState runColorAlgorithm(

final Map<Color, Color> map = new HashMap<>();

return switch (scope) {
case SELECTION -> runCAOnSelection(internal, map);
case LAYER_FRAME -> runCAOnFrame(internal, map, state,
state.getFrameIndex(), state.getLayerEditIndex());
case LAYER -> {
if (state.getEditingLayer().areFramesLinked()) {
yield runCAOnFrame(internal, map, state,
state.getFrameIndex(),
state.getLayerEditIndex());
} else {
final int frameCount = state.getFrameCount();
try {
return switch (scope) {
case SELECTION -> runCAOnSelection(internal, map);
case LAYER_FRAME -> runCAOnFrame(internal, map, state,
state.getFrameIndex(), state.getLayerEditIndex());
case LAYER -> {
if (state.getEditingLayer().areFramesLinked()) {
yield runCAOnFrame(internal, map, state,
state.getFrameIndex(),
state.getLayerEditIndex());
} else {
final int frameCount = state.getFrameCount();

for (int i = 0; i < frameCount; i++)
state = runCAOnFrame(internal, map, state,
i, state.getLayerEditIndex());
for (int i = 0; i < frameCount; i++)
state = runCAOnFrame(internal, map, state,
i, state.getLayerEditIndex());

yield state;
yield state;
}
}
}
case FRAME -> {
final int layerCount = state.getLayers().size();
case FRAME -> {
final int layerCount = state.getLayers().size();

for (int i = 0; i < layerCount; i++)
if (includeDisabledLayers ||
state.getLayers().get(i).isEnabled())
state = runCAOnFrame(internal, map, state,
state.getFrameIndex(), i);

yield state;
}
case PROJECT -> {
final int frameCount = state.getFrameCount(),
layerCount = state.getLayers().size();

for (int l = 0; l < layerCount; l++) {
if (!(includeDisabledLayers ||
state.getLayers().get(l).isEnabled()))
continue;
for (int i = 0; i < layerCount; i++)
if (includeDisabledLayers ||
state.getLayers().get(i).isEnabled())
state = runCAOnFrame(internal, map, state,
state.getFrameIndex(), i);

if (state.getLayers().get(l).areFramesLinked()) {
state = runCAOnFrame(internal, map, state,
state.getFrameIndex(), l);
} else {
for (int f = 0; f < frameCount; f++)
state = runCAOnFrame(internal, map, state, f, l);
}
yield state;
}
case PROJECT -> {
final int frameCount = state.getFrameCount(),
layerCount = state.getLayers().size();

for (int l = 0; l < layerCount; l++) {
if (!(includeDisabledLayers ||
state.getLayers().get(l).isEnabled()))
continue;

if (state.getLayers().get(l).areFramesLinked()) {
state = runCAOnFrame(internal, map, state,
state.getFrameIndex(), l);
} else {
for (int f = 0; f < frameCount; f++)
state = runCAOnFrame(internal, map, state, f, l);
}
}

yield state;
}
};
yield state;
}
};
} catch (RuntimeException re) {
return null;
}
}

private ProjectState runCAOnFrame(
Expand Down
85 changes: 66 additions & 19 deletions src/com/jordanbunke/stipple_effect/scripting/SEScriptVisitor.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
package com.jordanbunke.stipple_effect.scripting;

import com.jordanbunke.delta_time.scripting.ScriptParser;
import com.jordanbunke.delta_time.scripting.ast.nodes.expression.ExpressionNode;
import com.jordanbunke.delta_time.scripting.ast.nodes.expression.*;
import com.jordanbunke.delta_time.scripting.ast.nodes.statement.*;
import com.jordanbunke.delta_time.scripting.util.ScriptVisitor;
import com.jordanbunke.delta_time.scripting.util.TextPosition;
import com.jordanbunke.delta_time.scripting.util.TypeCompatibility;
import com.jordanbunke.stipple_effect.palette.Palette;
import com.jordanbunke.stipple_effect.project.SEContext;
import com.jordanbunke.stipple_effect.scripting.ext_ast_nodes.expression.SEExtExpressionNode;
import com.jordanbunke.stipple_effect.scripting.ext_ast_nodes.statement.SEExtStatementNode;
import com.jordanbunke.stipple_effect.scripting.ext_ast_nodes.type.SEExtTypeNode;
import com.jordanbunke.stipple_effect.scripting.util.LayerRep;
import com.jordanbunke.stipple_effect.scripting.util.SENodeDelegator;
import com.jordanbunke.stipple_effect.utility.Constants;

import java.util.Set;

public final class SEScriptVisitor extends ScriptVisitor {
private static final String SCOPE_SEP = ".";

static {
final Set<Class<?>> extensionTypeObjects =
Set.of(SEContext.class, LayerRep.class);
Set.of(SEContext.class, LayerRep.class, Palette.class);

extensionTypeObjects.forEach(TypeCompatibility::addBaseType);
}
Expand All @@ -26,31 +29,75 @@ public final class SEScriptVisitor extends ScriptVisitor {
public SEExtTypeNode visitExtensionType(
final ScriptParser.ExtensionTypeContext ctx
) {
return SENodeDelegator.delegateType(
return SENodeDelegator.type(
TextPosition.fromToken(ctx.start), ctx.ident().getText());
}

@Override
public SEExtExpressionNode visitExtFuncCallExpression(
public ExpressionNode visitExtFuncCallExpression(
final ScriptParser.ExtFuncCallExpressionContext ctx
) {
return SENodeDelegator.delegateExpression(
TextPosition.fromToken(ctx.start),
ctx.PATH().getText().substring(1),
ctx.args().expr().stream()
.map(e -> (ExpressionNode) visit(e))
.toArray(ExpressionNode[]::new));
final String namespace = ctx.namespace().ident().getText(),
fID = ctx.namespace().subident().getText()
.substring(SCOPE_SEP.length());

final TextPosition position = TextPosition.fromToken(ctx.start);

final ExpressionNode[] args = ctx.args().expr().stream()
.map(a -> (ExpressionNode) visit(a))
.toArray(ExpressionNode[]::new);

if (namespace.equals(Constants.SCRIPT_GLOBAL_NAMESPACE))
return SENodeDelegator.globalFunctionExpression(position, fID, args);

return new IllegalExpressionNode(position,
"\"" + namespace + "\" is an illegal namespace");
}

@Override
public SEExtStatementNode visitExtFuncCallStatement(
public StatementNode visitExtFuncCallStatement(
final ScriptParser.ExtFuncCallStatementContext ctx
) {
return SENodeDelegator.delegateStatement(
TextPosition.fromToken(ctx.start),
ctx.PATH().getText().substring(1),
ctx.args().expr().stream()
.map(e -> (ExpressionNode) visit(e))
.toArray(ExpressionNode[]::new));
final String namespace = ctx.namespace().ident().getText(),
fID = ctx.namespace().subident().getText()
.substring(SCOPE_SEP.length());

final TextPosition position = TextPosition.fromToken(ctx.start);

final ExpressionNode[] args = ctx.args().expr().stream()
.map(a -> (ExpressionNode) visit(a))
.toArray(ExpressionNode[]::new);

if (namespace.equals(Constants.SCRIPT_GLOBAL_NAMESPACE))
return SENodeDelegator.globalFunctionStatement(position, fID, args);

return new IllegalStatementNode(position,
"\"" + namespace + "\" is an illegal namespace");
}

@Override
public ExpressionNode determineExtPropertyExpression(
final TextPosition position, final ExpressionNode scope,
final String propertyID
) {
return SENodeDelegator.property(position, scope, propertyID);
}

@Override
public ExpressionNode determineExtScopedFunctionExpression(
final TextPosition position, final ExpressionNode scope,
final String functionID, final ExpressionNode... args
) {
return SENodeDelegator.scopedFunctionExpression(
position, scope, functionID, args);
}

@Override
public StatementNode determineExtScopedFunctionStatement(
final TextPosition position, final ExpressionNode scope,
final String functionID, final ExpressionNode... args
) {
return SENodeDelegator.scopedFunctionStatement(
position, scope, functionID, args);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,41 +9,41 @@

import java.awt.*;

public final class ColorPropertyGetterNode extends SEExtExpressionNode {
public static final String HUE = "hue", SAT = "sat", VAL = "value";
public final class ColorPropertyGetterNode extends PropertyNode {
public static final String HUE = "hue", SAT = "sat", VAL = "val";

private final String property;

private ColorPropertyGetterNode(
final TextPosition position, final ExpressionNode[] args,
final TextPosition position, final ExpressionNode scope,
final String property
) {
super(position, args, TypeNode.getColor());
super(position, scope, TypeNode.getColor());

this.property = property;
}

public static ColorPropertyGetterNode hue(
final TextPosition position, final ExpressionNode[] args
final TextPosition position, final ExpressionNode scope
) {
return new ColorPropertyGetterNode(position, args, HUE);
return new ColorPropertyGetterNode(position, scope, HUE);
}

public static ColorPropertyGetterNode sat(
final TextPosition position, final ExpressionNode[] args
final TextPosition position, final ExpressionNode scope
) {
return new ColorPropertyGetterNode(position, args, SAT);
return new ColorPropertyGetterNode(position, scope, SAT);
}

public static ColorPropertyGetterNode val(
final TextPosition position, final ExpressionNode[] args
final TextPosition position, final ExpressionNode scope
) {
return new ColorPropertyGetterNode(position, args, VAL);
return new ColorPropertyGetterNode(position, scope, VAL);
}

@Override
public Double evaluate(final SymbolTable symbolTable) {
final Color c = (Color) getValues(symbolTable)[0];
final Color c = (Color) scope.evaluate(symbolTable);

return switch (property) {
case HUE -> ColorMath.rgbToHue(c);
Expand All @@ -54,7 +54,7 @@ public Double evaluate(final SymbolTable symbolTable) {

@Override
public BaseTypeNode getType(final SymbolTable symbolTable) {
return TypeNode.getColor();
return TypeNode.getFloat();
}

@Override
Expand Down
Loading

0 comments on commit e398ea2

Please sign in to comment.