Skip to content

Commit

Permalink
+ allow replacing simulations and genomes
Browse files Browse the repository at this point in the history
+ new labels also show up for replaced items
  • Loading branch information
chrxh committed Apr 26, 2024
1 parent 59d64b4 commit 01bf355
Show file tree
Hide file tree
Showing 14 changed files with 325 additions and 46 deletions.
68 changes: 68 additions & 0 deletions scripts/Server/replacesimulation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php
require './helpers.php';
require './hooks.php';

function closeAndExit($db) {
echo json_encode(["result"=>false]);
$db->close();
exit;
}


$db = connectToDB();
$db->begin_transaction();

$userName = $_POST["userName"];
$pw = $_POST["password"];

if (!checkPw($db, $userName, $pw)) {
echo json_encode(["result"=>false]);
$db->close();
exit;
}

$obj = $db->query("SELECT u.ID as id FROM user u WHERE u.NAME='".addslashes($userName)."'")->fetch_object();
if (!$obj) {
echo json_encode(["result"=>false]);
$db->close();
exit;
}

$success = false;
$particles = (int)$_POST['particles'];
$version = $_POST['version'];
$content = $_POST['content'];
$settings = $_POST['settings'];
$simId = $_POST['simId'];
$size = strlen($content);
$type = array_key_exists('type', $_POST) ? $_POST['type'] : 0;
$workspace = array_key_exists('workspace', $_POST) ? $_POST['workspace'] : 0;
$statistics = array_key_exists('statistics', $_POST) ? $_POST['statistics'] : "";

if ($userName != 'alien-project' && $workspace == 1) {
closeAndExit($db);
}

$stmt = $db->prepare("UPDATE simulation SET PARTICLES=?, VERSION=?, CONTENT=?, WIDTH=?, HEIGHT=?, SETTINGS=?, SIZE=?, STATISTICS=?, CONTENT2=?, CONTENT3=?, CONTENT4=?, CONTENT5=?, CONTENT6=? WHERE ID=?");
if (!$stmt) {
closeAndExit($db);
}

$emptyString = '';
$stmt->bind_param("issiisissssssi", $particles, $version, $content, $width, $height, $settings, $size, $statistics, $emptyString, $emptyString, $emptyString, $emptyString, $emptyString, $simId);

if (!$stmt->execute()) {
closeAndExit($db);
}

// create Discord message
//if ($workspace != PRIVATE_WORKSPACE_TYPE) {
// $discordPayload = createAddResourceMessage($type, $simName, $userName, $simDesc, $width, $height, $particles);
// sendDiscordMessage($discordPayload);
//}

echo json_encode(["result"=>true]);

$db->commit();
$db->close();
?>
4 changes: 2 additions & 2 deletions source/Base/Cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ template<typename Key, typename Value, int MaxEntries>
class Cache
{
public:
void insert(Key const& key, Value const& value);
void insertOrAssign(Key const& key, Value const& value);

std::optional<Value> find(Key const& key);

Expand All @@ -21,7 +21,7 @@ class Cache
/* Implementation */
/************************************************************************/
template <typename Key, typename Value, int MaxEntries>
void Cache<Key, Value, MaxEntries>::insert(Key const& key, Value const& value)
void Cache<Key, Value, MaxEntries>::insertOrAssign(Key const& key, Value const& value)
{
if (_cacheMap.size() >= MaxEntries) {
_cacheMap.erase(_usedKeys.front());
Expand Down
93 changes: 76 additions & 17 deletions source/Gui/BrowserWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "OverlayMessageController.h"
#include "GenomeEditorWindow.h"
#include "HelpStrings.h"
#include "SerializationHelperService.h"

namespace
{
Expand Down Expand Up @@ -110,17 +111,19 @@ _BrowserWindow::~_BrowserWindow()
+ workspaceTypeToString.at(workspaceId.workspaceType),
NetworkResourceService::convertFolderNamesToSettings(workspace.collapsedFolderNames));
}
settings.setStringVector("windows.browser.simulation ids", getAllSimulationIds());
_lastSessionData.save(getAllRawTOs());
}

void _BrowserWindow::registerCyclicReferences(
LoginDialogWeakPtr const& loginDialog,
UploadSimulationDialogWeakPtr const& uploadSimulationDialog,
EditSimulationDialogWeakPtr const& editSimulationDialog)
EditSimulationDialogWeakPtr const& editSimulationDialog,
GenomeEditorWindowWeakPtr const& genomeEditorWindow)
{
_loginDialog = loginDialog;
_uploadSimulationDialog = uploadSimulationDialog;
_editSimulationDialog = editSimulationDialog;
_genomeEditorWindow = genomeEditorWindow;

auto firstStart = GlobalSettings::getInstance().getBool("windows.browser.first start", true);
refreshIntern(firstStart);
Expand All @@ -136,8 +139,7 @@ void _BrowserWindow::registerCyclicReferences(
createTreeTOs(workspace);
}

auto simIds = GlobalSettings::getInstance().getStringVector("windows.browser.simulation ids", getAllSimulationIds());
_simIdsFromLastSession = std::unordered_set(simIds.begin(), simIds.end());
_lastSessionData.load(getAllRawTOs());
}

void _BrowserWindow::onRefresh()
Expand All @@ -155,11 +157,6 @@ BrowserCache& _BrowserWindow::getSimulationCache()
return _simulationCache;
}

void _BrowserWindow::registerUploadedSimulation(std::string const& id)
{
_simIdsFromLastSession.insert(id);
}

void _BrowserWindow::refreshIntern(bool withRetry)
{
try {
Expand Down Expand Up @@ -291,6 +288,14 @@ void _BrowserWindow::processToolbar()
+ " to the server and made visible in the browser. You can choose whether you want to share it with other users or whether it should only be visible "
"in your private workspace.\nIf you have already selected a folder, your " + resourceTypeString + " will be uploaded there.");

//replace button
ImGui::SameLine();
ImGui::BeginDisabled(!isOwnerForSelectedItem || !_selectedTreeTO->isLeaf());
if (AlienImGui::ToolbarButton(ICON_FA_EXCHANGE_ALT)) {
onReplaceResource(_selectedTreeTO->getLeaf());
}
ImGui::EndDisabled();

//edit button
ImGui::SameLine();
ImGui::BeginDisabled(!isOwnerForSelectedItem);
Expand Down Expand Up @@ -769,7 +774,7 @@ bool _BrowserWindow::processResourceNameField(NetworkResourceTreeTO const& treeT
}
ImGui::SameLine();

if (!_simIdsFromLastSession.contains(leaf.rawTO->id)) {
if (!isOwner(treeTO) && _lastSessionData.isNew(leaf.rawTO)) {
auto font = StyleRepository::getInstance().getSmallBoldFont();
auto origSize = font->Scale;
font->Scale *= 0.65f;
Expand Down Expand Up @@ -1234,7 +1239,7 @@ void _BrowserWindow::onDownloadResource(BrowserLeaf const& leaf)
MessageDialog::getInstance().information("Error", "Failed to load simulation. Your program version may not match.");
return;
}
_simulationCache.insert(leaf.rawTO->id, deserializedSim);
_simulationCache.insertOrAssign(leaf.rawTO->id, deserializedSim);
} else {
log(Priority::Important, "browser: get resource with id=" + leaf.rawTO->id + " from simulation cache");
std::swap(deserializedSim, *cachedSimulation);
Expand Down Expand Up @@ -1286,6 +1291,62 @@ void _BrowserWindow::onDownloadResource(BrowserLeaf const& leaf)
});
}

void _BrowserWindow::onReplaceResource(BrowserLeaf const& leaf)
{
printOverlayMessage("Replacing ...");

delayedExecution([=, this] {
std::string mainData;
std::string settings;
std::string statistics;
IntVector2D worldSize;
int numObjects = 0;

DeserializedSimulation deserializedSim;
if (leaf.rawTO->resourceType == NetworkResourceType_Simulation) {
deserializedSim = SerializationHelperService::getDeserializedSerialization(_simController);

SerializedSimulation serializedSim;
if (!SerializerService::serializeSimulationToStrings(serializedSim, deserializedSim)) {
MessageDialog::getInstance().information("Replace simulation", "The simulation could not be serialized for replacing.");
return;
}
mainData = serializedSim.mainData;
settings = serializedSim.auxiliaryData;
statistics = serializedSim.statistics;
worldSize = {deserializedSim.auxiliaryData.generalSettings.worldSizeX, deserializedSim.auxiliaryData.generalSettings.worldSizeY};
numObjects = deserializedSim.mainData.getNumberOfCellAndParticles();
} else {
auto genome = _genomeEditorWindow.lock()->getCurrentGenome();
if (genome.cells.empty()) {
showMessage("Replace genome", "The is no valid genome in the genome editor selected.");
return;
}
auto genomeData = GenomeDescriptionService::convertDescriptionToBytes(genome);
numObjects = GenomeDescriptionService::getNumNodesRecursively(genomeData, true);

if (!SerializerService::serializeGenomeToString(mainData, genomeData)) {
showMessage("Replace genome", "The genome could not be serialized for replacing.");
return;
}
}

if (!NetworkService::replaceResource(leaf.rawTO->id, worldSize, numObjects, mainData, settings, statistics)) {
std::string type = leaf.rawTO->resourceType == NetworkResourceType_Simulation ? "simulation" : "genome";
showMessage(
"Error",
"Failed to replace " + type + ".\n\n"
"Possible reasons:\n\n" ICON_FA_CHEVRON_RIGHT " The server is not reachable.\n\n" ICON_FA_CHEVRON_RIGHT
" The total size of your uploads exceeds the allowed storage limit.");
return;
}
if (leaf.rawTO->resourceType == NetworkResourceType_Simulation) {
getSimulationCache().insertOrAssign(leaf.rawTO->id, deserializedSim);
}
onRefresh();
});
}

void _BrowserWindow::onEditResource(NetworkResourceTreeTO const& treeTO)
{
if (treeTO->isLeaf()) {
Expand Down Expand Up @@ -1455,15 +1516,13 @@ std::string _BrowserWindow::getUserNamesToEmojiType(std::string const& resourceI
return boost::algorithm::join(userNames, ", ");
}

std::vector<std::string> _BrowserWindow::getAllSimulationIds() const
std::unordered_set<NetworkResourceRawTO> _BrowserWindow::getAllRawTOs() const
{
std::unordered_set<std::string> result;
std::unordered_set<NetworkResourceRawTO> result;
for (auto const& workspace : _workspaces | std::views::values) {
for(auto const& rawTO : workspace.rawTOs) {
result.insert(rawTO->id);
}
result.insert(workspace.rawTOs.begin(), workspace.rawTOs.end());
}
return std::vector(result.begin(), result.end());
return result;
}

void _BrowserWindow::pushTextColor(NetworkResourceTreeTO const& to)
Expand Down
11 changes: 7 additions & 4 deletions source/Gui/BrowserWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include "AlienWindow.h"
#include "Definitions.h"
#include "LastSessionBrowserData.h"

struct ImGuiTableColumnSortSpecs;

Expand All @@ -30,13 +31,13 @@ class _BrowserWindow : public _AlienWindow
void registerCyclicReferences(
LoginDialogWeakPtr const& loginDialog,
UploadSimulationDialogWeakPtr const& uploadSimulationDialog,
EditSimulationDialogWeakPtr const& editSimulationDialog);
EditSimulationDialogWeakPtr const& editSimulationDialog,
GenomeEditorWindowWeakPtr const& genomeEditorWindow);

void onRefresh();
WorkspaceType getCurrentWorkspaceType() const;

BrowserCache& getSimulationCache();
void registerUploadedSimulation(std::string const& id);

private:
struct WorkspaceId
Expand Down Expand Up @@ -96,6 +97,7 @@ class _BrowserWindow : public _AlienWindow
void sortUserList();

void onDownloadResource(BrowserLeaf const& leaf);
void onReplaceResource(BrowserLeaf const& leaf);
void onEditResource(NetworkResourceTreeTO const& treeTO);
void onMoveResource(NetworkResourceTreeTO const& treeTO);
void onDeleteResource(NetworkResourceTreeTO const& treeTO);
Expand All @@ -107,7 +109,7 @@ class _BrowserWindow : public _AlienWindow
bool isOwner(NetworkResourceTreeTO const& treeTO) const;
std::string getUserNamesToEmojiType(std::string const& resourceId, int emojiType);

std::vector<std::string> getAllSimulationIds() const;
std::unordered_set<NetworkResourceRawTO> getAllRawTOs() const;

void pushTextColor(NetworkResourceTreeTO const& to);
void popTextColor();
Expand All @@ -120,7 +122,7 @@ class _BrowserWindow : public _AlienWindow
std::vector<UserTO> _userTOs;
WorkspaceId _currentWorkspace = {NetworkResourceType_Simulation, WorkspaceType_AlienProject};
std::map<WorkspaceId, Workspace> _workspaces;
std::unordered_set<std::string> _simIdsFromLastSession;
LastSessionBrowserData _lastSessionData;

NetworkResourceTreeTO _selectedTreeTO;

Expand All @@ -140,4 +142,5 @@ class _BrowserWindow : public _AlienWindow
EditorController _editorController;
UploadSimulationDialogWeakPtr _uploadSimulationDialog;
EditSimulationDialogWeakPtr _editSimulationDialog;
GenomeEditorWindowWeakPtr _genomeEditorWindow;
};
4 changes: 4 additions & 0 deletions source/Gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ PUBLIC
ImageToPatternDialog.h
InspectorWindow.cpp
InspectorWindow.h
LastSessionBrowserData.cpp
LastSessionBrowserData.h
LoginDialog.cpp
LoginDialog.h
LogWindow.cpp
Expand Down Expand Up @@ -91,6 +93,8 @@ PUBLIC
ResizeWorldDialog.h
SelectionWindow.cpp
SelectionWindow.h
SerializationHelperService.cpp
SerializationHelperService.h
Shader.cpp
Shader.h
ShaderWindow.cpp
Expand Down
1 change: 1 addition & 0 deletions source/Gui/Definitions.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ using ImageToPatternDialog = std::shared_ptr<_ImageToPatternDialog>;

class _GenomeEditorWindow;
using GenomeEditorWindow = std::shared_ptr<_GenomeEditorWindow>;
using GenomeEditorWindowWeakPtr = std::weak_ptr<_GenomeEditorWindow>;

class _RadiationSourcesWindow;
using RadiationSourcesWindow = std::shared_ptr<_RadiationSourcesWindow>;
Expand Down
38 changes: 38 additions & 0 deletions source/Gui/LastSessionBrowserData.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "LastSessionBrowserData.h"

#include "Base/GlobalSettings.h"
#include "Network/NetworkResourceRawTO.h"

void LastSessionBrowserData::load(std::unordered_set<NetworkResourceRawTO> const& rawTOs)
{
auto currentIdentifiers = convertToIdentifiers(rawTOs);
auto lastIdentifiers = GlobalSettings::getInstance().getStringVector(
"windows.browser.last session.simulation ids", std::vector(currentIdentifiers.begin(), currentIdentifiers.end()));
_identifiers = std::unordered_set(lastIdentifiers.begin(), lastIdentifiers.end());
}

void LastSessionBrowserData::save(std::unordered_set<NetworkResourceRawTO> const& rawTOs)
{
auto currentIdentifiers = convertToIdentifiers(rawTOs);
GlobalSettings::getInstance().setStringVector(
"windows.browser.last session.simulation ids", std::vector(currentIdentifiers.begin(), currentIdentifiers.end()));
}

bool LastSessionBrowserData::isNew(NetworkResourceRawTO const& rawTO) const
{
return !_identifiers.count(convertToIdentifier(rawTO));
}

std::unordered_set<std::string> LastSessionBrowserData::convertToIdentifiers(std::unordered_set<NetworkResourceRawTO> const& rawTOs) const
{
std::unordered_set<std::string> result;
for (auto const& rawTO : rawTOs) {
result.insert(convertToIdentifier(rawTO));
}
return result;
}

std::string LastSessionBrowserData::convertToIdentifier(NetworkResourceRawTO const& rawTO) const
{
return rawTO->id + "/" + rawTO->timestamp;
}
20 changes: 20 additions & 0 deletions source/Gui/LastSessionBrowserData.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#pragma once

#include <string>
#include <unordered_set>

#include "Network/Definitions.h"

class LastSessionBrowserData
{
public:
void load(std::unordered_set<NetworkResourceRawTO> const& rawTOs);
void save(std::unordered_set<NetworkResourceRawTO> const& rawTOs);
bool isNew(NetworkResourceRawTO const& rawTO) const;

private:
std::unordered_set<std::string> convertToIdentifiers(std::unordered_set<NetworkResourceRawTO> const& rawTOs) const;
std::string convertToIdentifier(NetworkResourceRawTO const& rawTO) const;

std::unordered_set<std::string> _identifiers;
};
Loading

0 comments on commit 01bf355

Please sign in to comment.