Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop Etupirka from burning the CPU #8

Merged
merged 2 commits into from
Jun 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Etupirka/Etupirka.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@
<Compile Include="DisplaySettings.cs" />
<Compile Include="GameData\DisplayInfo.cs" />
<Compile Include="InformationManager.cs" />
<Compile Include="ProcessInfoCache.cs" />
<Compile Include="StringProcessing.cs" />
<Compile Include="Views\DatabaseConfigView.xaml.cs">
<DependentUpon>DatabaseConfigView.xaml</DependentUpon>
Expand Down
170 changes: 84 additions & 86 deletions Etupirka/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,14 @@ private void OnHotKeyHandler_ErogeHelper(HotKey hotKey)
#endregion

private ObservableCollection<GameExecutionInfo> items;

//private Dictionary<string, TimeData> timeDict;

private System.Windows.Threading.DispatcherTimer watchProcTimer;

private System.Windows.Threading.DispatcherTimer watchProcTimer;
private DBManager db;

private ProcessInfoCache processInfoCache = new ProcessInfoCache();




public MainWindow()
public MainWindow()
{

if (Settings.Default.UpgradeRequired)
Expand All @@ -216,8 +213,8 @@ public MainWindow()
db = new DBManager(Utility.userDBPath);
Utility.im = new InformationManager(Utility.infoDBPath);

items = new ObservableCollection<GameExecutionInfo>();
db.LoadGame(items);
items = new ObservableCollection<GameExecutionInfo>();
db.LoadGame(items);

GameListView.ItemsSource = items;
GameListView.SelectedItem = null;
Expand Down Expand Up @@ -245,8 +242,8 @@ public MainWindow()
}
}

#region Function
private void doCheckUpdate()
#region Function
private void doCheckUpdate()
{
try
{
Expand Down Expand Up @@ -284,83 +281,84 @@ private void UpdateStatus(int time=0)
Console.WriteLine(e);
}

System.Console.WriteLine(calcID);
bool play_flag = false;

this.Dispatcher.BeginInvoke(
new Action(() =>
{
Process[] proc = Process.GetProcesses();

Dictionary<String, bool> dic = new Dictionary<string, bool>();
foreach (Process p in proc)
{
try
{
string path = p.MainModule.FileName.ToLower();
if (dic.ContainsKey(path))
{
dic[path] |= p.Id == calcID;
}
else
{
dic.Add(p.MainModule.FileName.ToLower(), p.Id == calcID);
}
}
catch (Exception e)
{
// Console.WriteLine(e);
}
}

string statusBarText = "";
string trayTipText = "Etupirka Version " + FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion;

foreach (GameExecutionInfo i in items)
{
bool running = false;
if (i.UpdateStatus2(dic, ref running, time))
// if (i.UpdateStatus(proc, calcID,ref running, time))
{
if (time != 0)
{
//string date = DateTime.Now.Date.ToString("yyyy-MM-dd");

db.UpdateTimeNow(i.UID, time);
}
db.UpdateGameTimeInfo(i.UID, i.TotalPlayTime, i.FirstPlayTime, i.LastPlayTime);
if (i.Status == ProcStat.Focused)
{
play_flag = true;
PlayMessage.Content = i.Title + " : " + i.TotalPlayTimeString;

if (Properties.Settings.Default.hideListWhenPlaying)
{
ErogeHelper = true;
}
}
}
System.Console.WriteLine(running);
if (running)
{
trayTipText += "\n" + i.Title + " : " + i.TotalPlayTimeString;
}
}

dic.Clear();
if (!play_flag)
{
PlayMessage.Content = statusBarText;

if (Properties.Settings.Default.hideListWhenPlaying)
{
ErogeHelper = false;
}
}
tbico.ToolTipText = trayTipText;

OnPropertyChanged("TotalTime");
}));
this.Dispatcher.BeginInvoke(new Action(() => {
Process[] proc = Process.GetProcesses();

Dictionary<String, bool> dic = new Dictionary<string, bool>();
using (var scopedAccess = processInfoCache.scopedAccess())
{
foreach (Process p in proc)
{
try
{
string path = processInfoCache.getProcessPath(p);
if (path == "")
{
continue;
}
bool isForeground = p.Id == calcID;
if (dic.ContainsKey(path))
{
dic[path] |= isForeground;
}
else
{
dic[path] = isForeground;
}
}
catch (Exception e)
{
// Console.WriteLine(e);
}
}
}

string statusBarText = "";
string trayTipText = "Etupirka Version " + FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion;

foreach (GameExecutionInfo i in items)
{
bool running = false;
if (i.UpdateStatus2(dic, ref running, time))
{
if (time != 0)
{
db.UpdateTimeNow(i.UID, time);
}
db.UpdateGameTimeInfo(i.UID, i.TotalPlayTime, i.FirstPlayTime, i.LastPlayTime);
if (i.Status == ProcStat.Focused)
{
play_flag = true;
PlayMessage.Content = i.Title + " : " + i.TotalPlayTimeString;

if (Properties.Settings.Default.hideListWhenPlaying)
{
ErogeHelper = true;
}
}
}
if (running)
{
trayTipText += "\n" + i.Title + " : " + i.TotalPlayTimeString;
}
}

dic.Clear();
if (!play_flag)
{
PlayMessage.Content = statusBarText;

if (Properties.Settings.Default.hideListWhenPlaying)
{
ErogeHelper = false;
}
}
tbico.ToolTipText = trayTipText;

OnPropertyChanged("TotalTime");
}));
}

private void RegisterInStartup(bool isChecked)
Expand Down
95 changes: 95 additions & 0 deletions Etupirka/ProcessInfoCache.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

namespace Etupirka
{
class ProcessInfo
{
public int id { get; set; }

public string processName { get; set; }

public string path { get; set; }

// True if we have access to this process.
public bool accesible { get; set; }

// True if the process info is pinned. Unpinned entries will be automatically cleaned up.
public bool pinned { get; set; }
}

class ProcessInfoCleanup : IDisposable
{
public ProcessInfoCleanup(ProcessInfoCache cache)
{
this.cache = cache;
}

public void Dispose()
{
cache.cleanUp();
}

private ProcessInfoCache cache;
}

class ProcessInfoCache
{
// Returns an object that automatically cleans up process info that is not used in the scope.
public ProcessInfoCleanup scopedAccess()
{
foreach (var entry in processInfoById)
{
entry.Value.pinned = false;
}

return new ProcessInfoCleanup(this);
}

public void cleanUp()
{
var entriesToRemove = processInfoById.Where((entry) => !entry.Value.pinned).ToList();
foreach (var entry in entriesToRemove)
{
processInfoById.Remove(entry.Key);
}
}

// Returns the path of the process, or an empty string if the process is not accesible.
public string getProcessPath(Process p)
{
if (processInfoById.ContainsKey(p.Id))
{
ProcessInfo info = processInfoById[p.Id];
if (info.processName == p.ProcessName)
{
info.pinned = true;
return info.path;
}
}

var processInfo = new ProcessInfo
{
id = p.Id,
accesible = false,
processName = p.ProcessName,
pinned = true
};

try
{
processInfo.path = p.MainModule.FileName.ToLower();
processInfo.accesible = true;
}
catch { }

processInfoById[p.Id] = processInfo;
return processInfo.path;
}

private Dictionary<int, ProcessInfo> processInfoById = new Dictionary<int, ProcessInfo>();
}
}