diff --git a/build.xml b/build.xml index a2c3f45..2a5fc0d 100644 --- a/build.xml +++ b/build.xml @@ -37,6 +37,9 @@ + + + diff --git a/resources/icon.png b/resources/icon.png new file mode 100644 index 0000000..88a9d5e Binary files /dev/null and b/resources/icon.png differ diff --git a/resources/title.png b/resources/title.png new file mode 100644 index 0000000..e52fffd Binary files /dev/null and b/resources/title.png differ diff --git a/src/com/sheepit/client/Client.java b/src/com/sheepit/client/Client.java index 8cff815..4ef0d4e 100644 --- a/src/com/sheepit/client/Client.java +++ b/src/com/sheepit/client/Client.java @@ -93,6 +93,10 @@ public class Client { return this.config; } + public Server getServer() { + return this.server; + } + public int run() { if (this.config.checkOSisSupported() == false) { this.gui.error(Error.humanString(Error.Type.OS_NOT_SUPPORTED)); diff --git a/src/com/sheepit/client/Configuration.java b/src/com/sheepit/client/Configuration.java index 538bc9d..a218613 100644 --- a/src/com/sheepit/client/Configuration.java +++ b/src/com/sheepit/client/Configuration.java @@ -77,10 +77,18 @@ public class Configuration { return this.login; } + public void setLogin(String login_) { + this.login = login_; + } + public String password() { return this.password; } + public void setPassword(String password_) { + this.password = password_; + } + public int maxUploadingJob() { return this.maxUploadingJob; } @@ -165,6 +173,10 @@ public class Configuration { } } + public boolean getUserSpecifiedACacheDir() { + return this.userSpecifiedACacheDir; + } + public void setExtras(String str) { this.extras = str; } diff --git a/src/com/sheepit/client/Gui.java b/src/com/sheepit/client/Gui.java index b6916de..cf63726 100644 --- a/src/com/sheepit/client/Gui.java +++ b/src/com/sheepit/client/Gui.java @@ -31,4 +31,8 @@ public interface Gui { public void AddFrameRendered(); public void framesRemaining(int nb_); + + public void setClient(Client cli); + + public Client getClient(); } diff --git a/src/com/sheepit/client/Server.java b/src/com/sheepit/client/Server.java index 2070213..f54fb58 100644 --- a/src/com/sheepit/client/Server.java +++ b/src/com/sheepit/client/Server.java @@ -714,6 +714,41 @@ public class Server extends Thread implements HostnameVerifier, X509TrustManager return ServerCode.UNKNOWN; } + public byte[] getLastRender() { + try { + HttpURLConnection httpCon = this.HTTPRequest(this.getPage("last-render-frame")); + + InputStream inStrm = httpCon.getInputStream(); + if (httpCon.getResponseCode() != HttpURLConnection.HTTP_OK) { + this.log.debug("Server::getLastRender code not ok " + httpCon.getResponseCode()); + return null; + } + int size = httpCon.getContentLength(); + + if (size == 0) { + this.log.debug("Server::getLastRender size is 0"); + return null; + } + + byte[] ret = new byte[size]; + byte[] ch = new byte[512 * 1024]; + int n = 0; + int i = 0; + while ((n = inStrm.read(ch)) != -1) { + System.arraycopy(ch, 0, ret, i, n); + i += n; + } + inStrm.close(); + return ret; + } + catch (Exception e) { + System.err.println("Server::getLastRender exception " + e); + e.printStackTrace(); + + } + return null; + } + private String generateXMLForMD5cache() { String xml_str = null; try { diff --git a/src/com/sheepit/client/standalone/GuiText.java b/src/com/sheepit/client/standalone/GuiText.java index 73fe442..0788a4f 100644 --- a/src/com/sheepit/client/standalone/GuiText.java +++ b/src/com/sheepit/client/standalone/GuiText.java @@ -19,6 +19,7 @@ package com.sheepit.client.standalone; +import com.sheepit.client.Client; import com.sheepit.client.Gui; import com.sheepit.client.Log; @@ -63,4 +64,13 @@ public class GuiText implements Gui { System.out.println("frame remaining: " + n_); } + @Override + public void setClient(Client cli) { + } + + @Override + public Client getClient() { + return null; + } + } diff --git a/src/com/sheepit/client/standalone/GuiTextOneLine.java b/src/com/sheepit/client/standalone/GuiTextOneLine.java index 56a3866..b7045a6 100644 --- a/src/com/sheepit/client/standalone/GuiTextOneLine.java +++ b/src/com/sheepit/client/standalone/GuiTextOneLine.java @@ -1,5 +1,6 @@ package com.sheepit.client.standalone; +import com.sheepit.client.Client; import com.sheepit.client.Gui; public class GuiTextOneLine implements Gui { @@ -47,6 +48,15 @@ public class GuiTextOneLine implements Gui { updateLine(); } + @Override + public void setClient(Client cli) { + } + + @Override + public Client getClient() { + return null; + } + private void updateLine() { int charToRemove = line.length(); diff --git a/src/com/sheepit/client/standalone/Worker.java b/src/com/sheepit/client/standalone/Worker.java index bf0dcdf..e0fa8f2 100644 --- a/src/com/sheepit/client/standalone/Worker.java +++ b/src/com/sheepit/client/standalone/Worker.java @@ -273,14 +273,20 @@ public class Worker { } gui = new GuiTextOneLine(); } + else if (ui_type.equals("swing")) { + gui = new GuiSwing(); + } else { gui = new GuiText(); } Client cli = new Client(gui, config, server); + gui.setClient(cli); ShutdownHook hook = new ShutdownHook(cli); hook.attachShutDownHook(); + gui.start(); + cli.run(); cli.stop(); } diff --git a/src/com/sheepit/client/standalone/swing/activity/Activity.java b/src/com/sheepit/client/standalone/swing/activity/Activity.java new file mode 100644 index 0000000..6f18a91 --- /dev/null +++ b/src/com/sheepit/client/standalone/swing/activity/Activity.java @@ -0,0 +1,7 @@ +package com.sheepit.client.standalone.swing.activity; + +public interface Activity { + + public void show(); + +} diff --git a/src/com/sheepit/client/standalone/swing/activity/Settings.java b/src/com/sheepit/client/standalone/swing/activity/Settings.java new file mode 100644 index 0000000..e2ccde8 --- /dev/null +++ b/src/com/sheepit/client/standalone/swing/activity/Settings.java @@ -0,0 +1,236 @@ +package com.sheepit.client.standalone.swing.activity; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.io.IOException; +import java.util.LinkedList; +import java.util.List; + +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JPasswordField; +import javax.swing.JTextField; +import com.sheepit.client.Configuration; +import com.sheepit.client.Configuration.ComputeType; +import com.sheepit.client.hardware.gpu.GPU; +import com.sheepit.client.hardware.gpu.GPUDevice; +import com.sheepit.client.standalone.GuiSwing; + +public class Settings implements Activity { + private static final String DUMMY_CACHE_DIR = "Auto detected"; + + private GuiSwing parent; + + private JTextField login; + private JPasswordField password; + private JLabel cacheDirText; + private File cacheDir; + private JFileChooser cacheDirChooser; + private JCheckBox useCPU; + private List useGPUs; + + public Settings(GuiSwing parent_) { + parent = parent_; + cacheDir = null; + useGPUs = new LinkedList(); + } + + @Override + public void show() { + Configuration config = parent.getConfiguration(); + + int size_height_label = 24; + int start_label_left = 109; + int start_label_right = 265; + int end_label_right = 490; + int n = 10; + int sep = 45; + + ImageIcon image = new ImageIcon(getClass().getResource("/title.png")); + JLabel labelImage = new JLabel(image); + labelImage.setBounds(600 / 2 - 265 / 2, n, 265, 130 + n); + n = labelImage.getHeight(); + parent.getContentPane().add(labelImage); + + n += 40; + + JLabel loginLabel = new JLabel("Login:"); + loginLabel.setBounds(start_label_left, n, 170, size_height_label); + parent.getContentPane().add(loginLabel); + + login = new JTextField(); + login.setBounds(start_label_right, n, end_label_right - start_label_right, size_height_label); + login.setText(parent.getConfiguration().login()); + login.setColumns(20); + parent.getContentPane().add(login); + + n += sep; + + JLabel passwordLabel = new JLabel("Password:"); + passwordLabel.setBounds(start_label_left, n, 170, size_height_label); + parent.getContentPane().add(passwordLabel); + + password = new JPasswordField(); + password.setBounds(start_label_right, n, end_label_right - start_label_right, size_height_label); + password.setText(parent.getConfiguration().password()); + password.setColumns(10); + parent.getContentPane().add(password); + + n += sep; + + JLabel cacheLabel = new JLabel("Working directory"); + cacheLabel.setBounds(start_label_left, n, 240, size_height_label); + parent.getContentPane().add(cacheLabel); + + String destination = DUMMY_CACHE_DIR; + if (config.getUserSpecifiedACacheDir()) { + try { + destination = config.getStorageDir().getCanonicalPath(); + } + catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + cacheDirText = new JLabel(destination); + cacheDirText.setBounds(start_label_right, n, 240, size_height_label); + parent.getContentPane().add(cacheDirText); + + cacheDirChooser = new JFileChooser(); + cacheDirChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + JButton openButton = new JButton("..."); + openButton.addActionListener(new ChooseFileAction()); + openButton.setBounds(end_label_right - 50, n, 50, size_height_label); + parent.getContentPane().add(openButton); + + n += sep; + + JLabel computeMethodLabel = new JLabel("Use"); + computeMethodLabel.setBounds(start_label_left, n, 240, size_height_label); + parent.getContentPane().add(computeMethodLabel); + + ComputeType method = config.getComputeMethod(); + useCPU = new JCheckBox("CPU"); + boolean gpuChecked = false; + + if (method == ComputeType.CPU_GPU) { + useCPU.setSelected(true); + gpuChecked = true; + } + else if (method == ComputeType.CPU_ONLY) { + useCPU.setSelected(true); + gpuChecked = false; + } + else if (method == ComputeType.GPU_ONLY) { + useCPU.setSelected(false); + gpuChecked = true; + } + + int size = 60; + useCPU.setBounds(start_label_right, n, size, size_height_label); + parent.getContentPane().add(useCPU); + + List gpus = GPU.listDevices(); + if (gpus != null) { + for (String model : gpus) { + n += 20; + JCheckBox gpuCheckBox = new JCheckBox(model); + gpuCheckBox.setSelected(gpuChecked); + gpuCheckBox.setBounds(start_label_right, n, 200, size_height_label); + gpuCheckBox.addActionListener(new GpuChangeAction()); + parent.getContentPane().add(gpuCheckBox); + useGPUs.add(gpuCheckBox); + } + } + + n += sep; + + JButton saveButton = new JButton("Start"); + saveButton.setBounds(start_label_right, n, 80, size_height_label); + saveButton.addActionListener(new SaveAction()); + parent.getContentPane().add(saveButton); + + } + + class ChooseFileAction implements ActionListener { + + @Override + public void actionPerformed(ActionEvent arg0) { + int returnVal = cacheDirChooser.showOpenDialog(parent.getContentPane()); + if (returnVal == JFileChooser.APPROVE_OPTION) { + File file = cacheDirChooser.getSelectedFile(); + cacheDir = file; + cacheDirText.setText(cacheDir.getName()); + } + } + } + + class GpuChangeAction implements ActionListener { + + @Override + public void actionPerformed(ActionEvent e) { + for (JCheckBox box : useGPUs) { + if (box.equals(e.getSource()) == false) { + box.setSelected(false); + } + } + } + } + + class SaveAction implements ActionListener { + + @Override + public void actionPerformed(ActionEvent e) { + if (parent == null) { + return; + } + + Configuration config = parent.getConfiguration(); + if (config == null) { + return; + } + + if (cacheDir != null) { + File fromConfig = config.getStorageDir(); + if (fromConfig != null && fromConfig.getAbsolutePath().equals(cacheDir.getAbsolutePath()) == false) { + config.setCacheDir(cacheDir); + } + else { + System.out.println("Activity::Settings::handle do not dir since it did not change (dir: " + cacheDir + ")"); + } + } + + String selected_gpu = null; + for (JCheckBox box : useGPUs) { + if (box.isSelected()) { + selected_gpu = box.getText(); // model + } + } + + ComputeType method = ComputeType.CPU_ONLY; + if (useCPU.isSelected() && selected_gpu == null) { + method = ComputeType.CPU_ONLY; + } + else if (useCPU.isSelected() == false && selected_gpu != null) { + method = ComputeType.GPU_ONLY; + } + else if (useCPU.isSelected() && selected_gpu != null) { + method = ComputeType.CPU_GPU; + } + config.setComputeMethod(method); + + GPUDevice gpu = GPU.getGPUDevice(selected_gpu); + if (gpu != null) { + config.setUseGPU(gpu); + } + + parent.setCredentials(login.getText(), new String(password.getPassword())); + } + } + +} diff --git a/src/com/sheepit/client/standalone/swing/activity/Working.java b/src/com/sheepit/client/standalone/swing/activity/Working.java new file mode 100644 index 0000000..af6ac44 --- /dev/null +++ b/src/com/sheepit/client/standalone/swing/activity/Working.java @@ -0,0 +1,154 @@ +package com.sheepit.client.standalone.swing.activity; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +import javax.imageio.ImageIO; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JLabel; +import com.sheepit.client.Client; +import com.sheepit.client.Server; +import com.sheepit.client.standalone.GuiSwing; +import com.sheepit.client.standalone.GuiSwing.ActivityType; + +public class Working implements Activity { + GuiSwing parent; + + JLabel statusContent; + JLabel renderedFrameContent; + JLabel remainingFrameContent; + JLabel lastRender; + + public Working(GuiSwing parent_) { + parent = parent_; + + statusContent = new JLabel("Init"); + renderedFrameContent = new JLabel("0"); + remainingFrameContent = new JLabel("0"); + + lastRender = new JLabel(); + } + + @Override + public void show() { + int n = 10; + int size_height_label = 24; + int sep = 45; + int start_label_left = 109; + int start_label_right = 280; + int end_label_right = 490; + + ImageIcon image = new ImageIcon(getClass().getResource("/title.png")); + JLabel labelImage = new JLabel(image); + labelImage.setBounds(600 / 2 - 265 / 2, n, 265, 130 + n); + n = labelImage.getHeight(); + parent.getContentPane().add(labelImage); + + n += 40; + + JLabel statusLabel = new JLabel("Status:"); + statusLabel.setBounds(start_label_left, n, 240, size_height_label); + parent.getContentPane().add(statusLabel); + + statusContent.setBounds(start_label_right, n, end_label_right - start_label_right, size_height_label); + parent.getContentPane().add(statusContent); + + n += sep; + + JLabel renderedFrameLabel = new JLabel("Rendered Frame:"); + renderedFrameLabel.setBounds(start_label_left, n, 240, size_height_label); + parent.getContentPane().add(renderedFrameLabel); + + renderedFrameContent.setBounds(start_label_right, n, end_label_right - start_label_right, size_height_label); + parent.getContentPane().add(renderedFrameContent); + + n += sep; + + JLabel remainingFrameLabel = new JLabel("Remaining Frame:"); + remainingFrameLabel.setBounds(start_label_left, n, 240, size_height_label); + parent.getContentPane().add(remainingFrameLabel); + + remainingFrameContent.setBounds(start_label_right, n, end_label_right - start_label_right, size_height_label); + parent.getContentPane().add(remainingFrameContent); + + n += sep; + + JLabel lastRenderedFrameLabel = new JLabel("Last rendered frame:"); + lastRenderedFrameLabel.setBounds(start_label_left, n, 240, size_height_label); + parent.getContentPane().add(lastRenderedFrameLabel); + + lastRender.setBounds(start_label_right, n, 200, 112); + parent.getContentPane().add(lastRender); + + JButton settingsButton = new JButton("Settings"); + settingsButton.setBounds(220, 500, 100, 25); + settingsButton.addActionListener(new SettingsAction()); + parent.getContentPane().add(settingsButton); + + JButton pauseButton = new JButton("Pause"); + pauseButton.setBounds(330, 500, 80, 25); + pauseButton.addActionListener(new PauseAction()); + parent.getContentPane().add(pauseButton); + } + + public void setStatus(String msg_) { + statusContent.setText(msg_); + } + + public void setRemainingFrame(int n) { + remainingFrameContent.setText(String.valueOf(n)); + } + + public void setRenderedFrame(int n) { + renderedFrameContent.setText(String.valueOf(n)); + showLastRender(); + } + + public void showLastRender() { + Client client = parent.getClient(); + if (client != null) { + Server server = client.getServer(); + if (server != null) { + byte[] data = server.getLastRender(); + if (data != null) { + InputStream is = new ByteArrayInputStream(data); + try { + BufferedImage image = ImageIO.read(is); + lastRender.setIcon(new ImageIcon(image)); + } + catch (IOException e) { + System.out.println("Working::showLastRender() exception " + e); + e.printStackTrace(); + } + } + } + } + + } + + class PauseAction implements ActionListener { + + @Override + public void actionPerformed(ActionEvent e) { + Client client = parent.getClient(); + if (client != null) { + client.suspend(); + } + } + } + + class SettingsAction implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + if (parent != null) { + parent.showActivity(ActivityType.SETTINGS); + } + } + } + +}