- Extend PluginAPI with storage.

- Store Skin Composer version checking and automatic update.
This commit is contained in:
fgnm
2020-07-11 12:49:30 +02:00
parent 93c8798adf
commit b551acf847
18 changed files with 143 additions and 60 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -37,6 +37,8 @@ public class MsgAPI {
public static final String DISPOSE = GLOBAL_PREFIX + ".DISPOSE";
public static final String CREATE = GLOBAL_PREFIX + ".CREATE_BTN_CLICKED";
public static final String SAVE_EDITOR_CONFIG = GLOBAL_PREFIX + ".SAVE_EDITOR_CONFIG";
// tmp events
public static final String ZOOM_CHANGED = GLOBAL_PREFIX + ".ZOOM_CHANGED";
public static final String GRID_SIZE_CHANGED = GLOBAL_PREFIX + ".GRID_SIZE_CHANGED";
@@ -81,4 +81,10 @@ public class UIDraggablePanel extends H2DDialog {
super.hide();
isOpen = false;
}
@Override
protected void close() {
super.close();
isOpen = false;
}
}
@@ -22,6 +22,8 @@ import com.badlogic.gdx.utils.Array;
import com.puremvc.patterns.facade.Facade;
import net.mountainblade.modular.Module;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
@@ -31,9 +33,14 @@ public abstract class H2DPluginAdapter implements H2DPlugin, Module {
public Facade facade;
protected PluginAPI pluginAPI;
protected String name;
public H2DPluginAdapter(String name) {
this.name = name;
}
public String getName() {
return "";
return name;
}
@Override
@@ -56,4 +63,8 @@ public abstract class H2DPluginAdapter implements H2DPlugin, Module {
public PluginAPI getAPI() {
return pluginAPI;
}
public Map<String, Object> getStorage() {
return pluginAPI.getEditorConfig().pluginStorage.computeIfAbsent(name, k -> new HashMap<>());
}
}
@@ -30,6 +30,7 @@ import com.kotcrab.vis.ui.widget.VisImageButton;
import com.puremvc.patterns.facade.Facade;
import games.rednblack.editor.renderer.SceneLoader;
import games.rednblack.h2d.common.vo.CursorData;
import games.rednblack.h2d.common.vo.EditorConfigVO;
import java.util.HashMap;
import java.util.HashSet;
@@ -43,45 +44,45 @@ public interface PluginAPI {
* Get scene loader of the runtime to work with scene and items
* @return SceneLoader
*/
public SceneLoader getSceneLoader();
SceneLoader getSceneLoader();
/**
* Returns MVC facade, to send notifications or commands, and register mediators
* @return Facade
*/
public Facade getFacade();
Facade getFacade();
/**
* Returns Ashley engine of main scene where all entities are located
* @return Engine
*/
public Engine getEngine();
Engine getEngine();
/**
* Get simple libGDX Stage for UI part of editor, to add dialogs or other UI elements and widgets
* @return
*/
public Stage getUIStage();
Stage getUIStage();
/**
* @return Path of plugin directory
*/
public String getPluginDir();
String getPluginDir();
/**
* @return Path of cache directory
*/
public String getCacheDir();
String getCacheDir();
/**
* @return Path of working project
*/
public String getProjectPath();
String getProjectPath();
/**
* @return TextureAtlas of loaded project
*/
public TextureAtlas getProjectTextureAtlas();
TextureAtlas getProjectTextureAtlas();
/**
@@ -90,7 +91,7 @@ public interface PluginAPI {
* @param subMenuName pretty string to name new submenu item
* @param notificationName unique notification id that will be fired when this menu item is clicked
*/
public void addMenuItem(String menu, String subMenuName, String notificationName);
void addMenuItem(String menu, String subMenuName, String notificationName);
/**
* Adds new tool to the tool bar
@@ -99,18 +100,18 @@ public interface PluginAPI {
* @param addSeparator true, if should add menu separator
* @param tool the tool object that is going to be added
*/
public void addTool(String toolName, VisImageButton.VisImageButtonStyle toolBtnStyle, boolean addSeparator, Tool tool);
void addTool(String toolName, VisImageButton.VisImageButtonStyle toolBtnStyle, boolean addSeparator, Tool tool);
/**
* hot-swaps a tool
*/
public void toolHotSwap(Tool tool);
void toolHotSwap(Tool tool);
/**
* hot-swaps a tool back
*/
public void toolHotSwapBack();
void toolHotSwapBack();
/**
* Creates new menu item for Contextual drop down menu, that is created when user right clicks on something in the editor.
@@ -118,30 +119,30 @@ public interface PluginAPI {
* @param action unique name of notification id that will be fired when this menu item is clicked
* @param name pretty text to be written on this menu item
*/
public void setDropDownItemName(String action, String name);
void setDropDownItemName(String action, String name);
/**
* re-loads current project entirely (used when changes were made that require to whole project to be reloaded)
*/
public void reLoadProject();
void reLoadProject();
/**
* Saves current project
*/
public void saveProject();
void saveProject();
/**
* Creates a revertable command that later can be undone or re-done by user with Ctrl+Z or similar.
* @param command Object containing your command logic
* @param body Additional data that can be send as parameters
*/
public void revertableCommand(IItemCommand command, Object body);
void revertibleCommand(IItemCommand command, Object body);
/**
* Removes follower object (selection rectangle) from particular entity (usually makes sense when entity is deleted without proper action)
* @param entity
*/
public void removeFollower(Entity entity);
void removeFollower(Entity entity);
/**
* Draws an image at selected position
@@ -180,4 +181,9 @@ public interface PluginAPI {
* returns current selected layer name
*/
String getCurrentSelectedLayerName();
/**
* returns current editor configs
*/
EditorConfigVO getEditorConfig();
}
@@ -21,14 +21,17 @@ package games.rednblack.h2d.common.vo;
import com.badlogic.gdx.utils.Json;
import com.badlogic.gdx.utils.JsonWriter;
/**
* Created by sargis on 8/1/14.
*/
import java.util.HashMap;
import java.util.Map;
public class EditorConfigVO {
public static final String EDITOR_CONFIG_FILE = "config.pit";
public String lastOpenedSystemPath = "";
public String lastImportedSystemPath = "";
//Map to store plugin storage
public Map<String, Map<String, Object>> pluginStorage = new HashMap<>();
public String constructJsonString() {
String str = "";
Json json = new Json();
@@ -26,6 +26,7 @@ public class NinePatchPlugin extends H2DPluginAdapter {
public Entity currEditingEntity;
public NinePatchPlugin() {
super(CLASS_NAME);
performancePanelMediator = new MainPanelMediator(this);
}
@@ -13,6 +13,7 @@ public class PerformancePlugin extends H2DPluginAdapter {
private final PerformancePanelMediator performancePanelMediator;
public PerformancePlugin() {
super(CLASS_NAME);
performancePanelMediator = new PerformancePanelMediator(this);
}
@@ -7,8 +7,8 @@ import games.rednblack.h2d.common.ProgressHandler;
import games.rednblack.h2d.common.UIDraggablePanel;
public class DownloadingDialog extends UIDraggablePanel implements ProgressHandler {
private VisLabel downloadingLabel;
private VisProgressBar progressBar;
private final VisLabel downloadingLabel;
private final VisProgressBar progressBar;
public DownloadingDialog () {
super("Skin Composer Plugin");
@@ -21,7 +21,7 @@ public class DownloadingDialog extends UIDraggablePanel implements ProgressHandl
VisTable mainTable = new VisTable();
add(mainTable).fill().expand();
downloadingLabel = new VisLabel("Downloading info ...");
downloadingLabel = new VisLabel("Checking for updates ...");
mainTable.add(downloadingLabel).left();
mainTable.row().padBottom(5);
@@ -32,8 +32,12 @@ public class DownloadingDialog extends UIDraggablePanel implements ProgressHandl
pack();
}
public void setCurrentVersion(String name) {
downloadingLabel.setText("Downloading "+ name + " ...");
public void setMessage(String message) {
downloadingLabel.setText(message);
}
public void setProgress(float value) {
progressBar.setValue(value);
}
@Override
@@ -48,6 +52,7 @@ public class DownloadingDialog extends UIDraggablePanel implements ProgressHandl
@Override
public void progressComplete() {
progressBar.setValue(100);
close();
}
@@ -1,8 +1,10 @@
package games.rednblack.editor.plugin.skincomposer;
import com.badlogic.gdx.utils.Json;
import com.kotcrab.vis.ui.util.dialog.Dialogs;
import com.puremvc.patterns.mediator.SimpleMediator;
import com.puremvc.patterns.observer.Notification;
import games.rednblack.h2d.common.MsgAPI;
import org.apache.commons.io.FileUtils;
import java.io.File;
@@ -10,11 +12,12 @@ import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SkinComposerMediator extends SimpleMediator<DownloadingDialog> {
public class SkinComposerMediator extends SimpleMediator<DownloadingDialog> {
private static final String TAG = SkinComposerMediator.class.getCanonicalName();
public static final String NAME = TAG;
private final SkinComposerPlugin plugin;
private String pluginPath, jarPath;
public SkinComposerMediator(SkinComposerPlugin plugin) {
super(NAME, new DownloadingDialog());
@@ -24,31 +27,30 @@ public class SkinComposerMediator extends SimpleMediator<DownloadingDialog> {
@Override
public String[] listNotificationInterests() {
return new String[]{
SkinComposerPlugin.PANEL_OPEN
SkinComposerPlugin.PANEL_OPEN,
SkinComposerPlugin.DOWNLOAD_JAR
};
}
@Override
public void handleNotification(Notification notification) {
super.handleNotification(notification);
pluginPath = plugin.getAPI().getCacheDir();
jarPath = pluginPath + File.separator + "SkinComposer.jar";
switch (notification.getName()) {
case SkinComposerPlugin.PANEL_OPEN:
if (viewComponent.isOpen) {
return;
}
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.execute(() -> {
String pluginPath = plugin.getAPI().getCacheDir();
String jarPath = pluginPath + File.separator + "SkinComposer.jar";
if (new File(jarPath).exists()) {
try {
Runtime.getRuntime().exec(" java -jar " + jarPath);
} catch (IOException e) {
e.printStackTrace();
}
return;
}
viewComponent.show(plugin.getAPI().getUIStage());
viewComponent.setMessage("Checking for updates ...");
viewComponent.setProgress(0);
try {
FileUtils.forceMkdir(new File(pluginPath));
@@ -61,30 +63,60 @@ public class SkinComposerMediator extends SimpleMediator<DownloadingDialog> {
Json json = new Json();
json.setIgnoreUnknownFields(true);
GithubReleaseData jsonData = json.fromJson(GithubReleaseData.class, data);
viewComponent.setCurrentVersion(jsonData.name);
for (GithubReleaseData.GithubReleaseAssetData assetData : jsonData.assets) {
if (assetData.name.equals("SkinComposer.jar")) {
try {
HttpDownloadUtility.downloadFile(assetData.browser_download_url, pluginPath, viewComponent);
} catch (IOException e) {
viewComponent.progressFailed();
e.printStackTrace();
}
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
try {
Runtime.getRuntime().exec(" java -jar " + jarPath);
if (!new File(jarPath).exists() || plugin.getStorage().get("latest_update") == null || !plugin.getStorage().get("latest_update").equals(jsonData.tag_name)) {
Dialogs.showConfirmDialog(plugin.getAPI().getUIStage(),
"New update found!", "A new version of Skin Composer has found, would you like to download it?",
new String[]{"Later", "Download Now"}, new Integer[]{0, 1}, r -> {
if (r == 1) {
plugin.facade.sendNotification(SkinComposerPlugin.DOWNLOAD_JAR, jsonData);
} else {
viewComponent.progressComplete();
runJar(jarPath);
}
}).padBottom(20).pack();
} else {
viewComponent.progressComplete();
runJar(jarPath);
}
} catch (IOException e) {
e.printStackTrace();
}
});
executor.shutdown();
break;
case SkinComposerPlugin.DOWNLOAD_JAR:
ExecutorService downloader = Executors.newSingleThreadExecutor();
downloader.execute(() -> {
GithubReleaseData jsonData = notification.getBody();
viewComponent.setMessage("Downloading " + jsonData.name + " ...");
for (GithubReleaseData.GithubReleaseAssetData assetData : jsonData.assets) {
if (assetData.name.equals("SkinComposer.jar")) {
try {
HttpDownloadUtility.downloadFile(assetData.browser_download_url, pluginPath, viewComponent);
plugin.getStorage().put("latest_update", jsonData.tag_name);
plugin.facade.sendNotification(MsgAPI.SAVE_EDITOR_CONFIG);
runJar(jarPath);
} catch (IOException e) {
viewComponent.progressFailed();
e.printStackTrace();
}
break;
}
}
});
downloader.shutdown();
break;
}
}
private void runJar(String jarPath) {
try {
Runtime.getRuntime().exec(" java -jar " + jarPath);
} catch (IOException e) {
e.printStackTrace();
}
}
}
@@ -9,10 +9,12 @@ public class SkinComposerPlugin extends H2DPluginAdapter {
public static final String PANEL_OPEN = CLASS_NAME + ".PANEL_OPEN";
public static final String WINDOWS_MENU = "games.rednblack.editor.view.HyperLap2DMenuBar.WINDOW_MENU";
public static final String DOWNLOAD_JAR = CLASS_NAME + ".DOWNLOAD_JAR";
private final SkinComposerMediator skinComposerMediator;
public SkinComposerPlugin() {
super(CLASS_NAME);
skinComposerMediator = new SkinComposerMediator(this);
}
@@ -85,6 +85,7 @@ public class TiledPlugin extends H2DPluginAdapter {
private TransformComponent currentEntityTransformComponent;
public TiledPlugin() {
super(CLASS_NAME);
selectedTileVO = new TileVO();
currentEntityCustomVariables = new CustomVariables();
}
@@ -50,6 +50,7 @@ import games.rednblack.editor.view.ui.UIDropDownMenuMediator;
import games.rednblack.editor.view.ui.box.UILayerBoxMediator;
import games.rednblack.editor.view.ui.box.UIToolBoxMediator;
import games.rednblack.h2d.common.vo.CursorData;
import games.rednblack.h2d.common.vo.EditorConfigVO;
import java.util.*;
@@ -125,7 +126,7 @@ public class PluginManager extends BaseProxy implements PluginAPI {
}
@Override
public void revertableCommand(IItemCommand command, Object body) {
public void revertibleCommand(IItemCommand command, Object body) {
Object payload = PluginItemCommand.build(command, body);
facade.sendNotification(MsgAPI.ACTION_PLUGIN_PROXY_COMMAND, payload);
}
@@ -264,4 +265,10 @@ public class PluginManager extends BaseProxy implements PluginAPI {
UILayerBoxMediator uiLayerBoxMediator = facade.retrieveMediator(UILayerBoxMediator.NAME);
return uiLayerBoxMediator.getViewComponent().getCurrentSelectedLayer().getLayerName();
}
@Override
public EditorConfigVO getEditorConfig() {
ProjectManager projectManager = facade.retrieveProxy(ProjectManager.NAME);
return projectManager.editorConfigVO;
}
}
@@ -81,7 +81,7 @@ public class ProjectManager extends BaseProxy {
private String defaultWorkspacePath;
private String DEFAULT_FOLDER = "HyperLap2D";
private EditorConfigVO editorConfigVO;
public EditorConfigVO editorConfigVO;
private String currentWindowTitle = "";
@@ -177,7 +177,7 @@ public class ProjectManager extends BaseProxy {
saveEditorConfig();
}
private void saveEditorConfig() {
public void saveEditorConfig() {
try {
String configFilePath = getRootPath() + File.separator + "configs" + File.separator + EditorConfigVO.EDITOR_CONFIG_FILE;
FileUtils.writeStringToFile(new File(configFilePath), editorConfigVO.constructJsonString(), "utf-8");
@@ -19,6 +19,7 @@
package games.rednblack.editor.view;
import com.badlogic.ashley.core.Engine;
import games.rednblack.editor.proxy.ProjectManager;
import games.rednblack.h2d.common.MsgAPI;
import com.puremvc.patterns.mediator.SimpleMediator;
import com.puremvc.patterns.observer.Notification;
@@ -47,7 +48,8 @@ public class HyperLap2DScreenMediator extends SimpleMediator<HyperLap2DScreen> {
MsgAPI.RENDER,
MsgAPI.RESIZE,
MsgAPI.DISPOSE,
MsgAPI.SCENE_LOADED
MsgAPI.SCENE_LOADED,
MsgAPI.SAVE_EDITOR_CONFIG
};
}
@@ -89,6 +91,10 @@ public class HyperLap2DScreenMediator extends SimpleMediator<HyperLap2DScreen> {
break;
case MsgAPI.DISPOSE:
break;
case MsgAPI.SAVE_EDITOR_CONFIG:
ProjectManager projectManager = facade.retrieveProxy(ProjectManager.NAME);
projectManager.saveEditorConfig();
break;
}
}
}