瀏覽代碼

playback recording

vlod 3 年之前
父節點
當前提交
c141d938d9
共有 30 個文件被更改,包括 567 次插入168 次删除
  1. 227 73
      Pika/core/pikaEditor/containersWindow/containersWindow.cpp
  2. 4 1
      Pika/core/pikaEditor/containersWindow/containersWindow.h
  3. 3 3
      Pika/core/pikaEditor/editShortcuts/editShortcuts.cpp
  4. 4 3
      Pika/core/pikaEditor/editor/editor.cpp
  5. 1 0
      Pika/core/pikaEditor/editor/editor.h
  6. 3 4
      Pika/core/pikaEditor/logs/logWindow.cpp
  7. 4 1
      Pika/core/pikaEditor/logs/logWindow.h
  8. 282 74
      Pika/core/pikaRuntime/containerManager/containerManager.cpp
  9. 14 1
      Pika/core/pikaRuntime/containerManager/containerManager.h
  10. 13 1
      Pika/core/pikaRuntime/runtimeContainer/runtimeContainer.h
  11. 0 4
      Pika/core/sharedRuntime/pikaImgui/pikaImgui.h
  12. 5 0
      Pika/core/sharedRuntime/windowSystemm/window.cpp
  13. 二進制
      Pika/engineResources/engineSaves/windowPos1.bin
  14. 二進制
      Pika/engineResources/engineSaves/windowPos2.bin
  15. 二進制
      Pika/engineResources/r.recording
  16. 二進制
      Pika/engineResources/r.snapshot
  17. 二進制
      Pika/engineResources/record.recording
  18. 二進制
      Pika/engineResources/record.snapshot
  19. 二進制
      Pika/engineResources/record1.recording
  20. 二進制
      Pika/engineResources/record1.snapshot
  21. 二進制
      Pika/engineResources/recordtest.recording
  22. 二進制
      Pika/engineResources/recordtest.snapshot
  23. 二進制
      Pika/engineResources/test.snapshot
  24. 二進制
      Pika/engineResources/test1.recording
  25. 二進制
      Pika/engineResources/test1.snapshot
  26. 二進制
      Pika/engineResources/test2.snapshot
  27. 二進制
      Pika/engineResources/testrecordfirst.recording
  28. 二進制
      Pika/engineResources/testrecordfirst.snapshot
  29. 1 1
      Pika/gameplay/containers/pikaGameplay.h
  30. 6 2
      Pika/resources/logs.txt

+ 227 - 73
Pika/core/pikaEditor/containersWindow/containersWindow.cpp

@@ -4,15 +4,15 @@
 #include <imgui_spinner.h>
 #include <validatePath.h>
 
-void pika::ContainersWindow::init()
+void pika::ContainersWindow::init(pika::pikaImgui::ImGuiIdsManager &imguiIdsManager)
 {
+	imguiIds = imguiIdsManager.getImguiIds(10);
 }
 
 void pika::ContainersWindow::update(pika::LogManager &logManager, bool &open, pika::LoadedDll &loadedDll,
 	pika::ContainerManager &containerManager, pika::pikaImgui::ImGuiIdsManager &imguiIdsManager)
 {
-	//todo imgui firsttime stuff for all windows
-	ImGui::PushID(pikaImgui::EditorImguiIds::containersWindow);
+	ImGui::PushID(imguiIds);
 
 
 	if (!ImGui::Begin(ICON_NAME, &open))
@@ -31,7 +31,7 @@ void pika::ContainersWindow::update(pika::LogManager &logManager, bool &open, pi
 		ImGui::BeginGroup();
 		ImGui::BeginChild("item view", ImVec2(0, -ImGui::GetFrameHeightWithSpacing())); // Leave room for 1 line below us
 
-		if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None))
+		if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_Reorderable))
 		{
 			if (ImGui::BeginTabItem(ICON_FK_PLUS_SQUARE_O " Create container"))
 			{
@@ -39,7 +39,7 @@ void pika::ContainersWindow::update(pika::LogManager &logManager, bool &open, pi
 				ImGui::Separator();
 
 				//left
-				ImGui::PushID(pikaImgui::EditorImguiIds::containersWindow+1);
+				ImGui::PushID(imguiIds +1);
 				ImGui::BeginGroup();
 				{
 
@@ -68,7 +68,7 @@ void pika::ContainersWindow::update(pika::LogManager &logManager, bool &open, pi
 				ImGui::SameLine();
 
 				//right
-				ImGui::PushID(pikaImgui::EditorImguiIds::containersWindow + 2);
+				ImGui::PushID(imguiIds + 2);
 				ImGui::BeginGroup();
 				{
 					if (itemCurrentAvailableCOntainers < loadedDll.containerInfo.size())
@@ -262,7 +262,7 @@ void pika::ContainersWindow::update(pika::LogManager &logManager, bool &open, pi
 				std::vector<pika::containerId_t> containerIds;
 				std::vector<std::string> containerNames;
 
-				ImGui::PushID(pikaImgui::EditorImguiIds::containersWindow + 3);
+				ImGui::PushID(imguiIds + 3);
 				ImGui::BeginGroup();
 				{
 					
@@ -292,7 +292,7 @@ void pika::ContainersWindow::update(pika::LogManager &logManager, bool &open, pi
 				ImGui::SameLine();
 
 				//right
-				ImGui::PushID(pikaImgui::EditorImguiIds::containersWindow + 4);
+				ImGui::PushID(imguiIds + 4);
 				ImGui::BeginGroup();
 				{
 					if (itemCurrentCreatedContainers < containerIds.size())
@@ -342,7 +342,7 @@ void pika::ContainersWindow::update(pika::LogManager &logManager, bool &open, pi
 								ImGui::SetTooltip("Resume container.");
 							}
 						}
-						else
+						else if (c.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_RECORDED)
 						{
 							ImGui::BeginDisabled();
 							if (ImGui::Button(ICON_FK_PAUSE))
@@ -355,6 +355,18 @@ void pika::ContainersWindow::update(pika::LogManager &logManager, bool &open, pi
 								ImGui::SetTooltip("Can't pause container while it is recorded."); //todo implement
 							}
 						}
+						else if (c.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_PLAYBACK)
+						{
+							if (ImGui::Button(ICON_FK_REPEAT))
+							{
+								c.flags.status = pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
+							}
+
+							if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
+							{
+								ImGui::SetTooltip("Stop playback");
+							}
+						}
 
 
 						ImGui::SameLine();
@@ -391,104 +403,246 @@ void pika::ContainersWindow::update(pika::LogManager &logManager, bool &open, pi
 						{
 
 							ImGui::Text("Status: %s", c.flags.getStatusName());
-							
-
 							ImGui::Separator();
 
-
+							if (ImGui::BeginTabBar("##Tabs for play and record", ImGuiTabBarFlags_Reorderable))
 							{
-								if (ImGui::Button(ICON_FK_CAMERA))
+								if (ImGui::BeginTabItem(ICON_FK_CAMERA " Snapshot"))
 								{
-									if (pika::isFileNameValid(snapshotName, sizeof(snapshotName)))
+									//snapshot button
 									{
-										if (!containerManager.makeSnapshot(containerIds[itemCurrentCreatedContainers], logManager, snapshotName))
+										if (ImGui::Button(ICON_FK_CAMERA))
 										{
-											logManager.log("Coultn't make snapshot", pika::logError);
+											if (pika::isFileNameValid(snapshotName, sizeof(snapshotName)))
+											{
+												if (!containerManager.makeSnapshot(containerIds[itemCurrentCreatedContainers], logManager, snapshotName))
+												{
+													logManager.log("Coultn't make snapshot", pika::logError);
+												}
+												else
+												{
+													logManager.log("Successfully created snapshot.");
+												}
+											}
+											else
+											{
+												logManager.log("File name invalid", pika::logError);
+											}
+
 										}
-										else
+										if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
 										{
-											logManager.log("Successfully created snapshot.");
+											ImGui::SetTooltip("Make snapshot");
 										}
+
+										ImGui::SameLine();
+										ImGui::InputText("snapshot name", snapshotName, sizeof(snapshotName));
 									}
-									else
+
+									ImGui::NewLine();
+									ImGui::Separator();
+
+								#pragma region snapshots
 									{
-										logManager.log("File name invalid", pika::logError);
+
+										auto snapshots = pika::getAvailableSnapshots(
+											containerManager.runningContainers[containerIds[itemCurrentCreatedContainers]]);
+
+										auto contentSize = ImGui::GetItemRectSize();
+										contentSize.y -= ImGui::GetFrameHeightWithSpacing();
+										contentSize.x /= 2;
+
+										ImGui::ListWithFilter("##list box snapshots", &currentSelectedSnapshot,
+											filterSnapshots, sizeof(filterSnapshots),
+											snapshots, contentSize);
+
+										ImGui::SameLine();
+
+										if (snapshots.size() == 0 || currentSelectedSnapshot >= snapshots.size())
+										{
+											ImGui::BeginDisabled(true);
+										}
+										else
+										{
+											ImGui::BeginDisabled(false);
+										}
+
+										if (ImGui::Button(ICON_FK_PLAY "##play snapshot"))
+										{
+											if (!containerManager.setSnapshotToContainer(
+												containerIds[itemCurrentCreatedContainers],
+												snapshots[currentSelectedSnapshot].c_str(), logManager
+												))
+											{
+												logManager.log("Failed to assign snapshot", pika::logError);
+											}
+										}
+
+										ImGui::EndDisabled();
+
+										if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
+										{
+											ImGui::SetTooltip("Play this snapshot to this container");
+										}
+
 									}
+								#pragma endregion
+
+									ImGui::EndTabItem();
 
 								}
-								if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
+
+								if (ImGui::BeginTabItem(ICON_FK_VIDEO_CAMERA " Record"))
 								{
-									ImGui::SetTooltip("Make snapshot");
-								}
+									//recording
+									{
+										if (c.flags.status == pika::RuntimeContainer::FLAGS::STATUS_RUNNING)
+										{
+											if (ImGui::Button(ICON_FK_VIDEO_CAMERA))
+											{
+												if (pika::isFileNameValid(recordingName, sizeof(recordingName)))
+												{
+													containerManager.startRecordingContainer
+													(containerIds[itemCurrentCreatedContainers], logManager, recordingName);
+												}
+												else
+												{
+													logManager.log("File name invalid", pika::logError);
+												}
 
-								ImGui::SameLine();
-								ImGui::InputText("snapshot name", snapshotName, sizeof(snapshotName));
-							}
+											}
+											if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
+											{
+												ImGui::SetTooltip("start recording");
+											}
+										}
+										else if (c.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_RECORDED)
+										{
+											if (ImGui::Button(ICON_FK_STOP_CIRCLE))
+											{
+												containerManager.stopRecordingContainer
+												(containerIds[itemCurrentCreatedContainers], logManager);
+											}
+											if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
+											{
+												ImGui::SetTooltip("stop recording");
+											}
+										}
+										else if (c.flags.status == pika::RuntimeContainer::FLAGS::STATUS_PAUSE)
+										{
+											ImGui::BeginDisabled(1);
+											if (ImGui::Button(ICON_FK_VIDEO_CAMERA))
+											{
 
-							//recording
-							{
-								if (ImGui::Button(ICON_FK_VIDEO_CAMERA))
-								{
+											}
+											ImGui::EndDisabled();
+											if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
+											{
+												ImGui::SetTooltip("Can't record while container is paused");
+											}
+										}
+										else if (c.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_PLAYBACK)
+										{
+											ImGui::BeginDisabled(1);
+											if (ImGui::Button(ICON_FK_VIDEO_CAMERA))
+											{
 
-								}
-								if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
-								{
-									ImGui::SetTooltip("start recording");
-								}
-								ImGui::SameLine();
-								ImGui::InputText("recording name", recordingName, sizeof(recordingName));
-							}
+											}
+											ImGui::EndDisabled();
+											if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
+											{
+												ImGui::SetTooltip("Can't record while container is on playback");
+											}
+										}
 
+										ImGui::BeginDisabled(c.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_RECORDED);
+										ImGui::SameLine();
+										ImGui::InputText("recording name", recordingName, sizeof(recordingName));
+										ImGui::EndDisabled();
 
-							ImGui::NewLine();
-							ImGui::Separator();
+									}
 
-						#pragma region snapshots
-							{
-								static int currentSelectedSnapshot = 0; //todo move
 
-								auto snapshots = pika::getAvailableSnapshots(
-									containerManager.runningContainers[containerIds[itemCurrentCreatedContainers]]);
+									ImGui::NewLine();
+									ImGui::Separator();
 
-								auto contentSize = ImGui::GetItemRectSize();
-								contentSize.y -= ImGui::GetFrameHeightWithSpacing();
-								contentSize.x /= 2;
 
-								ImGui::ListWithFilter("##list box snapshots", &currentSelectedSnapshot,
-									filterSnapshots, sizeof(filterSnapshots),
-									snapshots, contentSize);
+								#pragma region recordings
 
-								ImGui::SameLine();
+									auto recordings = pika::getAvailableRecordings(
+										containerManager.runningContainers[containerIds[itemCurrentCreatedContainers]]);
 
-								if (snapshots.size() == 0 || currentSelectedSnapshot >= snapshots.size())
-								{
-									ImGui::BeginDisabled(true);
-								}
-								else
-								{
-									ImGui::BeginDisabled(false);
-								}
+									auto contentSize = ImGui::GetItemRectSize();
+									contentSize.y -= ImGui::GetFrameHeightWithSpacing();
+									contentSize.x /= 2;
 
-								if(ImGui::Button(ICON_FK_PLAY "##play snapshot"))
-								{
-									if (!containerManager.setSnapshotToContainer(
-										containerIds[itemCurrentCreatedContainers],
-										snapshots[currentSelectedSnapshot].c_str(), logManager
-										))
+									ImGui::ListWithFilter("##list box recordings", &currentSelectedRecording,
+										filterSnapshots, sizeof(filterSnapshots),
+										recordings, contentSize);
+
+									ImGui::SameLine();
+
+									if (recordings.size() == 0 || currentSelectedRecording >= recordings.size()
+										|| c.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_RECORDED)
 									{
-										logManager.log("Failed to assign snapshot", pika::logError);
+										ImGui::BeginDisabled(true);
+									}
+									else
+									{
+										ImGui::BeginDisabled(false);
 									}
-								}
 
-								ImGui::EndDisabled();
+									if (ImGui::Button(ICON_FK_PLAY "##play recording"))
+									{
+										if (!containerManager.setRecordingToContainer(
+											containerIds[itemCurrentCreatedContainers],
+											recordings[currentSelectedSnapshot].c_str(), logManager
+											))
+										{
+											logManager.log("Failed to assign recording", pika::logError);
+										}
+									}
 
-								if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
-								{
-									ImGui::SetTooltip("Play this snapshot to this container");
+									ImGui::EndDisabled();
+														
+									if (c.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_RECORDED)
+									{
+										if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
+										{
+											ImGui::SetTooltip("Can't play a recording because the container is being recorded at the moment");
+										}
+									}
+									else
+									{
+										if (ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
+										{
+											ImGui::SetTooltip("Play this recording to this container");
+										}
+									}
+									
+
+
+
+								#pragma endregion
+
+
+									ImGui::EndTabItem();
 								}
 
+
+								ImGui::EndTabBar();
 							}
-						#pragma endregion
+
+							
+
+
+							
+
+							
+
+
+
+						
 
 						}
 					}

+ 4 - 1
Pika/core/pikaEditor/containersWindow/containersWindow.h

@@ -11,7 +11,7 @@ namespace pika
 	struct ContainersWindow
 	{
 
-		void init();
+		void init(pika::pikaImgui::ImGuiIdsManager &imguiIdsManager);
 
 		void update(pika::LogManager &logManager, bool &open, pika::LoadedDll &loadedDll,
 			pika::ContainerManager &containerManager, pika::pikaImgui::ImGuiIdsManager &imguiIdsManager);
@@ -27,9 +27,12 @@ namespace pika
 
 		int itemCurrentAvailableCOntainers = 0;
 		int itemCurrentCreatedContainers = 0;
+		int currentSelectedSnapshot = 0;
+		int currentSelectedRecording = 0;
 
 		bool createAtSpecificMemoryRegion = 0;
 
+		int imguiIds = 0;
 	};
 
 

+ 3 - 3
Pika/core/pikaEditor/editShortcuts/editShortcuts.cpp

@@ -4,7 +4,7 @@
 
 void pika::EditShortcutsWindow::init(pika::pikaImgui::ImGuiIdsManager &imguiIdManager)
 {
-	imguiId = imguiIdManager.getImguiIds();
+	imguiId = imguiIdManager.getImguiIds(2);
 	//todo save shortcuts
 }
 
@@ -14,7 +14,7 @@ void pika::EditShortcutsWindow::update(pika::ShortcutManager &shortcutManager, b
 
 	ImGui::SetNextWindowSize({400, 500});
 
-	ImGui::PushID(pika::pikaImgui::EditorImguiIds::editShortcutWindow);
+	ImGui::PushID(imguiId);
 
 	if (ImGui::Begin(ICON_NAME, &open,
 		ImGuiWindowFlags_NoDocking | 
@@ -25,7 +25,7 @@ void pika::EditShortcutsWindow::update(pika::ShortcutManager &shortcutManager, b
 		
 		ImGui::Text("Edit shortcuts\n");
 
-		if (ImGui::BeginChild(imguiId, {}, true))
+		if (ImGui::BeginChild(imguiId + 1, {}, true))
 		{
 
 

+ 4 - 3
Pika/core/pikaEditor/editor/editor.cpp

@@ -28,10 +28,11 @@ void pika::Editor::init(pika::ShortcutManager &shortcutManager, pika::pikaImgui:
 	shortcutManager.registerShortcut(RELOAD_DLL_SHORTCUTS, "Ctrl+Alt+R", &shouldReloadDll);
 	shortcutManager.registerShortcut(TRANSPARENT_EDITOR_WINDOW, "Ctrl+Alt+T", &windowFlags.transparentWindow);
 
+	imguiId = imguiIDManager.getImguiIds(1);
 
-	logWindow.init();
+	logWindow.init(imguiIDManager);
 	editShortcutsWindow.init(imguiIDManager);
-	containersWindow.init();
+	containersWindow.init(imguiIDManager);
 
 	
 	if (sfs::safeLoad(&optionsFlags, sizeof(optionsFlags), PIKA_ENGINE_SAVES_PATH "options", false) != sfs::noError)
@@ -97,7 +98,7 @@ void pika::Editor::update(const pika::Input &input,
 		//ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.2f, 0.2f, 0.3f, 1.0f));
 	
 	
-		ImGui::PushID(pika::pikaImgui::EditorImguiIds::mainEditorWindow);
+		ImGui::PushID(imguiId);
 
 		ImGui::SetNextWindowBgAlpha(0);
 

+ 1 - 0
Pika/core/pikaEditor/editor/editor.h

@@ -48,6 +48,7 @@ namespace pika
 		bool lastHideWindowState = optionsFlags.hideMainWindow;
 
 		bool shouldReloadDll = 0;
+		int imguiId = 0;
 	};
 
 

+ 3 - 4
Pika/core/pikaEditor/logs/logWindow.cpp

@@ -3,15 +3,14 @@
 #include <IconsForkAwesome.h>
 #include <pikaImgui/pikaImgui.h>
 
-void pika::LogWindow::init()
+void pika::LogWindow::init(pika::pikaImgui::ImGuiIdsManager &idManager)
 {
-
-
+	imguiId = idManager.getImguiIds();
 }
 
 void pika::LogWindow::update(pika::LogManager &logManager, bool &open)
 {
-	ImGui::PushID(pikaImgui::EditorImguiIds::logWindow);
+	ImGui::PushID(imguiId);
 
 	if (!ImGui::Begin(ICON_NAME, &open))
 	{

+ 4 - 1
Pika/core/pikaEditor/logs/logWindow.h

@@ -2,6 +2,7 @@
 #include <logs/log.h>
 #include <IconsForkAwesome.h>
 #include <imgui.h>
+#include <pikaImgui/pikaImgui.h>
 
 namespace pika
 {
@@ -10,7 +11,7 @@ namespace pika
 	struct LogWindow
 	{
 
-		void init();
+		void init(pika::pikaImgui::ImGuiIdsManager &idManager);
 
 		void update(pika::LogManager &logManager, bool &open);
 
@@ -19,6 +20,8 @@ namespace pika
 		static constexpr char *ICON_NAME = ICON_FK_COMMENT_O " logs";
 		bool autoScroll = true;
 		ImGuiTextFilter filter;
+
+		int imguiId = 0;
 	};
 
 }

+ 282 - 74
Pika/core/pikaRuntime/containerManager/containerManager.cpp

@@ -70,6 +70,28 @@ bool pika::ContainerManager::setSnapshotToContainer(pika::containerId_t containe
 	return true;
 }
 
+bool pika::ContainerManager::setRecordingToContainer(pika::containerId_t containerId, const char *recordingName, pika::LogManager &logManager)
+{
+	auto c = runningContainers.find(containerId);
+	if (c == runningContainers.end())
+	{
+		logManager.log((std::string("Couldn't find container for setting recording: #")
+			+ std::to_string(containerId)).c_str(),
+			pika::logError);
+		return false;
+	}
+
+	if (!setSnapshotToContainer(containerId, recordingName, logManager))
+	{
+		return false;
+	}
+
+	c->second.flags.status = pika::RuntimeContainer::FLAGS::STATUS_BEING_PLAYBACK;
+	c->second.flags.frameNumber = 0;
+	pika::strlcpy(c->second.flags.recordingName, recordingName, sizeof(c->second.flags.recordingName));
+
+}
+
 //todo use regions further appart in production
 void* pika::ContainerManager::allocateContainerMemory(pika::RuntimeContainer &container,
 	pika::ContainerInformation containerInformation, void *memPos)
@@ -210,7 +232,8 @@ void pika::ContainerManager::init()
 {
 }
 
-void pika::ContainerManager::update(pika::LoadedDll &loadedDll, pika::PikaWindow &window, pika::LogManager &logs)
+void pika::ContainerManager::update(pika::LoadedDll &loadedDll, pika::PikaWindow &window,
+	pika::LogManager &logs)
 {
 	PIKA_DEVELOPMENT_ONLY_ASSERT(loadedDll.dllHand != 0, "dll not loaded when trying to update containers");
 
@@ -223,72 +246,11 @@ void pika::ContainerManager::update(pika::LoadedDll &loadedDll, pika::PikaWindow
 	{
 		reloadDll(loadedDll, window, logs); //todo return 0 on fail
 
-		//todo mark shouldCallReaload
+		//todo mark shouldCallReaload or just call reload
 		
+	}
 
-
-		//for (auto &c : runningContainers)
-		//{
-		//	if (c.second.flags.running)
-		//	{
-		//		loadedDll.bindAllocatorDllRealm(&c.second.allocator);
-		//		//c.second.pointer->reload...
-		//		loadedDll.resetAllocatorDllRealm();
-		//	}
-		//	else
-		//	{
-		//		c.second.flags.shouldCallReaload = true;
-		//	}
-		//
-		//	
-		//}
-	}
-
-	//if (loadedDll.shouldReloadDll() || window.input.buttons[pika::Button::P].released())
-	//{
-	//	pika::LoadedDll newDll = {};
-	//
-	//
-	//	newDll.tryToloadDllUntillPossible(!loadedDll.id, logs); //create a new copy with a new id 
-	//
-	//#if 0
-	//	//clear containers that dissapeared
-	//	{
-	//		std::unordered_set<std::string> containerNames;
-	//		for (auto &c : newDll.containerInfo)
-	//		{
-	//			containerNames.insert(c.containerName);
-	//		}
-	//
-	//		std::vector<pika::containerId_t> containersToClean;
-	//		for (auto &i : runningContainers)
-	//		{
-	//			if (containerNames.find(i.second.baseContainerName) ==
-	//				containerNames.end())
-	//			{
-	//				std::string l = "Killed container because it does not exist anymore in dll: " + i.second.baseContainerName
-	//					+ " #" + std::to_string(i.first);
-	//				logs.log(l.c_str(), pika::logError);
-	//
-	//				containersToClean.push_back(i.first);
-	//			}
-	//		}
-	//
-	//		for (auto i : containersToClean)
-	//		{
-	//			destroyContainer(i, loadedDll, logs);
-	//		}
-	//	}
-	//#endif
-	//
-	//	//set new dll
-	//	loadedDll.unloadDll();
-	//
-	//	loadedDll = newDll;
-	//		
-	//	loadedDll.gameplayReload_(window.context);
-	//}
-
+	
 	
 #pragma endregion
 
@@ -300,6 +262,8 @@ void pika::ContainerManager::update(pika::LoadedDll &loadedDll, pika::PikaWindow
 		if (c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_RUNNING
 			||
 			c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_RECORDED
+			||
+			c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_PLAYBACK
 			)
 		{
 			
@@ -311,9 +275,91 @@ void pika::ContainerManager::update(pika::LoadedDll &loadedDll, pika::PikaWindow
 				c.second.imguiWindowId != 0), "we have a fbo but no imguiwindow id"
 			);
 
-			if (c.second.imguiWindowId)
+			auto windowInput = window.input;
+
+		#if PIKA_DEVELOPMENT
+
+			if (c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_RECORDED)
+			{
+				if (!makeRecordingStep(c.first, logs, windowInput))
+				{
+
+					c.second.flags.status = pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
+
+					logs.log((std::string("Stopped container recording because we couldn't oppen file") 
+						+ std::to_string(c.first)).c_str(),
+						pika::logError);
+				}
+			}
+			
+			
+			
+		#endif
+
+			if (c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_BEING_PLAYBACK)
+			{
+				pika::Input readInput;
+
+				std::string fileName = c.second.flags.recordingName;
+				fileName += ".recording";
+				fileName = PIKA_ENGINE_RESOURCES_PATH + fileName;
+
+				auto s = pika::getFileSize(fileName.c_str());
+				if (c.second.flags.frameNumber * sizeof(pika::Input) >= s && s != 0)
+				{
+					//todo optional logs here
+					if (!setSnapshotToContainer(c.first, c.second.flags.recordingName, logs)) 
+					{
+						logs.log((std::string("Stopped container playback because we couldn't assign it's snapshot on frame 0")
+							+ std::to_string(c.first)).c_str(),
+							pika::logError);
+						c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
+						goto endContainerErrorChecking;
+					}
+					c.second.flags.frameNumber = 0;
+				}
+
+				if (s == 0)
+				{
+					logs.log((std::string("Stopped container playback because we couldn't oppen file or its content is empty")
+						+ std::to_string(c.first)).c_str(),
+						pika::logError);
+					c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
+				}
+				else if (s % sizeof(pika::Input) != 0)
+				{
+					logs.log((std::string("Stopped container playback because the file content is corrupt")
+						+ std::to_string(c.first)).c_str(),
+						pika::logError);
+					c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
+				}
+				if (!pika::readEntireFile(fileName.c_str(), &readInput, sizeof(pika::Input), sizeof(pika::Input) * c.second.flags.frameNumber))
+				{
+					logs.log((std::string("Stopped container playback because we couldn't oppen file")
+						+ std::to_string(c.first)).c_str(),
+						pika::logError);
+					c.second.flags.status == pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
+				}
+				else
+				{
+					windowInput = readInput;
+					c.second.flags.frameNumber++;
+				}
+
+
+			}
+
+			endContainerErrorChecking:
+
+
+		#if PIKA_PRODUCTION
+			constexpr bool isProduction = 1;
+		#else
+			constexpr bool isProduction = 0;
+		#endif
+
+			if (c.second.imguiWindowId && !isProduction)
 			{
-				//todo remove in production
 
 				ImGui::PushID(c.second.imguiWindowId);
 				
@@ -333,31 +379,34 @@ void pika::ContainerManager::update(pika::LoadedDll &loadedDll, pika::PikaWindow
 
 				ImGui::PopID();
 
-				auto state = window.windowState;
-				state.w = s.x;
-				state.h = s.y;
+				auto windowState = window.windowState;
+				windowState.w = s.x;
+				windowState.h = s.y;
 
-				c.second.requestedContainerInfo.requestedFBO.resizeFramebuffer(state.w, state.h);
+				c.second.requestedContainerInfo.requestedFBO.resizeFramebuffer(windowState.w, windowState.h);
 
 				glBindFramebuffer(GL_FRAMEBUFFER, c.second.requestedContainerInfo.requestedFBO.fbo);
 
 				loadedDll.bindAllocatorDllRealm(&c.second.allocator);
-				c.second.pointer->update(window.input, state, c.second.requestedContainerInfo);
+				c.second.pointer->update(windowInput, windowState, c.second.requestedContainerInfo);
 				loadedDll.resetAllocatorDllRealm();
 
 				glBindFramebuffer(GL_FRAMEBUFFER, 0);
 
-
 			}
 			else
 			{
 				loadedDll.bindAllocatorDllRealm(&c.second.allocator);
-				c.second.pointer->update(window.input, window.windowState, c.second.requestedContainerInfo);
+				c.second.pointer->update(windowInput, window.windowState, c.second.requestedContainerInfo);
 				loadedDll.resetAllocatorDllRealm();
 			}
 
 
 		}
+		else
+		{
+			//still keep it running on the same frame mabe
+		}
 
 	}
 #pragma endregion
@@ -567,6 +616,87 @@ bool pika::ContainerManager::makeSnapshot(containerId_t id, pika::LogManager &lo
 	return true;
 }
 
+bool pika::ContainerManager::startRecordingContainer(containerId_t id, pika::LogManager &logManager, const char *fileName)
+{
+	auto c = runningContainers.find(id);
+	if (c == runningContainers.end())
+	{
+		logManager.log((std::string("Couldn't find container for making recording: #") + std::to_string(id)).c_str(),
+			pika::logError);
+		return false;
+	}
+
+	if(c->second.flags.status != pika::RuntimeContainer::FLAGS::STATUS_RUNNING)
+	{
+		logManager.log((std::string("Trying to record a container that is not running (on status): #") + std::to_string(id)).c_str(),
+			pika::logError);
+		return false;
+	}
+
+
+	std::string filePath = PIKA_ENGINE_RESOURCES_PATH;
+	filePath += fileName;
+
+	filePath += ".recording";
+
+	if (filePath.size() > sizeof(c->second.flags.recordingName) - 1)
+	{
+		logManager.log((std::string("File path too big (on trying to record)") + std::to_string(id)).c_str(),
+			pika::logError);
+		return 0;
+	}
+
+	if (!makeSnapshot(id, logManager, fileName)) 
+	{
+		logManager.log((std::string("Couldn't make snapshot for starting recording") + std::to_string(id)).c_str(),
+			pika::logError);
+		return 0;
+	}
+
+
+
+	c->second.flags.status = pika::RuntimeContainer::FLAGS::STATUS_BEING_RECORDED;
+	pika::strlcpy(c->second.flags.recordingName, filePath, sizeof(c->second.flags.recordingName));
+
+
+
+}
+
+bool pika::ContainerManager::stopRecordingContainer(containerId_t id, pika::LogManager &logManager)
+{
+	auto c = runningContainers.find(id);
+	if (c == runningContainers.end())
+	{
+		logManager.log((std::string("Couldn't find container for stopping recording: #") + std::to_string(id)).c_str(),
+			pika::logError);
+		return false;
+	}
+
+	c->second.flags.status = pika::RuntimeContainer::FLAGS::STATUS_RUNNING;
+
+}
+
+bool pika::ContainerManager::makeRecordingStep(containerId_t id, pika::LogManager &logManager,
+	pika::Input &input)
+{
+	auto c = runningContainers.find(id);
+	if (c == runningContainers.end())
+	{
+		logManager.log((std::string("Couldn't find container for making recording step: #") + std::to_string(id)).c_str(),
+			pika::logError);
+		return false;
+	}
+
+	if (!pika::appendToFile(c->second.flags.recordingName, &input, sizeof(input)))
+	{
+		logManager.log((std::string("Couldn't append to file for recording container") + std::to_string(id)).c_str(),
+			pika::logError);
+		return false;
+	}
+
+	return true;
+}
+
 bool pika::ContainerManager::forceTerminateContainer(containerId_t id, pika::LoadedDll &loadedDll, pika::LogManager &logManager)
 {
 	PIKA_DEVELOPMENT_ONLY_ASSERT(loadedDll.dllHand != 0, "dll not loaded when trying to destroy container");
@@ -664,6 +794,32 @@ std::vector<std::string> pika::getAvailableSnapshots(pika::RuntimeContainer &inf
 	return files;
 }
 
+std::vector<std::string> pika::getAvailableRecordings(pika::RuntimeContainer &info)
+{
+	auto snapshots = getAvailableSnapshots(info);
+	
+	std::vector<std::string> returnVec;
+	returnVec.reserve(snapshots.size());
+
+	auto curDir = std::filesystem::directory_iterator(PIKA_ENGINE_RESOURCES_PATH);
+
+	for (const auto &iter : curDir)
+	{
+		if (std::filesystem::is_regular_file(iter)
+			&& iter.path().extension() == ".recording"
+			)
+		{
+
+			if (std::find(snapshots.begin(), snapshots.end(), iter.path().stem().string()) != snapshots.end())
+			{
+				returnVec.push_back(iter.path().stem().string());
+			}
+		}
+	}
+
+	return returnVec;
+}
+
 std::vector<std::string> pika::getAvailableSnapshotsAnyMemoryPosition(pika::RuntimeContainer &info)
 {
 	std::vector<std::string> files;
@@ -687,6 +843,32 @@ std::vector<std::string> pika::getAvailableSnapshotsAnyMemoryPosition(pika::Runt
 	return files;
 }
 
+std::vector<std::string> pika::getAvailableRecordingAnyMemoryPosition(pika::RuntimeContainer &info)
+{
+	auto snapshots = getAvailableSnapshotsAnyMemoryPosition(info);
+
+	std::vector<std::string> returnVec;
+	returnVec.reserve(snapshots.size());
+
+	auto curDir = std::filesystem::directory_iterator(PIKA_ENGINE_RESOURCES_PATH);
+
+	for (const auto &iter : curDir)
+	{
+		if (std::filesystem::is_regular_file(iter)
+			&& iter.path().extension() == ".recording"
+			)
+		{
+
+			if (std::find(snapshots.begin(), snapshots.end(), iter.path().stem().string()) != snapshots.end())
+			{
+				returnVec.push_back(iter.path().stem().string());
+			}
+		}
+	}
+
+	return returnVec;
+}
+
 std::vector<std::string> pika::getAvailableSnapshotsAnyMemoryPosition(pika::ContainerInformation &info)
 {
 	std::vector<std::string> files;
@@ -710,6 +892,32 @@ std::vector<std::string> pika::getAvailableSnapshotsAnyMemoryPosition(pika::Cont
 	return files;
 }
 
+std::vector<std::string> pika::getAvailableRecordingsAnyMemoryPosition(pika::ContainerInformation &info)
+{
+	auto snapshots = getAvailableSnapshotsAnyMemoryPosition(info);
+
+	std::vector<std::string> returnVec;
+	returnVec.reserve(snapshots.size());
+
+	auto curDir = std::filesystem::directory_iterator(PIKA_ENGINE_RESOURCES_PATH);
+
+	for (const auto &iter : curDir)
+	{
+		if (std::filesystem::is_regular_file(iter)
+			&& iter.path().extension() == ".recording"
+			)
+		{
+
+			if (std::find(snapshots.begin(), snapshots.end(), iter.path().stem().string()) != snapshots.end())
+			{
+				returnVec.push_back(iter.path().stem().string());
+			}
+		}
+	}
+
+	return returnVec;
+}
+
 bool pika::checkIfSnapshotIsCompatible(pika::RuntimeContainer &info, const char *snapshotName)
 {
 

+ 14 - 1
Pika/core/pikaRuntime/containerManager/containerManager.h

@@ -35,6 +35,9 @@ namespace pika
 		bool setSnapshotToContainer(pika::containerId_t containerId, const char* snapshotName,
 			pika::LogManager &logManager);
 
+		bool setRecordingToContainer(pika::containerId_t containerId, const char *recordingName,
+			pika::LogManager &logManager);
+
 		void* allocateContainerMemory(pika::RuntimeContainer &container, pika::ContainerInformation containerInformation, void *memPos = 0);
 
 		//buffer should have the correct size
@@ -61,6 +64,13 @@ namespace pika
 
 		bool makeSnapshot(containerId_t id, pika::LogManager &logManager, const char* fileName);
 
+		bool startRecordingContainer(containerId_t id, pika::LogManager &logManager, const char *fileName);
+
+		bool stopRecordingContainer(containerId_t id, pika::LogManager &logManager);
+
+		bool makeRecordingStep(containerId_t id, pika::LogManager &logManager, 
+			pika::Input &input);
+
 		//same as destroy container but doesn't call user destructors
 		bool forceTerminateContainer(containerId_t id, pika::LoadedDll &loadedDll,
 			pika::LogManager &logManager);
@@ -78,10 +88,13 @@ namespace pika
 
 
 	std::vector<std::string> getAvailableSnapshots(pika::RuntimeContainer &info);
+	std::vector<std::string> getAvailableRecordings(pika::RuntimeContainer &info);
 
 	std::vector<std::string> getAvailableSnapshotsAnyMemoryPosition(pika::RuntimeContainer &info);
-	
+	std::vector<std::string> getAvailableRecordingAnyMemoryPosition(pika::RuntimeContainer &info);
+
 	std::vector<std::string> getAvailableSnapshotsAnyMemoryPosition(pika::ContainerInformation &info);
+	std::vector<std::string> getAvailableRecordingsAnyMemoryPosition(pika::ContainerInformation &info);
 
 	bool checkIfSnapshotIsCompatible(pika::RuntimeContainer &info, const char *snapshotName);
 

+ 13 - 1
Pika/core/pikaRuntime/runtimeContainer/runtimeContainer.h

@@ -41,13 +41,17 @@ struct RuntimeContainer
 		{
 			STATUS_PAUSE = 0,
 			STATUS_RUNNING = 1,
-			STATUS_BEING_RECORDED = 1,
+			STATUS_BEING_RECORDED = 2,
+			STATUS_BEING_PLAYBACK = 3,
 		};
 
 		int status = STATUS_RUNNING;
 
 		bool shouldCallReaload = 0; //if the container happens to be on pause when the dll reloads we mark this to true
 
+		char recordingName[256] = {};
+		int frameNumber = 0;
+
 		const char *getStatusName()
 		{
 
@@ -70,6 +74,10 @@ struct RuntimeContainer
 			{
 				return "on recording";
 			}
+			else if (status == STATUS_BEING_PLAYBACK)
+			{
+				return "on input playback";
+			}
 		}
 		
 		const char *getStatusIcon()
@@ -86,6 +94,10 @@ struct RuntimeContainer
 			{
 				return ICON_FK_VIDEO_CAMERA;
 			}
+			else if (status == STATUS_BEING_PLAYBACK)
+			{
+				return ICON_FK_REPEAT;
+			}
 		}
 
 	}flags;

+ 0 - 4
Pika/core/sharedRuntime/pikaImgui/pikaImgui.h

@@ -40,10 +40,6 @@ namespace pika
 		{
 			enum
 			{
-				mainEditorWindow = 100,
-				editShortcutWindow = 200,
-				logWindow = 300,
-				containersWindow = 400,
 
 				idsCount = 4000
 			};

+ 5 - 0
Pika/core/sharedRuntime/windowSystemm/window.cpp

@@ -28,6 +28,11 @@ void pika::PikaWindow::create()
 		wr = {};
 	}
 #endif
+	
+	if (wr.x < 0 || wr.y < 0 || wr.z <= 0 || wr.w <= 0)
+	{
+		wr = {};
+	}
 
 	context.wind = glfwCreateWindow(wr.z, wr.w, "Pika", NULL, NULL);
 	glfwSetWindowPos(context.wind, wr.x, wr.y);

二進制
Pika/engineResources/engineSaves/windowPos1.bin


二進制
Pika/engineResources/engineSaves/windowPos2.bin


二進制
Pika/engineResources/r.recording


二進制
Pika/engineResources/r.snapshot


二進制
Pika/engineResources/record.recording


二進制
Pika/engineResources/record.snapshot


二進制
Pika/engineResources/record1.recording


二進制
Pika/engineResources/record1.snapshot


二進制
Pika/engineResources/recordtest.recording


二進制
Pika/engineResources/recordtest.snapshot


二進制
Pika/engineResources/test.snapshot


二進制
Pika/engineResources/test1.recording


二進制
Pika/engineResources/test1.snapshot


二進制
Pika/engineResources/test2.snapshot


二進制
Pika/engineResources/testrecordfirst.recording


二進制
Pika/engineResources/testrecordfirst.snapshot


+ 1 - 1
Pika/gameplay/containers/pikaGameplay.h

@@ -75,7 +75,7 @@ struct Gameplay : public Container
 
 		*r += input.deltaTime * 4.f;
 
-		renderer.renderRectangle({10, 10, 100, 100}, Colors_Green, {}, *r);
+		renderer.renderRectangle({10, 10, 100, 100}, Colors_Red, {}, *r);
 
 		//if (input.lMouse.pressed())
 		//{

+ 6 - 2
Pika/resources/logs.txt

@@ -1,2 +1,6 @@
-#2022-10-12 20:35:18: Created container: Gameplay
-#2022-10-12 20:35:35: Destroyed continer: Gameplay #1
+#2022-10-21 13:32:05: Created container: Gameplay
+#2022-10-21 13:32:25: Loaded snapshot
+#2022-10-21 13:32:27: Loaded snapshot
+#2022-10-21 13:32:30: Loaded snapshot
+#2022-10-21 13:32:36: Loaded snapshot
+#2022-10-21 13:32:37: Destroyed continer: Gameplay #1