Skip to content

Commit

Permalink
"Clearing folder" step now is shown in the DBPF unpack progress bar. …
Browse files Browse the repository at this point in the history
…Fixed bugs in the project view. Version 2.1.7
  • Loading branch information
emd4600 committed Nov 9, 2019
1 parent 9279ab4 commit 5f17fe8
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 30 deletions.
3 changes: 2 additions & 1 deletion reg_file.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77667,4 +77667,5 @@ DeformAxleLength
sail
jetengine
Nudge
GlobalEditorUI
GlobalEditorUI
CreatureDetailTemplate
17 changes: 15 additions & 2 deletions src/sporemodder/ProjectManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,8 @@ public void setUI(ProjectTreeUI treeUI) {

showModdedOnlyProperty().addListener((obs, oldValue, newValue) -> {
projectSearcher.setOnlyModFiles(newValue);
if (activeProject != null) activeProject.setShowOnlyModded(newValue);
treeUI.getTreeView().scrollTo(treeUI.getTreeView().getRow(treeUI.getTreeView().getSelectionModel().getSelectedItem()));
});
}

Expand Down Expand Up @@ -858,6 +860,9 @@ public void setActive(Project project) {
UIManager.get().getUserInterface().setStatusFile(null);
UIManager.get().getUserInterface().setStatusInfo(null);

treeUI.getSearchField().setText("");
treeUI.getShowModdedBox().setSelected(activeProject.isShowOnlyModded());

refreshProjectTree();

EditorManager.get().loadFixedTabs(project.getFixedTabPaths());
Expand Down Expand Up @@ -1318,11 +1323,10 @@ public void unpackPresets(List<ProjectPreset> presets) {

// Create the project or override the existing one
final Project project = getOrCreateProject(preset.getName());
ProjectManager.get().initializeProject(project);
project.setReadOnly(true);

// The project is passed to set the 'packageSignature' setting, but we don't want that in presets
final DBPFUnpackingTask task = new DBPFUnpackingTask(files.values(), project.getFolder(), null, converters);
final DBPFUnpackingTask task = new DBPFUnpackingTask(files.values(), project.getFolder(), project, converters);

task.setItemFilter(preset.getItemFilter());

Expand Down Expand Up @@ -1656,6 +1660,9 @@ public boolean removeItem(ProjectItem item) throws IOException {
EditorManager.get().reloadEditor(filePath);
}

ProjectTreeItem parentItem = (ProjectTreeItem) item.getTreeItem().getParent();
if (parentItem != null) parentItem.invalidatePredicate();

// Repaint tree
UIManager.get().getUserInterface().getProjectTree().getTreeView().refresh();

Expand Down Expand Up @@ -1961,6 +1968,12 @@ public boolean refreshItem(ProjectItem item) throws IOException {

// Reloading the nodes
((ProjectTreeItem) treeItem).requestReload();

if (!searchedWords.isEmpty()) {
// Search the new nodes
projectSearcher.startSearch(treeItem);
}

// If it is expanded we need to ensure its children are reloaded
if (treeItem.isExpanded()) {
treeItem.setExpanded(false);
Expand Down
2 changes: 1 addition & 1 deletion src/sporemodder/UpdateManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public class UpdateManager {
*/
public static final TimeZone TIMEZONE = TimeZone.getTimeZone("UTC");

public final VersionInfo versionInfo = new VersionInfo(2, 1, 6, null);
public final VersionInfo versionInfo = new VersionInfo(2, 1, 7, null);

public static UpdateManager get() {
return MainApp.get().getUpdateManager();
Expand Down
45 changes: 37 additions & 8 deletions src/sporemodder/file/dbpf/DBPFUnpackingTask.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import emord.filestructures.StreamReader;
import sporemodder.HashManager;
import sporemodder.MessageManager;
import sporemodder.ProjectManager;
import sporemodder.MessageManager.MessageType;
import sporemodder.file.Converter;
import sporemodder.file.ResourceKey;
Expand All @@ -54,7 +55,9 @@ public static interface DBPFItemFilter {
}

/** The estimated progress (in [0, 1]) that reading the index takes. */
private static final double INDEX_PROGRESS = 0.15;
private static final double INDEX_PROGRESS = 0.05;
/** The estimated progress (in [0, 1]) that clearing the folder takes. */
private static final double CLEAR_FOLDER_PROGRESS = 0.10;

// Cannot use getProgress() as it throws thread exception
private double progress = 0;
Expand Down Expand Up @@ -85,6 +88,8 @@ public static interface DBPFItemFilter {

private Project project;

private boolean setPackageSignature;

//TODO it's faster, but apparently it causes problems; I can't reproduce the bug
private boolean isParallel = true;

Expand All @@ -111,6 +116,10 @@ public DBPFUnpackingTask(StreamReader inputStream, File outputFolder, Project pr
this.project = project;
}

public void setPackageSignature(boolean value) {
setPackageSignature = value && project != null;
}

/**
* Returns a list of all the converters that will be used when unpacking files.
* On every file, if the converter {@link Converter.isDecoder()} method returns true, it will be used to decode the file.
Expand Down Expand Up @@ -190,10 +199,16 @@ private void unpackStream(StreamReader packageStream, Map<Integer, Set<ResourceK

System.out.println("File index successfully read, " + index.items.size() + " items.");

incProgress(INDEX_PROGRESS / inputFiles.size());
double inc = 1.0;

if (project != null) {
incProgress((1.0 - CLEAR_FOLDER_PROGRESS) * INDEX_PROGRESS / inputFiles.size());
inc -= CLEAR_FOLDER_PROGRESS;
}

updateMessage("Unpacking files...");

double inc = ((1.0 - INDEX_PROGRESS) / header.indexCount) / inputFiles.size();
inc = (inc * (1.0 - INDEX_PROGRESS) / header.indexCount) / inputFiles.size();

//First search sporemaster/names.txt, and use it if it exists
hasher.getProjectRegistry().clear();
Expand All @@ -208,17 +223,20 @@ private void unpackStream(StreamReader packageStream, Map<Integer, Set<ResourceK

if (itemFilter != null && !itemFilter.filter(item)) {
latch.countDown();
incProgress(inc);
continue;
}

int groupID = item.name.getGroupID();
int instanceID = item.name.getInstanceID();

// Skip files if they have already been written by higher priority packages
if (writtenFiles != null) {
Set<ResourceKey> groupSet = writtenFiles.get(groupID);
if (groupSet != null) {
if (groupSet.contains(item.name)) {
latch.countDown();
incProgress(inc);
continue;
}
}
Expand All @@ -229,6 +247,7 @@ private void unpackStream(StreamReader packageStream, Map<Integer, Set<ResourceK
// skip autolocale files
if (groupID == 0x02FABF01 && fileName.startsWith("auto_")) {
latch.countDown();
incProgress(inc);
continue;
}

Expand Down Expand Up @@ -264,9 +283,6 @@ private void unpackStream(StreamReader packageStream, Map<Integer, Set<ResourceK

// Remove the extra names; if they need to be used, loading the project will load them as well
hasher.getProjectRegistry().clear();

// Remove the extra names; if they need to be used, loading the project will load them as well
hasher.getProjectRegistry().clear();
}

@Override
Expand All @@ -280,13 +296,26 @@ protected Exception call() throws Exception {
unpackStream(inputStream, null);
}
else {
double progressInc = 1.0;

if (project != null) {
updateMessage("Clearing folder...");
ProjectManager.get().initializeProject(project);
incProgress(CLEAR_FOLDER_PROGRESS);

progressInc -= CLEAR_FOLDER_PROGRESS;
}

progressInc = progressInc / inputFiles.size();

final HashMap<Integer, Set<ResourceKey>> writtenFiles = new HashMap<>();
boolean checkFiles = inputFiles.size() > 1; // only check already existing files if we are unpacking more than one package at once

for (File inputFile : inputFiles) {
System.out.println("## UNPACKNG " + inputFile.getName());

if (!inputFile.exists()) {
incProgress(100.0f / inputFiles.size());
incProgress(progressInc);
failedDBPFs.add(inputFile);
continue;
}
Expand Down Expand Up @@ -370,7 +399,7 @@ private class FileConvertAction extends RecursiveAction {

// Do not convert editor packages
if (groupID == 0x40404000 && item.name.getTypeID() == 0x00B1B104) {
if (project != null) {
if (setPackageSignature) {
for (PackageSignature entry : PackageSignature.values()) {
if (entry.getFileName() != null && hasher.fnvHash(entry.getFileName()) == instanceID) {
project.setPackageSignature(entry);
Expand Down
9 changes: 9 additions & 0 deletions src/sporemodder/util/Project.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ public enum PackageSignature {
private static final String PROPERTY_packageName = "packageName";
private static final String PROPERTY_packageSignature = "embeddedEditorPackages"; // for compatibility
private static final String PROPERTY_isReadOnly = "isReadOnly";
private static final String PROPERTY_showOnlyModded = "showOnlyModded";

/** The name of the project, which is taken from the folder name. */
private String name;
Expand Down Expand Up @@ -279,6 +280,14 @@ public void setReadOnly(boolean isReadOnly) {
public List<String> getFixedTabPaths() {
return fixedTabPaths;
}

public boolean isShowOnlyModded() {
return Boolean.parseBoolean(settings.getProperty(PROPERTY_showOnlyModded, "False"));
}

public void setShowOnlyModded(boolean value) {
settings.setProperty(PROPERTY_showOnlyModded, Boolean.toString(value));
}

/**
* Returns the last time this project was active in the program, in milliseconds.
Expand Down
31 changes: 19 additions & 12 deletions src/sporemodder/util/ProjectSearcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
import javafx.beans.property.ReadOnlyBooleanWrapper;
import javafx.beans.property.ReadOnlyDoubleProperty;
import javafx.beans.property.ReadOnlyDoubleWrapper;
import javafx.beans.property.ReadOnlyIntegerWrapper;
import sporemodder.FileManager;
import sporemodder.view.ProjectTreeItem;

Expand Down Expand Up @@ -226,11 +225,12 @@ protected void compute() {
long time = System.currentTimeMillis();

// The given item is expected to have its children loaded
List<ItemSearchRecursive> tasks = new ArrayList<ItemSearchRecursive>();
for (ProjectTreeItem child : item.getInternalChildren()) {
tasks.add(new ItemSearchRecursive(child, null, 1.0 / progressMax));
}
ForkJoinTask.invokeAll(tasks);
// List<ItemSearchRecursive> tasks = new ArrayList<ItemSearchRecursive>();
// for (ProjectTreeItem child : item.getInternalChildren()) {
// tasks.add(new ItemSearchRecursive(child, null, 1.0 / progressMax));
// }
// ForkJoinTask.invokeAll(tasks);
new ItemSearchRecursive(item, null, 1.0 / progressMax, true).invoke();

time = System.currentTimeMillis() - time;

Expand All @@ -252,32 +252,39 @@ private class ItemSearchRecursive extends RecursiveTask<Boolean> {
private final ProjectTreeItem item;
private final boolean[] foundWords;
private final double progressIncrement;
// Roots don't add increment, but pass the increment to their children
private final boolean isSearchRoot;

public ItemSearchRecursive(ProjectTreeItem item, boolean[] foundWords, double progressIncrement) {
public ItemSearchRecursive(ProjectTreeItem item, boolean[] foundWords, double progressIncrement, boolean isSearchRoot) {
super();
this.item = item;
this.foundWords = new boolean[wordBytes.length];
this.progressIncrement = progressIncrement;
this.isSearchRoot = isSearchRoot;
if (foundWords != null) {
System.arraycopy(foundWords, 0, this.foundWords, 0, foundWords.length);
}
}

public ItemSearchRecursive(ProjectTreeItem item, boolean[] foundWords, double progressIncrement) {
this(item, foundWords, progressIncrement, false);
}

@Override protected Boolean compute() {
if (!internalIsSearching) return false;

numItemsSearched++;
//System.out.println("Items: " + numItemsSearched + "\t[" + item.getValue().getName() + "]");

boolean matches = searchInNameOptional(item.getValue().name, foundWords);
// We want to search in the name if the search root is not the project root
boolean matches = (isSearchRoot && item.getValue().isRoot) ? false : searchInNameOptional(item.getValue().name, foundWords);
File file = item.getValue().getFile();

if (matches) {
// If the name matches, all its children must be shown (and we don't need to search in them)
item.propagateMatchesSearch(matches);
}
else {
if (file.isFile()) {
if (file != null && file.isFile()) {
if (FileManager.get().isSearchable(file.getName()) && isExtensiveSearch) {
try {
matches = searchInFile(file, foundWords);
Expand All @@ -290,7 +297,7 @@ else if (item.isLoaded()) {
// We must search in all children
List<ItemSearchRecursive> tasks = new ArrayList<ItemSearchRecursive>();
for (ProjectTreeItem child : item.getInternalChildren()) {
tasks.add(new ItemSearchRecursive(child, foundWords, 0.0));
tasks.add(new ItemSearchRecursive(child, foundWords, isSearchRoot ? progressIncrement : 0.0));
}

//System.out.println(tasks.size() + " tasks scheduled");
Expand All @@ -309,7 +316,7 @@ else if (item.isLoaded()) {
}
}

if (progressIncrement != 0.0) {
if (!isSearchRoot && progressIncrement != 0.0) {
progress.setValue(progress.getValue() + progressIncrement);
}

Expand Down
13 changes: 11 additions & 2 deletions src/sporemodder/view/ProjectTreeItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
Expand All @@ -41,6 +42,8 @@ public class ProjectTreeItem extends TreeItem<ProjectItem> {
private final FilteredList<ProjectTreeItem> filteredList = new FilteredList<>(sourceList);
private final ReadOnlyObjectWrapper<TreeItemPredicate> predicate = new ReadOnlyObjectWrapper<>();

private ObjectBinding<? extends Predicate<ProjectTreeItem>> predicateBinding;

private boolean matchesSearch = false;

public ProjectTreeItem(ProjectItem item) {
Expand Down Expand Up @@ -117,7 +120,7 @@ public ObservableList<ProjectTreeItem> getInternalChildren() {
public final void setPredicate(TreeItemPredicate predicate, Observable ... dependencies) {
this.predicate.set(predicate);

filteredList.predicateProperty().bind(Bindings.createObjectBinding(() -> {
predicateBinding = Bindings.createObjectBinding(() -> {
return child -> {

// Set the predicate of child items to force filtering
Expand All @@ -131,7 +134,13 @@ public final void setPredicate(TreeItemPredicate predicate, Observable ... depen
// Otherwise ask the TreeItemPredicate
return this.predicate.get().test(this, child.getValue());
};
}, dependencies));
}, dependencies);

filteredList.predicateProperty().bind(predicateBinding);
}

public void invalidatePredicate() {
predicateBinding.invalidate();
}

public final ObjectProperty<Predicate<? super ProjectTreeItem>> predicateProperty() {
Expand Down
3 changes: 0 additions & 3 deletions src/sporemodder/view/dialogs/UnpackPackageUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,6 @@ private void showInternal(File packageFile) {

final Project project = p;

// Create already deletes the existing content if any
ProjectManager.get().initializeProject(project);

project.setReadOnly(cbReadOnly.isSelected());

List<Converter> selectedConverters = new ArrayList<Converter>();
Expand Down
2 changes: 1 addition & 1 deletion src/sporemodder/view/editors/TextEditor.java
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ public void tabulate() {

// Try to find where the current line starts
// Subtract one because we just typed the '\n' character
String text = codeArea.getText().substring(0, codeArea.getCaretPosition() - 1);
String text = codeArea.getCaretPosition() == 0 ? "" : codeArea.getText().substring(0, codeArea.getCaretPosition() - 1);
int lineStartIndex = text.lastIndexOf("\n");

if (lineStartIndex == -1) {
Expand Down

0 comments on commit 5f17fe8

Please sign in to comment.