упорядочил папки с кодом.
This commit is contained in:
@@ -1,444 +0,0 @@
|
||||
package Visual_DVM_2021.Passes;
|
||||
import Common.Current;
|
||||
import Common.Global;
|
||||
import Common.UI.DebugPrintLevel;
|
||||
import Common.UI.Menus_2023.PassButton;
|
||||
import Common.UI.Menus_2023.PassControl;
|
||||
import Common.UI.Menus_2023.StablePassMenuItem;
|
||||
import Common.UI.UI;
|
||||
import Common.Utils.Stopwatch;
|
||||
import Common.Utils.TextLog;
|
||||
import Common.Utils.Utils;
|
||||
import Visual_DVM_2021.PassStats.PassStats;
|
||||
import Visual_DVM_2021.Passes.UI.PassForm;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Stack;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.Semaphore;
|
||||
public class Pass_2021<T> {
|
||||
public static Vector<Pass_2021> FAPasses = new Vector<>();
|
||||
//</editor-fold>
|
||||
//-
|
||||
public static LinkedHashMap<PassCode_2021, Pass_2021> passes = new LinkedHashMap<>();
|
||||
public PassStats stats = null;
|
||||
public int callsCount = 0; //число вызовов прохода за текущий сеанс визуализатора.
|
||||
public T target; //главный аргумент.
|
||||
public PassState state = PassState.Inactive; //текущее состояние прохода.
|
||||
public Semaphore animation_sem;
|
||||
//--------------
|
||||
public Vector<PassControl> controls = new Vector<>();
|
||||
protected TextLog Log; //внутренний журнал прохода.
|
||||
protected boolean interrupt;
|
||||
protected SwingWorker dispatcher = null;
|
||||
private PassForm form = null;
|
||||
protected JMenuItem menuItem = null;
|
||||
private JButton button = null;
|
||||
private JButton tabButton = null;
|
||||
private Exception last_error; //последнее пойманное исключение выполнения.
|
||||
//->>
|
||||
public static Throwable getCauseRec(Throwable ex) {
|
||||
Throwable cause = ex.getCause();
|
||||
return (cause == null) ? ex : getCauseRec(cause);
|
||||
}
|
||||
public static void setPassesControlsVisible(boolean flag, PassCode_2021... codes_in) {
|
||||
for (PassCode_2021 code_in : codes_in)
|
||||
passes.get(code_in).setControlsVisible(flag);
|
||||
}
|
||||
//важно. вызывать только если есть интерфейс.
|
||||
public static void CheckAllStats() throws Exception {
|
||||
for (Pass_2021 pass : FAPasses) {
|
||||
if (!Global.db.passStats.Data.containsKey(pass.code()))
|
||||
Global.db.Insert(pass.stats = new PassStats(pass));
|
||||
else pass.stats = Global.db.passStats.Data.get(pass.code());
|
||||
}
|
||||
FAPasses.sort(new SortPassesByStats());
|
||||
}
|
||||
public static void CreateAll() {
|
||||
for (PassCode_2021 code : PassCode_2021.values()) {
|
||||
if (code != PassCode_2021.Undefined) {
|
||||
try {
|
||||
Class<?> clazz = Class.forName("Visual_DVM_2021.Passes.All." + code.toString());
|
||||
Pass_2021 pass = ((Pass_2021) clazz.newInstance());
|
||||
passes.put(code, pass);
|
||||
if (pass.hasStats())
|
||||
FAPasses.add(pass);
|
||||
} catch (Exception ex) {
|
||||
Global.Log.PrintException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//<editor-fold desc="Интерфейс">
|
||||
//https://www.delftstack.com/ru/howto/java/java-resize-image/
|
||||
public String getIconPath() {
|
||||
return null;
|
||||
}
|
||||
public Icon getTabIcon(){
|
||||
return Utils.getTabIcon(getIconPath());
|
||||
}
|
||||
public AbstractAction getControlAction() {
|
||||
return new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
UpdateStatsIfNeed();
|
||||
Do();
|
||||
}
|
||||
};
|
||||
}
|
||||
public String getButtonText() {
|
||||
return getDescription();
|
||||
}
|
||||
public JMenuItem createMenuItem() {
|
||||
if (menuItem == null)
|
||||
menuItem = new StablePassMenuItem(this);
|
||||
return menuItem;
|
||||
}
|
||||
public JButton createButton() {
|
||||
if (button == null)
|
||||
button = new PassButton(this);
|
||||
return button;
|
||||
}
|
||||
public JButton createTabButton() {
|
||||
if (tabButton == null)
|
||||
tabButton = new PassButton(this, true);
|
||||
return tabButton;
|
||||
}
|
||||
public void setControlsEnabled(boolean flag) {
|
||||
for (PassControl control : controls)
|
||||
control.setEnabled(flag);
|
||||
}
|
||||
public void setControlsVisible(boolean flag) {
|
||||
for (PassControl control : controls)
|
||||
control.setVisible(flag);
|
||||
}
|
||||
public void setControlsToolTipText(String text) {
|
||||
for (PassControl control : controls)
|
||||
control.setToolTipText(text);
|
||||
}
|
||||
protected void FocusResult() {
|
||||
}
|
||||
protected boolean hasStats() {
|
||||
return false;
|
||||
}
|
||||
public void UpdateStatsIfNeed() {
|
||||
if (hasStats()) {
|
||||
stats.Inc();
|
||||
try {
|
||||
Global.db.Update(stats);
|
||||
FAPasses.sort(new SortPassesByStats());
|
||||
if (Current.HasProject())
|
||||
UI.fastAccessMenuBar.Refresh();
|
||||
} catch (Exception ex) {
|
||||
Global.Log.PrintException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
public PassCode_2021 code() {
|
||||
return PassCode_2021.valueOf(getClass().getSimpleName());
|
||||
}
|
||||
public boolean isDone() {
|
||||
return state == PassState.Done;
|
||||
}
|
||||
public void setDone() {
|
||||
state = PassState.Done;
|
||||
}
|
||||
public String getDescription() {
|
||||
return code().getDescription();
|
||||
}
|
||||
public String getStartDescription() {
|
||||
return getDescription();
|
||||
}
|
||||
protected void FocusBeforeStart() {
|
||||
//отображение вкладок.
|
||||
}
|
||||
//-
|
||||
//объединение старых методов InitArgs и CanStart. зачастую семантика у них пересекалась.
|
||||
protected boolean canStart(Object... args) throws Exception {
|
||||
return true;
|
||||
}
|
||||
//-
|
||||
protected void body() throws Exception {
|
||||
}
|
||||
protected boolean validate() {
|
||||
return true;
|
||||
}
|
||||
//-
|
||||
protected void performCanNotStart() throws Exception {
|
||||
}
|
||||
protected void showCanNotStart() throws Exception {
|
||||
}
|
||||
protected void performPreparation() throws Exception {
|
||||
}
|
||||
protected void showPreparation() throws Exception {
|
||||
}
|
||||
protected void performFinish() throws Exception {
|
||||
}
|
||||
protected void showFinish() throws Exception {
|
||||
}
|
||||
protected void performDone() throws Exception {
|
||||
}
|
||||
protected void showDone() throws Exception {
|
||||
}
|
||||
protected void performFail() throws Exception {
|
||||
}
|
||||
protected void showFail() throws Exception {
|
||||
}
|
||||
//-
|
||||
private void PerformCanNotStart() throws Exception {
|
||||
performCanNotStart();
|
||||
if (Current.hasUI())
|
||||
showCanNotStart();
|
||||
}
|
||||
protected void PerformPreparation() throws Exception {
|
||||
performPreparation();
|
||||
if (Current.hasUI())
|
||||
showPreparation();
|
||||
}
|
||||
private void PerformFinish() throws Exception {
|
||||
performFinish();
|
||||
//-
|
||||
if (Current.hasUI())
|
||||
showFinish();
|
||||
}
|
||||
private void PerformDone() throws Exception {
|
||||
performDone();
|
||||
//-
|
||||
if (Current.hasUI())
|
||||
showDone();
|
||||
}
|
||||
private void PerformFail() throws Exception {
|
||||
performFail();
|
||||
//-
|
||||
if (Current.hasUI())
|
||||
showFail();
|
||||
}
|
||||
//------
|
||||
protected PassCode_2021 necessary() {
|
||||
return null;
|
||||
}
|
||||
protected boolean resetsNecessary() {
|
||||
return false;
|
||||
}
|
||||
public void Reset() {
|
||||
if (state == PassState.Done)
|
||||
state = PassState.Inactive;
|
||||
}
|
||||
//------
|
||||
protected void createStack_r(Stack<Pass_2021> ToDo, Vector<String> ToPrint) {
|
||||
ToDo.push(this);
|
||||
if (needsConfirmations() // если UI нет, сюда он не дойдет.
|
||||
) {
|
||||
ToPrint.add(this.getStartDescription());
|
||||
}
|
||||
if (necessary() != null) {
|
||||
Pass_2021 next = passes.get(necessary());
|
||||
if (resetsNecessary() || !next.isDone())
|
||||
next.createStack_r(ToDo, ToPrint);
|
||||
}
|
||||
}
|
||||
public boolean Do(Object... args) {
|
||||
Stack<Pass_2021> ToDo = new Stack<>();
|
||||
Vector<String> ToPrint = new Vector<>();
|
||||
createStack_r(ToDo, ToPrint);
|
||||
if (Global.properties.ConfirmPassesStart && !ToPrint.isEmpty() &&
|
||||
!UI.Question("Выполнить проход(ы):\n" + String.join("\n", ToPrint))
|
||||
) return false;
|
||||
while (ToDo.size() > 1) {
|
||||
if (!ToDo.pop().start()) return false;
|
||||
}
|
||||
if (start(args)) {
|
||||
if (Global.properties.FocusPassesResult)
|
||||
FocusResult();
|
||||
//-
|
||||
if (Global.properties.ShowPassesDone && !ToPrint.isEmpty()
|
||||
) {
|
||||
UI.Info("Проход(ы)\n\n" + String.join("\n", ToPrint) +
|
||||
"\nуспешно выполнен(ы)!");
|
||||
}
|
||||
//-
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//-
|
||||
//<editor-fold desc="Анимация">
|
||||
protected boolean needsAnimation() {
|
||||
return false;
|
||||
}
|
||||
public void Interrupt() throws Exception {
|
||||
UI.Info("Проход " + Utils.Brackets(getDescription()) + " не разрешено прерывать.");
|
||||
}
|
||||
public boolean needsConfirmations() {
|
||||
return false;
|
||||
}
|
||||
//</editor-fold>
|
||||
//-
|
||||
protected void CheckException(Exception ex) {
|
||||
if (ex instanceof PassException) {
|
||||
Log.Writeln_(ex.getMessage());
|
||||
} else
|
||||
Global.Log.PrintException(ex);
|
||||
}
|
||||
public boolean start(Object... args) {
|
||||
//------------------------------->
|
||||
interrupt = false;
|
||||
callsCount++;
|
||||
Stopwatch timer = new Stopwatch();
|
||||
state = PassState.Inactive;
|
||||
last_error = null;
|
||||
target = null;
|
||||
Log = new TextLog();
|
||||
if (!getDescription().isEmpty())
|
||||
Global.Log.Print(DebugPrintLevel.Passes, getDescription() + " стартует..");
|
||||
timer.Start();
|
||||
//------------------------------->
|
||||
try {
|
||||
if (Current.hasUI()) FocusBeforeStart();
|
||||
if (canStart(args)) {
|
||||
PerformPreparation();
|
||||
//todo тут должна быть вилка на анимацию?
|
||||
if (Current.hasUI() && needsAnimation()) {
|
||||
animation_sem = new Semaphore(1);
|
||||
animation_sem.acquire();
|
||||
//---
|
||||
form = null;
|
||||
Current.set(Current.PassForm, null);
|
||||
System.gc();
|
||||
//--
|
||||
Current.set(Current.PassForm, form = new PassForm(this));
|
||||
dispatcher = new SwingWorker() {
|
||||
@Override
|
||||
protected Object doInBackground() {
|
||||
// UI.Print(DebugPrintLevel.Passes, "фоновое выполнение началось");
|
||||
try {
|
||||
body();
|
||||
} catch (Exception ex) {
|
||||
last_error = ex;
|
||||
}
|
||||
// UI.Print(DebugPrintLevel.Passes, "Ожидание активации окна анимации ");
|
||||
//ждем пока окно откроется и освободит его.
|
||||
try {
|
||||
animation_sem.acquire();
|
||||
} catch (InterruptedException e) {
|
||||
Global.Log.PrintException(e);
|
||||
}
|
||||
//и уничтожаем его.
|
||||
// UI.Print(DebugPrintLevel.Passes, "Окно анимации активировано.");
|
||||
form.dispose();
|
||||
form = null;
|
||||
// UI.Print(DebugPrintLevel.Passes, "Окно анимации закрыто.");
|
||||
animation_sem.release();
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
protected void done() {
|
||||
//тут ничего не анализируем. события - отдельный поток. тут это не нужно
|
||||
}
|
||||
};
|
||||
dispatcher.execute();
|
||||
form.ShowDialog();
|
||||
// UI.Print(DebugPrintLevel.Passes, "фоновое выполнение закончено, обработка резульатов");
|
||||
if (last_error != null) {
|
||||
state = PassState.Crushed;
|
||||
CheckException(last_error);
|
||||
}
|
||||
// UI.Print(DebugPrintLevel.Passes, "OK");
|
||||
dispatcher = null;
|
||||
} else {
|
||||
//исключения во время выполнения возможны в штатном режиме.
|
||||
try {
|
||||
body();
|
||||
} catch (Exception ex) {
|
||||
state = PassState.Crushed;//упал при выполнении.
|
||||
CheckException(ex);
|
||||
}
|
||||
}
|
||||
//---
|
||||
// UI.Info(this.getClass().getSimpleName()+" +");
|
||||
PerformFinish();
|
||||
// UI.Info(this.getClass().getSimpleName()+" ++");
|
||||
//---
|
||||
if ((state != PassState.Crushed) && validate()) {
|
||||
state = PassState.Done;
|
||||
PerformDone();
|
||||
} else {
|
||||
state = PassState.Failed;
|
||||
PerformFail();
|
||||
}
|
||||
} else {
|
||||
state = PassState.CantStart;
|
||||
PerformCanNotStart();
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
state = PassState.ExternalCrushed;
|
||||
Global.Log.PrintException(ex);
|
||||
}
|
||||
//------------------------------->
|
||||
timer.Stop();
|
||||
if (!getDescription().isEmpty()) {
|
||||
Global.Log.Print(DebugPrintLevel.Passes,
|
||||
getDescription() +
|
||||
" окончен за " + timer.Print() +
|
||||
" состояние " + Utils.Brackets(state.getDescription())
|
||||
);
|
||||
if (!Log.isEmpty() && Current.hasUI())
|
||||
UI.Error(
|
||||
"проход " + Utils.Brackets(getDescription()) + "\n" + state.getDescription() + "\n\n" +
|
||||
Log.toString());
|
||||
}
|
||||
//------------------------------->
|
||||
return isDone();
|
||||
}
|
||||
//--
|
||||
public void ShowSapforMessage(String message) {
|
||||
if (Current.hasUI() && form != null) {
|
||||
String[] data = message.split(":");
|
||||
switch (data[0]) {
|
||||
case "message_1":
|
||||
form.fields.Label1.setText((data.length > 1) ? data[1] : "");
|
||||
break;
|
||||
case "message_2":
|
||||
form.fields.Label2.setText((data.length > 1) ? data[1] : "");
|
||||
break;
|
||||
case "progress":
|
||||
form.fields.ProgressBar.setValue((data.length > 1) ? Integer.parseInt(data[1]) : 0);
|
||||
break;
|
||||
}
|
||||
} else System.out.println(Utils.Brackets(message));
|
||||
}
|
||||
public void ShowMessage1(String message) {
|
||||
if (form != null)
|
||||
form.fields.Label1.setText((message.length() > 1) ? message : "");
|
||||
else System.out.println(Utils.Brackets(message));
|
||||
}
|
||||
public void ShowMessage2(String message) {
|
||||
if (form != null)
|
||||
form.fields.Label2.setText((message.isEmpty() ? "" : message));
|
||||
else System.out.println(Utils.Brackets(message));
|
||||
}
|
||||
public void ShowProgress(int total, int current, boolean auto) {
|
||||
if (form != null) {
|
||||
form.lTitle.setText(getDescription() + " " + (current + 1) + "/" + total);
|
||||
if (auto) {
|
||||
double dp = ((double) current / total) * 100;
|
||||
int p = (int) dp;
|
||||
form.fields.ProgressBar.setValue(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void ShowProgress2(int total, int current, String comment) {
|
||||
if (form != null) {
|
||||
form.fields.Label2.setText(comment + " " + current + "/" + total);
|
||||
double dp = ((double) current / total) * 100;
|
||||
int p = (int) dp;
|
||||
form.fields.ProgressBar.setValue(p);
|
||||
}
|
||||
}
|
||||
public void ShowProgressTextOnly(int total, int current, String comment) {
|
||||
if (form != null)
|
||||
form.lTitle.setText(form.lTitle.getText() + " : " + comment + " " + current + "/" + total);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user