Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
dbartolini committed Aug 20, 2024
1 parent b98c3a4 commit 04a11ad
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 31 deletions.
2 changes: 2 additions & 0 deletions tools/level_editor/level_editor.vala
Original file line number Diff line number Diff line change
Expand Up @@ -1104,6 +1104,8 @@ public class LevelEditorApplication : Gtk.Application
// FIXME
} else if (msg.has_key("success")) {
_data_compiler.compile_finished((bool)msg["success"], (uint)(double)msg["revision"]);
_project._data_compiled = true;
_project_browser.update_icon_view();
}
} else if (msg_type == "refresh_list") {
_data_compiler.refresh_list_finished((ArrayList<Value?>)msg["list"]);
Expand Down
12 changes: 12 additions & 0 deletions tools/level_editor/project.vala
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ public class Project
public Gee.HashMap<string, Guid?> _map;
public ImporterData _all_extensions_importer_data;
public Gee.ArrayList<ImporterData?> _importers;
public bool _data_compiled;

public signal void file_added(string type, string name, uint64 size, uint64 mtime);
public signal void file_removed(string type, string name);
Expand All @@ -67,6 +68,15 @@ public class Project
_all_extensions_importer_data = ImporterData();
_all_extensions_importer_data.delegate = import_all_extensions;
_importers = new Gee.ArrayList<ImporterData?>();
_data_compiled = false;
}

public uint64 mtime(string type, string name)
{
var path = ResourceId.path(type, name);
Guid id = _map[path];
string mtime = _files.get_property_string(id, "mtime");
return uint64.parse(mtime);
}

public void reset()
Expand Down Expand Up @@ -434,6 +444,8 @@ public class Project
_files.set_property_string(id, "size", size.to_string());
_files.set_property_string(id, "mtime", mtime.to_string());

_data_compiled = false;

file_changed(type, name, size, mtime);
}

Expand Down
2 changes: 1 addition & 1 deletion tools/level_editor/project_browser.vala
Original file line number Diff line number Diff line change
Expand Up @@ -783,7 +783,7 @@ public class ProjectBrowser : Gtk.Bin
return Gdk.EVENT_PROPAGATE;
}

private void update_icon_view()
public void update_icon_view()
{
Gtk.TreeModel selected_model;
Gtk.TreeIter selected_iter;
Expand Down
95 changes: 65 additions & 30 deletions tools/level_editor/thumbnail_cache.vala
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ public class ThumbnailCache
[Compact]
public struct CacheEntry
{
// Pixbuf area inside the atlas.
Gdk.Pixbuf? pixbuf;
unowned List<StringId64?> lru;
Gdk.Pixbuf? pixbuf; ///< Pixbuf area inside the atlas.
unowned List<StringId64?> lru; ///< Pointer to LRU list entry.
uint64 mtime; ///< Pixbuf last modification time.
bool pending; ///< Whether a request to generate the thumbnail is pending.
}

public const int THUMBNAIL_SIZE = 64;
Expand Down Expand Up @@ -101,7 +102,23 @@ public class ThumbnailCache
if (entry == null)
return;

copy_thumbnail_from_path(entry.pixbuf, thumb_path_dst.get_path());
// Read thumbnail mtime.
try {
uint64 thumb_mtime = 0;
GLib.FileInfo thumb_info = thumb_path_dst.query_info("*", GLib.FileQueryInfoFlags.NOFOLLOW_SYMLINKS);
GLib.DateTime? mdate = thumb_info.get_modification_date_time();
if (mdate != null)
thumb_mtime = mdate.to_unix() * 1000000000 + mdate.get_microsecond() * 1000; // Convert to ns.

copy_thumbnail_from_path(entry.pixbuf, thumb_path_dst.get_path());
entry.mtime = thumb_mtime;
entry.pending = false;
_map.set(resource_id, entry);
assert(_map.get(resource_id).mtime == thumb_mtime);
logi("done generating %s mtime %llu %d.%d (%s)".printf(resource_path, entry.mtime, mdate.get_second(), mdate.get_microsecond(), thumb_path_dst.get_path()));
} catch (GLib.Error e) {
loge(e.message);
}
}

// Copies @a thumbnail inside the atlas at the position defined by @a subpixbuf.
Expand Down Expand Up @@ -152,59 +169,77 @@ public class ThumbnailCache
{
string resource_path = ResourceId.path(type, name);
StringId64 resource_id = StringId64(resource_path);
Gdk.Pixbuf? pixbuf = null;
CacheEntry? entry = null;

// Allocate a subpixbuf slot inside the atlas.
if (_map.has_key(resource_id)) {
entry = _map.get(resource_id);

// Set resource_id as most recently used entry.
_list.remove_link(entry.lru);

_list.append(resource_id);
entry.lru = _list.last();
_map.set(resource_id, entry);
} else {
Gdk.Pixbuf? pixbuf = null;

if (!_map.has_key(resource_id)) {
if (_list.length() == _max_cache_size) {
// Evict the least recently used entry.
unowned List<StringId64?> lru = _list.nth(0);
// Reuse the subpixbuf from the evicted entry.
pixbuf = _map.get(lru.data).pixbuf;
_map.unset(lru.data);
_list.remove_link(lru);
} else {
// Create a new subpixbuf if the entry is new.
pixbuf = create_thumbnail_subpixbuf();
}

// Create a new subpixbuf if the entry has not been reused.
if (pixbuf == null)
pixbuf = create_thumbnail_subpixbuf();
// Read thumbnail from disk.
uint64 thumb_mtime = 0;
try {
GLib.File thumb_path_dst = GLib.File.new_for_path(thumbnail_path(resource_path));
GLib.FileInfo thumb_info = thumb_path_dst.query_info("*", GLib.FileQueryInfoFlags.NOFOLLOW_SYMLINKS);
GLib.DateTime? mdate = thumb_info.get_modification_date_time();
if (mdate != null)
thumb_mtime = mdate.to_unix() * 1000000000 + mdate.get_microsecond() * 1000; // Convert to ns.

copy_thumbnail_from_path(pixbuf, thumb_path_dst.get_path());
logi("copy from path %s".printf(resource_path));
} catch (GLib.Error e) {
// Nobody cares.
}

// Create a new cache entry.
_list.append(resource_id);
CacheEntry entry = { pixbuf, _list.last() };
entry = { pixbuf, _list.last(), thumb_mtime };
_map.set(resource_id, entry);
}

GLib.File thumb_path_dst = GLib.File.new_for_path(thumbnail_path(resource_path));
if (false && thumb_path_dst.query_exists()) {
copy_thumbnail_from_path(pixbuf, thumb_path_dst.get_path());
} else {
// No on-disk thumbnail found, ask the thumbnail server to generate one.
// Create a unique temporary file to store the thumbnail's data.
GLib.File thumb_path_tmp = null;
if (!entry.pending && (entry.mtime == 0 || entry.mtime <= _project.mtime(type, name))) {
// On-disk thumbnail not found or outdated.
// Ask the server to generate a fresh one if the data is ready.
if (_project._data_compiled) {
try {
// Create a unique temporary file to store the thumbnail's data.
FileIOStream fs;
thumb_path_tmp = GLib.File.new_tmp(null, out fs);
GLib.File thumb_path_tmp = GLib.File.new_tmp(null, out fs);
fs.close();

// Append request to generate a thumbnail.
// Request a new thumbnail.
logi("generate %s entry.mtime %llu (prj.mtime %llu)".printf(resource_path, entry.mtime, _project.mtime(type, name)));
entry.pending = true;
_map.set(resource_id, entry);
_thumbnail.send_script(ThumbnailApi.add_request(type, name, thumb_path_tmp.get_path()));
_thumbnail.send(DeviceApi.frame());
} catch (GLib.Error e) {
loge(e.message);
}
}
} else {
CacheEntry? entry = _map.get(resource_id);
pixbuf = entry.pixbuf;

// Set resource_id as most recently used entry.
_list.remove_link(entry.lru);

_list.append(resource_id);
entry.lru = _list.last();
_map.set(resource_id, entry);
}

return pixbuf;
return entry.pixbuf;
}
}

Expand Down

0 comments on commit 04a11ad

Please sign in to comment.