/* * Copyright 2013-2016 consulo.io * * Licensed under the Apache License, Version 2.0 (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-2.0 * * 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. */ package consulo.unity3d.run.debugger; import java.awt.BorderLayout; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import javax.swing.Icon; import javax.swing.JComponent; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import com.intellij.ide.util.ChooseElementsDialog; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.components.JBCheckBox; import com.intellij.util.concurrency.AppExecutorUtil; import com.intellij.util.ui.UIUtil; import com.intellij.xdebugger.impl.settings.XDebuggerSettingManagerImpl; import com.jezhumble.javasysmon.JavaSysMon; import com.jezhumble.javasysmon.ProcessInfo; import consulo.annotations.DeprecationInfo; import consulo.unity3d.Unity3dBundle; import consulo.unity3d.Unity3dIcons; /** * @author VISTALL * @since 18.11.14 */ public class UnityProcessDialog extends ChooseElementsDialog<UnityProcess> { private static final Logger LOGGER = Logger.getInstance(UnityProcessDialog.class); private Future<?> myTask; @Deprecated private boolean myShowConfigBox; public UnityProcessDialog(@NotNull Project project) { super(project, new ArrayList<>(), "Select Unity Process", "", true); } @Deprecated @DeprecationInfo("Deprecated constructor, will be dropped with old attach support") public UnityProcessDialog(@NotNull Project project, boolean showConfigBox) { super(project, new ArrayList<>(), "Select Unity Process", "", true); myShowConfigBox = true; } @Override public void show() { myTask = AppExecutorUtil.getAppScheduledExecutorService().scheduleWithFixedDelay((Runnable) () -> UIUtil.invokeLaterIfNeeded(() -> { List<UnityProcess> selectedElements = myChooser.getSelectedElements(); UnityProcessDialog.this.setElements(collectItems(), selectedElements); }), 0, 1, TimeUnit.SECONDS); super.show(); } @NotNull public static List<UnityProcess> collectItems() { Collection<UnityPlayer> players = UnityPlayerService.getInstance().getPlayers(); List<UnityProcess> items = new ArrayList<>(players.size() + 1); try { for(UnityPlayer player : players) { if(player.isSupportDebugging()) { items.add(new UnityProcess((int) player.getGuid(), player.getId(), player.getIp(), player.getDebuggerPort())); } } JavaSysMon javaSysMon = new JavaSysMon(); ProcessInfo[] processInfos = javaSysMon.processTable(); for(ProcessInfo processInfo : processInfos) { String name = processInfo.getName(); if((StringUtil.startsWithIgnoreCase(name, "unity") || StringUtil.containsIgnoreCase(name, "Unity.app")) && !(StringUtil.containsIgnoreCase(name, "Unity") && StringUtil .containsIgnoreCase(name, "Helper")) //ignore 'UnityHelper' and 'Unity Helper' && !StringUtil.containsIgnoreCase(name, "UnityShader")) { items.add(new UnityProcess(processInfo.getPid(), name, "localhost", buildDebuggerPort(processInfo.getPid()))); } } } catch(Exception e) { LOGGER.error(e); } return items; } public static int buildDebuggerPort(int pid) { return 56000 + pid % 1000; } @Override protected JComponent createCenterPanel() { JComponent centerPanel = super.createCenterPanel(); assert centerPanel != null; if(myShowConfigBox) { final Unity3dDebuggerSettings settings = XDebuggerSettingManagerImpl.getInstanceImpl().getSettings(Unity3dDebuggerSettings.class); final JBCheckBox comp = new JBCheckBox(Unity3dBundle.message("attach.to.single.process.without.dialog.box"), settings.myAttachToSingleProcessWithoutDialog); comp.addChangeListener(e -> settings.myAttachToSingleProcessWithoutDialog = comp.isSelected()); centerPanel.add(comp, BorderLayout.SOUTH); } return centerPanel; } @Nullable @Override protected String getDimensionServiceKey() { return getClass().getSimpleName(); } @Override protected void dispose() { if(myTask != null) { myTask.cancel(false); } super.dispose(); } @Override protected String getItemText(UnityProcess item) { return item.getName() + " (" + item.getHost() + ":" + item.getPort() + ")"; } @Nullable @Override protected Icon getItemIcon(UnityProcess item) { return Unity3dIcons.Unity3d; } }