+ Added command functionality base and modified command stub

This commit is contained in:
Matthew Cech
2019-05-05 15:22:49 -07:00
parent 854da8d8cd
commit 645e632dcb
9 changed files with 218 additions and 16 deletions
@@ -10,12 +10,12 @@ import dataStructures.KittyUser;
import dataStructures.Response; import dataStructures.Response;
import dataStructures.UserInput; import dataStructures.UserInput;
public class CommandUserBenchmark extends Command public class CommandBenchmark extends Command
{ {
public CommandUserBenchmark(KittyRole level, KittyRating rating) { super(level, rating); } public CommandBenchmark(KittyRole level, KittyRating rating) { super(level, rating); }
@Override @Override
public String HelpText() { return LocStrings.Stub("UserBenchmarkInfo"); } public String HelpText() { return LocStrings.Stub("BenchmarkInfo"); }
@Override @Override
public void OnRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response res) public void OnRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response res)
+40 -10
View File
@@ -6,6 +6,7 @@ import java.util.List;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import commands.*; import commands.*;
import core.benchmark.BenchmarkManager;
import core.lua.PluginManager; import core.lua.PluginManager;
import dataStructures.*; import dataStructures.*;
import net.dv8tion.jda.core.entities.Emote; import net.dv8tion.jda.core.entities.Emote;
@@ -42,6 +43,9 @@ public class ObjectBuilderFactory
// Plugin manager // Plugin manager
private static PluginManager pluginManager; private static PluginManager pluginManager;
// Userbenchmark csv manager instance
private static BenchmarkManager benchmarkManager;
// Localization classes - these are singletons, but should be initialized before almost all other // Localization classes - these are singletons, but should be initialized before almost all other
// things so their inclusion in the factory is to ensure they're started at the correct time. // things so their inclusion in the factory is to ensure they're started at the correct time.
@SuppressWarnings("unused") private static LocStrings locStrings; @SuppressWarnings("unused") private static LocStrings locStrings;
@@ -93,6 +97,10 @@ public class ObjectBuilderFactory
} }
} }
////////////////////////
// Extraction Methods //
////////////////////////
// Explicitly locks: guildCache // Explicitly locks: guildCache
public static KittyGuild ExtractGuild(GuildMessageReceivedEvent event) public static KittyGuild ExtractGuild(GuildMessageReceivedEvent event)
{ {
@@ -311,16 +319,9 @@ public class ObjectBuilderFactory
user.avatarID = member.getUser().getAvatarUrl(); user.avatarID = member.getUser().getAvatarUrl();
} }
// Constructs a CommandEnabler if it doesn't exist, and gets the existing one if it does. //////////////////////////
public static CommandEnabler ConstructCommandEnabler() // Construction Methods //
{ //////////////////////////
LazyInit();
if(commandEnabler == null)
commandEnabler = new CommandEnabler();
return commandEnabler;
}
// Default construction of the command manager. In order to remotely resolve command enabling // Default construction of the command manager. In order to remotely resolve command enabling
// and disabling, what we do is construct the commands with a localized pair that is checked against // and disabling, what we do is construct the commands with a localized pair that is checked against
@@ -378,9 +379,22 @@ public class ObjectBuilderFactory
manager.Register(LocCommands.Stub("catch"), new CommandCatch(KittyRole.General, KittyRating.Safe)); manager.Register(LocCommands.Stub("catch"), new CommandCatch(KittyRole.General, KittyRating.Safe));
manager.Register(LocCommands.Stub("guildrolelist"), new CommandGuildRoleList(KittyRole.General, KittyRating.Safe)); manager.Register(LocCommands.Stub("guildrolelist"), new CommandGuildRoleList(KittyRole.General, KittyRating.Safe));
manager.Register(LocCommands.Stub("benchmark, bench"), new CommandBenchmark(KittyRole.General, KittyRating.Safe));
return manager; return manager;
} }
// Constructs a CommandEnabler if it doesn't exist, and gets the existing one if it does.
public static CommandEnabler ConstructCommandEnabler()
{
LazyInit();
if(commandEnabler == null)
commandEnabler = new CommandEnabler();
return commandEnabler;
}
// Default database manager construction. It can be constructed // Default database manager construction. It can be constructed
// in different ways, and so we construct it outside of the constructor for // in different ways, and so we construct it outside of the constructor for
// the factory since it doesn't have to be present / can be elsewhere. // the factory since it doesn't have to be present / can be elsewhere.
@@ -425,6 +439,21 @@ public class ObjectBuilderFactory
return pluginManager; return pluginManager;
} }
public static BenchmarkManager ConstructBenchmarkManager()
{
LazyInit();
if(benchmarkManager == null)
benchmarkManager = new BenchmarkManager();
return benchmarkManager;
}
/////////////////////
// Utility Methods //
/////////////////////
// Returns number of cached guilds (does not equal total users in the database, only what's in memory)
public static Integer GetGuildCount() public static Integer GetGuildCount()
{ synchronized(guildCache) { synchronized(guildCache)
{ {
@@ -432,6 +461,7 @@ public class ObjectBuilderFactory
} }
} }
// Returns number of cached users (does not equal total users in the database, only what's in memory)
public static Integer GetUserCount() public static Integer GetUserCount()
{ synchronized(userCache) { synchronized(userCache)
{ {
+27
View File
@@ -0,0 +1,27 @@
package core.benchmark;
public class BenchmarkEntry
{
public final BenchmarkType type;
public final String partNumber;
public final String brand;
public final String model;
public final int rank;
public final float benchmark;
public final int samples;
public final String url;
BenchmarkEntry(String input)
{
String[] row = input.split(",");
type = BenchmarkType.valueOf(row[0]);
partNumber = row[1];
brand = row[2];
model = row[3];
rank = Integer.parseInt(row[4]);
benchmark = Float.parseFloat(row[5]);
samples = Integer.parseInt(row[6]);
url = row[7];
}
}
+11
View File
@@ -0,0 +1,11 @@
package core.benchmark;
import utils.GlobalLog;
public class BenchmarkLog
{
// Logging
public static void Log(String str) { GlobalLog.Log("[Benchmark] " + str); }
public static void Warn(String str) { GlobalLog.Warn("[Benchmark] " + str); }
public static void Error(String str) { GlobalLog.Error(" [Benchmark] " + str); }
}
+106
View File
@@ -0,0 +1,106 @@
package core.benchmark;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import utils.FileUtils;
import utils.directoryMonitor.DirectoryMonitor;
import utils.directoryMonitor.MonitoredFile;
// All things considered, this doesn't need to be particularly efficient since anything
// less than 10ms of search time won't be noticable to an end user really, not for
// a networked application that's not performance bound.
public class BenchmarkManager
{
// Variables
public final String directory = "assets/userbench/";
public final String extension = ".csv";
public final String lineDelimiter = "\n";
private List<BenchmarkEntry> raw;
private DirectoryMonitor directoryMonitor;
private boolean needsUpdate;
// Read in all extensions
public BenchmarkManager()
{
long start = Instant.now().toEpochMilli();
raw = new ArrayList<BenchmarkEntry>();
directoryMonitor = new DirectoryMonitor(directory);
needsUpdate = false;
RebuildLookup();
BenchmarkLog.Log("Took " + (Instant.now().toEpochMilli() - start) + " ms to load " + raw.size() + " entries from " + directoryMonitor.GetCurrentFiles().size() + " file" + (raw.size() > 1 ? "s" : ""));
}
// Rebuilds the files being monitored
public void RebuildLookup()
{
synchronized(raw)
{
raw.clear();
List<MonitoredFile> files;
synchronized(directoryMonitor)
{
files = directoryMonitor.GetCurrentFiles();
}
if(files != null)
{
for(MonitoredFile mf : files)
{
String contents = FileUtils.ReadContent(mf.path);
String[] lines = contents.split(lineDelimiter);
for(int i = 1; i < lines.length; ++i)
raw.add(new BenchmarkEntry(lines[i]));
}
}
else
{
BenchmarkLog.Warn("No " + extension + " files where found in " + directory);
}
}
}
// Search for a substring in the model name
public List<BenchmarkEntry> FindModel(String modelSubstr)
{
long start = Instant.now().toEpochMilli();
List<BenchmarkEntry> matching = new ArrayList<BenchmarkEntry>();
String searchSubstr = modelSubstr.toLowerCase();
for(BenchmarkEntry e : raw)
{
String model = e.model.toLowerCase().trim();
if(model.contains(searchSubstr))
matching.add(e);
}
BenchmarkLog.Log("Searched for '" + searchSubstr + "' for "+ (Instant.now().toEpochMilli() - start) + "ms and found " + matching.size() + " entries.");
return matching;
}
// Keeps tabs on any changes of the files.
public void Update()
{
needsUpdate = false;
directoryMonitor.Update(this::OnRescan, this::OnRescan, this::OnRescan);
if(needsUpdate)
RebuildLookup();
}
// When a file is changed, handle it.
private void OnRescan(MonitoredFile file)
{
// For now, all we need is to note that something was adjusted.
if(file.path.endsWith(extension))
needsUpdate = true;
}
}
+17
View File
@@ -0,0 +1,17 @@
package core.benchmark;
public enum BenchmarkType
{
CPU(0), GPU(1), SSD(2), HDD(4), RAM(8), USB(16);
private final int value;
private BenchmarkType(int value)
{
this.value = value;
}
public int getValue()
{
return value;
}
}
+3
View File
@@ -2,6 +2,7 @@ package main;
import javax.security.auth.login.LoginException; import javax.security.auth.login.LoginException;
import core.*; import core.*;
import core.benchmark.BenchmarkManager;
import core.lua.PluginManager; import core.lua.PluginManager;
import core.lua.PluginUser; import core.lua.PluginUser;
import dataStructures.KittyChannel; import dataStructures.KittyChannel;
@@ -32,6 +33,7 @@ public class Main extends ListenerAdapter
private static Stats stats; private static Stats stats;
private static RPManager rpManager; private static RPManager rpManager;
private static PluginManager pluginManager; private static PluginManager pluginManager;
private static BenchmarkManager benchmarkManager;
// Main test location // Main test location
public static void main(String[] args) throws InterruptedException, LoginException, Exception public static void main(String[] args) throws InterruptedException, LoginException, Exception
@@ -44,6 +46,7 @@ public class Main extends ListenerAdapter
stats = ObjectBuilderFactory.ConstructStats(commandManager); stats = ObjectBuilderFactory.ConstructStats(commandManager);
rpManager = ObjectBuilderFactory.ConstructRPManager(); rpManager = ObjectBuilderFactory.ConstructRPManager();
pluginManager = ObjectBuilderFactory.ConstructPluginManager(); pluginManager = ObjectBuilderFactory.ConstructPluginManager();
benchmarkManager = ObjectBuilderFactory.ConstructBenchmarkManager();
// Bot startup // Bot startup
kitty = new JDABuilder(AccountType.BOT).setToken(Ref.TestToken).buildBlocking(); kitty = new JDABuilder(AccountType.BOT).setToken(Ref.TestToken).buildBlocking();
@@ -1,4 +1,4 @@
package utils; package utils.directoryMonitor;
import java.io.File; import java.io.File;
import java.nio.file.Files; import java.nio.file.Files;
@@ -6,10 +6,12 @@ import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Stream; import java.util.stream.Stream;
import dataStructures.MonitoredFile; import utils.GlobalLog;
import utils.LogFilter;
// NOTE: Consider shifting internal behavior to https://docs.oracle.com/javase/tutorial/essential/io/notification.html // NOTE: Consider shifting internal behavior to https://docs.oracle.com/javase/tutorial/essential/io/notification.html
// for external stability and support // for external stability and support
@@ -151,6 +153,12 @@ public class DirectoryMonitor
Warn("There's nothing at all in a FileMonitor's target folder! Folder: " + directory); Warn("There's nothing at all in a FileMonitor's target folder! Folder: " + directory);
} }
// Returns the current list of files the monitor is tracking in the directory.
public List<MonitoredFile> GetCurrentFiles()
{
return last;
}
// Prints out an arraylist of items from a directory by path // Prints out an arraylist of items from a directory by path
private void Print(ArrayList<MonitoredFile> toPrint) private void Print(ArrayList<MonitoredFile> toPrint)
{ {
@@ -1,4 +1,4 @@
package dataStructures; package utils.directoryMonitor;
import java.nio.file.Path; import java.nio.file.Path;