2015-09-10 16:22:07 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2015 The 8-Bit Bunch. Licensed under the Apache License, Version 1.1
|
|
|
|
* (the "License"); you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-1.1>.
|
|
|
|
* Unless required by applicable law or agreed to in writing, software distributed under
|
|
|
|
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
|
|
* ANY KIND, either express or implied. See the License for the specific language
|
|
|
|
* governing permissions and limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2014-03-25 05:01:01 +00:00
|
|
|
package org.badvision.outlaweditor;
|
|
|
|
|
2014-04-04 04:19:59 +00:00
|
|
|
import java.io.ByteArrayInputStream;
|
2014-03-25 05:01:01 +00:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.StringWriter;
|
2015-06-22 07:14:12 +00:00
|
|
|
import java.util.ArrayList;
|
2014-04-13 03:36:25 +00:00
|
|
|
import java.util.HashMap;
|
2015-06-02 01:42:52 +00:00
|
|
|
import java.util.List;
|
2014-04-13 03:36:25 +00:00
|
|
|
import java.util.Map;
|
2015-09-12 23:40:08 +00:00
|
|
|
import java.util.Set;
|
2014-03-25 05:01:01 +00:00
|
|
|
import java.util.logging.Level;
|
|
|
|
import java.util.logging.Logger;
|
2015-06-22 06:40:07 +00:00
|
|
|
import java.util.stream.Collectors;
|
2015-06-23 22:07:19 +00:00
|
|
|
import java.util.stream.Stream;
|
2014-03-25 05:01:01 +00:00
|
|
|
import javafx.fxml.FXMLLoader;
|
|
|
|
import javafx.scene.Scene;
|
|
|
|
import javafx.scene.layout.AnchorPane;
|
|
|
|
import javafx.stage.Stage;
|
|
|
|
import javafx.stage.WindowEvent;
|
|
|
|
import javax.xml.bind.JAXBContext;
|
2014-04-04 04:19:59 +00:00
|
|
|
import javax.xml.bind.JAXBElement;
|
2014-03-25 05:01:01 +00:00
|
|
|
import javax.xml.bind.JAXBException;
|
2014-04-04 04:19:59 +00:00
|
|
|
import javax.xml.bind.Unmarshaller;
|
2014-04-13 05:19:50 +00:00
|
|
|
import javax.xml.namespace.QName;
|
2014-04-04 04:19:59 +00:00
|
|
|
import javax.xml.parsers.DocumentBuilder;
|
|
|
|
import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
|
import javax.xml.parsers.ParserConfigurationException;
|
2014-03-25 05:01:01 +00:00
|
|
|
import org.badvision.outlaweditor.data.xml.Block;
|
2015-06-29 04:19:29 +00:00
|
|
|
import org.badvision.outlaweditor.data.xml.Global;
|
2015-06-23 06:37:39 +00:00
|
|
|
import org.badvision.outlaweditor.data.xml.Mutation;
|
2015-06-23 21:31:37 +00:00
|
|
|
import org.badvision.outlaweditor.data.xml.Scope;
|
2014-03-25 05:01:01 +00:00
|
|
|
import org.badvision.outlaweditor.data.xml.Script;
|
2015-06-23 21:31:37 +00:00
|
|
|
import org.badvision.outlaweditor.data.xml.UserType;
|
|
|
|
import org.badvision.outlaweditor.data.xml.Variable;
|
2015-09-12 23:40:08 +00:00
|
|
|
import org.badvision.outlaweditor.spelling.SpellChecker;
|
|
|
|
import org.badvision.outlaweditor.spelling.SpellResponse;
|
|
|
|
import org.badvision.outlaweditor.spelling.Suggestion;
|
2014-05-25 05:22:26 +00:00
|
|
|
import org.badvision.outlaweditor.ui.ApplicationUIController;
|
|
|
|
import org.badvision.outlaweditor.ui.MythosScriptEditorController;
|
2014-04-04 04:19:59 +00:00
|
|
|
import org.w3c.dom.Document;
|
|
|
|
import org.xml.sax.SAXException;
|
2014-03-25 05:01:01 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Mythos Scripting Editor
|
2014-04-04 04:19:59 +00:00
|
|
|
*
|
2014-03-25 05:01:01 +00:00
|
|
|
* @author blurry
|
|
|
|
*/
|
|
|
|
public class MythosEditor {
|
2014-04-04 04:19:59 +00:00
|
|
|
|
2015-06-23 21:31:37 +00:00
|
|
|
Scope scope;
|
2014-03-25 05:01:01 +00:00
|
|
|
Script script;
|
|
|
|
Stage primaryStage;
|
|
|
|
MythosScriptEditorController controller;
|
2014-04-04 04:19:59 +00:00
|
|
|
public static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n";
|
2015-09-12 23:40:08 +00:00
|
|
|
SpellChecker spellChecker;
|
2014-04-04 04:19:59 +00:00
|
|
|
|
2015-06-23 21:31:37 +00:00
|
|
|
public MythosEditor(Script theScript, Scope theScope) {
|
2014-03-25 05:01:01 +00:00
|
|
|
script = theScript;
|
2015-06-23 21:31:37 +00:00
|
|
|
scope = theScope;
|
2015-09-12 23:40:08 +00:00
|
|
|
spellChecker = new SpellChecker();
|
2014-03-25 05:01:01 +00:00
|
|
|
}
|
2014-04-04 04:19:59 +00:00
|
|
|
|
2014-03-25 05:01:01 +00:00
|
|
|
public void show() {
|
|
|
|
primaryStage = new Stage();
|
|
|
|
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/MythosScriptEditor.fxml"));
|
2014-05-25 05:29:58 +00:00
|
|
|
Map<String, String> properties = new HashMap<>();
|
2014-04-13 03:36:25 +00:00
|
|
|
properties.put(MythosScriptEditorController.ONLOAD_SCRIPT, generateLoadScript());
|
|
|
|
fxmlLoader.setResources(MythosScriptEditorController.createResourceBundle(properties));
|
2014-03-25 05:01:01 +00:00
|
|
|
try {
|
|
|
|
AnchorPane node = (AnchorPane) fxmlLoader.load();
|
|
|
|
controller = fxmlLoader.getController();
|
|
|
|
controller.setEditor(this);
|
|
|
|
Scene s = new Scene(node);
|
|
|
|
primaryStage.setScene(s);
|
|
|
|
} catch (IOException exception) {
|
|
|
|
throw new RuntimeException(exception);
|
|
|
|
}
|
2014-04-04 04:19:59 +00:00
|
|
|
|
2014-09-28 06:54:49 +00:00
|
|
|
primaryStage.setOnCloseRequest((final WindowEvent t) -> {
|
|
|
|
t.consume();
|
2014-03-25 05:01:01 +00:00
|
|
|
});
|
|
|
|
primaryStage.show();
|
2014-04-13 03:36:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void close() {
|
2014-09-28 06:54:49 +00:00
|
|
|
javafx.application.Platform.runLater(() -> {
|
|
|
|
primaryStage.getScene().getRoot().setDisable(true);
|
|
|
|
primaryStage.close();
|
2014-04-04 04:19:59 +00:00
|
|
|
});
|
2014-03-25 05:01:01 +00:00
|
|
|
}
|
2014-04-04 04:19:59 +00:00
|
|
|
|
2014-03-25 05:01:01 +00:00
|
|
|
public void applyChanges() {
|
|
|
|
try {
|
2014-04-13 03:36:25 +00:00
|
|
|
String xml = controller.getScriptXml();
|
2014-04-04 04:19:59 +00:00
|
|
|
JAXBContext context = JAXBContext.newInstance("org.badvision.outlaweditor.data.xml");
|
|
|
|
Unmarshaller unmarshaller = context.createUnmarshaller();
|
|
|
|
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
|
|
|
dbf.setNamespaceAware(true);
|
|
|
|
DocumentBuilder db = dbf.newDocumentBuilder();
|
|
|
|
Document doc = db.parse(new ByteArrayInputStream(xml.getBytes("UTF-8")));
|
|
|
|
JAXBElement<Block> b = unmarshaller.unmarshal(doc, Block.class);
|
|
|
|
script.setBlock(b.getValue());
|
|
|
|
} catch (JAXBException | ParserConfigurationException | SAXException | IOException ex) {
|
2014-03-25 05:01:01 +00:00
|
|
|
Logger.getLogger(MythosEditor.class.getName()).log(Level.SEVERE, null, ex);
|
|
|
|
}
|
|
|
|
}
|
2014-04-04 04:19:59 +00:00
|
|
|
|
2014-04-13 03:36:25 +00:00
|
|
|
public String generateLoadScript() {
|
2014-03-25 05:01:01 +00:00
|
|
|
if (script == null || script.getBlock() == null) {
|
2014-04-13 03:36:25 +00:00
|
|
|
return generateLoadScript(getDefaultBlockMarkup());
|
|
|
|
} else {
|
|
|
|
try {
|
|
|
|
JAXBContext context = JAXBContext.newInstance(Block.class);
|
|
|
|
StringWriter buffer = new StringWriter();
|
2014-05-25 05:29:58 +00:00
|
|
|
QName qName = new QName("outlaw", "block");
|
|
|
|
JAXBElement<Block> root = new JAXBElement<>(qName, Block.class, script.getBlock());
|
2014-04-13 05:19:50 +00:00
|
|
|
context.createMarshaller().marshal(root, buffer);
|
2014-04-13 03:36:25 +00:00
|
|
|
String xml = buffer.toString();
|
2014-07-06 21:49:13 +00:00
|
|
|
xml = xml.replaceAll("'", "'");
|
2014-05-25 05:29:58 +00:00
|
|
|
xml = xml.replace("?>", "?><xml>");
|
2014-04-13 05:19:50 +00:00
|
|
|
xml += "</xml>";
|
2014-04-13 03:36:25 +00:00
|
|
|
return generateLoadScript(xml);
|
|
|
|
} catch (JAXBException ex) {
|
|
|
|
Logger.getLogger(MythosEditor.class.getName()).log(Level.SEVERE, null, ex);
|
|
|
|
}
|
2014-03-25 05:01:01 +00:00
|
|
|
}
|
2014-04-13 03:36:25 +00:00
|
|
|
return null;
|
2014-03-25 05:01:01 +00:00
|
|
|
}
|
2014-04-04 04:19:59 +00:00
|
|
|
|
2014-04-13 03:36:25 +00:00
|
|
|
public String generateLoadScript(String xml) {
|
2014-04-04 04:19:59 +00:00
|
|
|
xml = xml.replaceAll("'", "\\'");
|
|
|
|
xml = xml.replaceAll("\n", "");
|
2015-06-02 01:42:52 +00:00
|
|
|
String loadScript = "Mythos.initCustomDefinitions();";
|
|
|
|
loadScript += "Mythos.setScriptXml('" + xml + "');";
|
2014-04-13 03:36:25 +00:00
|
|
|
return loadScript;
|
2014-03-25 05:01:01 +00:00
|
|
|
}
|
|
|
|
|
2014-04-13 03:36:25 +00:00
|
|
|
private String getDefaultBlockMarkup() {
|
2014-05-25 05:29:58 +00:00
|
|
|
return XML_HEADER + "<xml><block type=\"procedures_defreturn\" id=\"1\" inline=\"false\" x=\"5\" y=\"5\"><mutation></mutation><field name=\"NAME\">NewScript</field></block></xml>";
|
2014-04-13 03:36:25 +00:00
|
|
|
}
|
2014-05-25 05:29:58 +00:00
|
|
|
|
2014-04-13 03:36:25 +00:00
|
|
|
// Called when the name of the root block is changed in the JS editor
|
|
|
|
public void setFunctionName(String name) {
|
2014-04-13 05:19:50 +00:00
|
|
|
if (script == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
script.setName(name);
|
2014-05-25 05:22:26 +00:00
|
|
|
ApplicationUIController.getController().redrawScripts();
|
2014-03-25 05:01:01 +00:00
|
|
|
}
|
2015-06-22 06:40:07 +00:00
|
|
|
|
2015-06-23 22:07:19 +00:00
|
|
|
public List<UserType> getUserTypes() {
|
2015-06-29 04:19:29 +00:00
|
|
|
Global global = (Global) getGlobalScope();
|
|
|
|
if (global.getUserTypes() == null) {
|
2015-06-23 22:07:19 +00:00
|
|
|
return new ArrayList<>();
|
|
|
|
} else {
|
2015-06-29 04:19:29 +00:00
|
|
|
return global.getUserTypes().getUserType();
|
2015-06-23 22:07:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-23 06:37:39 +00:00
|
|
|
public List<Script> getGlobalFunctions() {
|
2015-06-29 04:19:29 +00:00
|
|
|
return getFunctions(getGlobalScope());
|
2015-06-23 22:07:19 +00:00
|
|
|
}
|
2015-09-12 23:40:08 +00:00
|
|
|
|
2015-06-23 22:07:19 +00:00
|
|
|
public List<Script> getLocalFunctions() {
|
|
|
|
return getFunctions(scope);
|
|
|
|
}
|
2015-09-12 23:40:08 +00:00
|
|
|
|
2015-06-23 22:07:19 +00:00
|
|
|
private List<Script> getFunctions(Scope scriptScope) {
|
|
|
|
if (scriptScope.getScripts() == null) {
|
2015-06-22 07:14:12 +00:00
|
|
|
return new ArrayList<>();
|
2015-06-22 06:40:07 +00:00
|
|
|
} else {
|
2015-06-23 22:07:19 +00:00
|
|
|
List<Script> scripts = scriptScope.getScripts().getScript();
|
2015-06-22 06:40:07 +00:00
|
|
|
List<Script> filteredList = scripts.stream().filter((Script s) -> {
|
2015-06-23 06:37:39 +00:00
|
|
|
return s.getName() != null;
|
2015-06-22 06:40:07 +00:00
|
|
|
}).collect(Collectors.toList());
|
|
|
|
return filteredList;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-23 22:07:19 +00:00
|
|
|
public List<Variable> getGlobalVariables() {
|
2015-06-29 04:19:29 +00:00
|
|
|
return getVariables(getGlobalScope());
|
2015-06-22 06:40:07 +00:00
|
|
|
}
|
|
|
|
|
2015-06-29 04:19:29 +00:00
|
|
|
public static Scope getGlobalScope() {
|
|
|
|
return Application.gameData.getGlobal();
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean isGlobalScope() {
|
|
|
|
return scope.equals(getGlobalScope());
|
|
|
|
}
|
2015-09-12 23:40:08 +00:00
|
|
|
|
2015-06-23 22:07:19 +00:00
|
|
|
public List<Variable> getLocalVariables() {
|
|
|
|
return getVariables(scope);
|
|
|
|
}
|
2015-09-12 23:40:08 +00:00
|
|
|
|
2015-06-23 22:07:19 +00:00
|
|
|
private List<Variable> getVariables(Scope scriptScope) {
|
|
|
|
if (scriptScope.getVariables() == null) {
|
2015-06-22 07:14:12 +00:00
|
|
|
return new ArrayList<>();
|
2015-06-22 06:40:07 +00:00
|
|
|
} else {
|
2015-06-23 22:07:19 +00:00
|
|
|
return scriptScope.getVariables().getVariable();
|
2015-09-12 23:40:08 +00:00
|
|
|
}
|
2015-06-22 06:40:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public List<Variable> getVariablesByType(String type) {
|
2015-06-29 04:19:29 +00:00
|
|
|
Stream<Variable> allGlobals = Stream.empty();
|
|
|
|
if (!isGlobalScope()) {
|
|
|
|
allGlobals = getGlobalVariables().stream();
|
|
|
|
}
|
2015-06-23 22:07:19 +00:00
|
|
|
Stream<Variable> allLocals = getLocalVariables().stream();
|
|
|
|
return Stream.concat(allGlobals, allLocals).filter(
|
2015-06-22 06:40:07 +00:00
|
|
|
(Variable v) -> {
|
|
|
|
return v.getType().equals(type);
|
|
|
|
}).collect(Collectors.toList());
|
|
|
|
}
|
2015-06-23 06:37:39 +00:00
|
|
|
|
|
|
|
public List<String> getParametersForScript(Script script) {
|
|
|
|
List<String> allArgs = new ArrayList();
|
2015-06-23 22:07:19 +00:00
|
|
|
if (script.getBlock() != null && script.getBlock().getFieldOrMutationOrStatement() != null) {
|
2015-09-12 23:40:08 +00:00
|
|
|
script.getBlock().getFieldOrMutationOrStatement()
|
|
|
|
.stream().filter((o) -> (o instanceof Mutation))
|
|
|
|
.map((o) -> (Mutation) o).findFirst().ifPresent((m) -> {
|
|
|
|
m.getArg().stream().forEach((a) -> {
|
|
|
|
allArgs.add(a.getName());
|
2015-06-23 06:37:39 +00:00
|
|
|
});
|
2015-09-12 23:40:08 +00:00
|
|
|
});
|
2015-06-23 22:07:19 +00:00
|
|
|
}
|
2015-06-23 06:37:39 +00:00
|
|
|
return allArgs;
|
|
|
|
}
|
|
|
|
|
2015-09-12 23:40:08 +00:00
|
|
|
public String checkSpelling(String value) {
|
|
|
|
SpellResponse result = spellChecker.check(value);
|
|
|
|
if (result.getErrors() == 0) {
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
StringBuilder message = new StringBuilder();
|
|
|
|
result.getCorrections().forEach((SpellResponse.Source source, Set<Suggestion> suggestions) -> {
|
|
|
|
message
|
|
|
|
.append(source.word)
|
|
|
|
.append(" : ")
|
|
|
|
.append(suggestions.stream().map(Suggestion::getWord).collect(Collectors.joining(", ")))
|
|
|
|
.append("\n");
|
|
|
|
});
|
|
|
|
return message.toString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-22 06:40:07 +00:00
|
|
|
public void log(String message) {
|
2015-09-12 23:40:08 +00:00
|
|
|
Logger.getLogger(getClass().getName()).warning(message);
|
2015-06-22 06:40:07 +00:00
|
|
|
System.out.println(message);
|
2015-06-02 01:42:52 +00:00
|
|
|
}
|
2015-06-23 06:37:39 +00:00
|
|
|
}
|