A script can now be attached to any number of entities at once

dev
Joey Pollack 3 years ago
parent 060bfcf6c9
commit d75f37d575

@ -7,10 +7,14 @@ Build System:
✔ Modify .sh scripts to recognize the noeditor flag @done (1/25/2022, 3:59:23 PM)
Core:
☐ Update console gui system to store the full message meta-data so that filters can be applied @High
☐ Create log rotation system so that log files do not grow to GB in size... @critical
- If file is X MBs, check for file with .old ext and erase if exists, .old to current file and create new log file
☐ Figure out how to represent Unique Entities and entity instances - and how this will work with UUIDs @critical
☐ Design Entity Template system
☐ Add log settings to the state file
✔ Implement generic serialization system @done(22-06-29 18:44)
✔ JSON serializable base class @done(22-06-29 17:41)
✔ JSON implementions should be stubbed out in non-editor builds @done(22-06-29 17:41)
@ -27,7 +31,6 @@ Core:
✔ assets @done(22-05-17 14:27)
✔ gui @done(22-05-17 14:27)
✔ Replace the File Browser (imgui) class with the NFD library (https://github.com/btzy/nativefiledialog-extended) @high @done(22-05-23 16:00)
☐ Add log settings to the state file
✔ Refactor log system to use separate log level methods instead of passing log level @done(22-05-12 16:46)
✔ Add log level options to config script @done(22-05-12 16:46)
✔ Add run modes (Editor, Game, Test) to state file @done (9/15/2021, 7:27:03 PM)
@ -35,15 +38,19 @@ Core:
✔ Read the window size and position on shutdown and write these to the state file @done (2/8/2022, 4:39:37 PM)
Physics:
☐ Joint Component to allow parent/child entities to both use the physics system @high
☐ Come up with a way to wrap Box2D into an API @low
✔ Research Box2D as a possible physics library @done (10/27/2021, 7:40:44 PM)
✔ Add Box2D to the project as an external library @done (10/27/2021, 7:40:46 PM)
✔ Add a scene to the tester to test Box2D usage @done (10/28/2021, 2:42:45 PM)
☐ Come up with a way to wrap Box2D into an API
☐ Joint Component to allow parent/child entities to both use the physics system
Scripting:
☐ Add a Log methods to the CoreAPI
☐ Add Entity class to wrap entity id values
- Foreign class that stores the entity id values and gives access to
- foreign methods for interacting with that entity (getting components/scripts)
✔ Add a Log methods to the CoreAPI @done(23-01-11 15:24)
✔ Allow scripts to interact (calling methods in other scripts) @done(23-01-10 16:54)
- In order for a script to be registered with the World API it MUST
@ -56,11 +63,16 @@ Scripting:
✔ Script Asset @done(22-11-14 18:19)
Script Managment class:
Script State class:
✔ Allow for running script class objects @done(23-01-11 15:28)
✔ Allow for running raw code snippets (with module importing made easy) @done(23-01-11 15:29)
✔ Wrapper methods for registering foreign classes and methods @done(23-01-11 15:29)
✔ Wrapper methods for getting handles to classes @done(23-01-11 15:29)
✘ Manage LUA states @cancelled(22-05-13 17:31)
☐ Initialize new scripts
☐ Run given script with given state
☐ Add any generated errors to the Script object
✘ Initialize new scripts @cancelled(23-01-11 15:28)
✘ Run given script with given state @cancelled(23-01-11 15:28)
✘ Add any generated errors to the Script object @cancelled(23-01-11 15:28)
Interface Class (Core API):
☐ Provide Methods that give access to the C++ code
@ -71,8 +83,9 @@ Audio:
☐ Design Audio API
Assets:
☐ Document Index.Dat and the AssetIndex class
✔ Internal Asset Manager @high @done (1/25/2022, 3:58:20 PM)
☐ Document Index.Dat and the AssetIndex class
✔ Move the GenerateFont method from internal_font.h into data_manager.h @done(22-06-29 17:42)
Types:
@ -156,7 +169,7 @@ ECS:
✔ Single UUID @done(22-06-01 14:01)
✔ Functionality for adding/working with components (through EnTT) @done(22-06-01 14:01)
☐ Serialize
☐ JSON
✔ JSON @done(23-01-11 15:35)
☐ Binary
Components:
@ -171,11 +184,12 @@ ECS:
✔ Script @done(22-11-14 18:19)
☐ Audio Listener
Physics:
☐ Rigid Body (Box2D)
☐ Box Collider (Box2D)
☐ Joint Component
✔ Rigid Body (Box2D) @done(23-01-11 15:35)
✔ Collider (Box2D) @done(23-01-11 15:35)
World (Lunariums version of a "Scene"):
Add Render layer property to all renderable components
Add Render layer property to all renderable components @done(23-01-11 15:35)
✔ Implement memento pattern to save the initial state of the world @done(22-11-14 18:19)
✔ Implement running the world and resetting to initial state @done(22-11-14 18:19)
✔ Implement the world without Regions first @done(22-11-14 18:20)

@ -1,7 +1,11 @@
Editor:
☐ Add ability to browse and restore trashed assets @High
☐ Add button to flip image assets vertically
☐ Design a custom editor style @low
☐ Save and unload world data when a new world is selected
✔ Generate boiler-plate code when a new script is created @critical @done(23-01-11 13:49)
✔ Add pure virtual ShowProperties method to EditorAsset @done(22-11-28 20:11)
✔ Script Editor Asset @done(22-11-14 18:19)
✔ Editor Assets need to switch to using UUIDs @critical @done(22-11-02 18:51)
@ -10,9 +14,6 @@ Editor:
✔ Add Entity children @done(22-09-14 15:07)
✔ Entity Parent/Child hierarchy system @done(22-09-14 15:07)
✔ Give Entities a name property separate from the tag component @done(22-09-14 15:06)
☐ Add button to flip image assets vertically
☐ Design a custom editor style @low
☐ Save and unload world data when a new world is selected
✔ Load the selected world when double clicked on in the asset browser @done(22-07-05 14:29)
✔ Asset Location MUST be relative to the project root directory @critical @done(22-05-20 18:35)
✔ Switch to NFD dialogs @done(22-05-20 18:35)
@ -24,8 +25,7 @@ Editor:
✔ Turn World into an editor asset that can be created @done(22-07-05 14:04)
✔ Store entities in the World object @done(22-07-06 17:53)
✔ Implement Saving/loading the World asset @done(22-07-06 17:53)
☐ Test the Asset Trashing system @high
☐ Add ability to browse and restore trashed assets
✔ Test the Asset Trashing system @high @done(23-01-11 15:22)
✔ Figure out how to make game asset types integrate with editor asset types @critical @done(22-06-27 13:32)
- Probably just wrap the game object in an EditorAsset object if needed

@ -46,7 +46,7 @@ namespace lunarium
Console::Console(const char* name, PanelDockZone dock_zone, bool isOpen, int window_flags)
: Panel(name, dock_zone, isOpen, window_flags),
mbNewCommand(false), mRecalledCommand(-1), mIsFocused(false), mListener(nullptr),
mbOglDebug(false), mbInfoVerbose(false), mpListener(nullptr), mInputWindowHeight(20)
mbOglDebug(false), mbInfoVerbose(false), mbInfoDebug(false), mpListener(nullptr), mInputWindowHeight(20)
{
memset(mBuffer, 0, CONSOLE_BUFFER_SIZE);
mpListener = Logger::GetInstance()->AddListener(new GuiListener(this));
@ -76,6 +76,12 @@ namespace lunarium
}
void Console::SetDebugFlag(bool flag)
{
mbInfoDebug = flag;
}
void Console::ClearMessageHistory()
{
mMsgHistory.clear();
@ -105,7 +111,8 @@ namespace lunarium
{
if ((mMsgHistory[i].find("[GRAPHICS INTERNAL DEBUG]") != std::string::npos && !mbOglDebug)
|| (mMsgHistory[i].find("[TRACE]") != std::string::npos && !mbInfoVerbose))
|| (mMsgHistory[i].find("[TRACE]") != std::string::npos && !mbInfoVerbose)
|| (mMsgHistory[i].find("[DEBUG]") != std::string::npos && !mbInfoDebug))
{
continue;
}

@ -53,6 +53,7 @@ namespace lunarium
void SetOGLDebugFlag(bool flag);
void SetVerboseFlag(bool flag);
void SetDebugFlag(bool flag);
private:
// INPUT COMMAND STUFF
@ -71,6 +72,7 @@ namespace lunarium
GuiListener* mListener;
bool mbOglDebug;
bool mbInfoVerbose;
bool mbInfoDebug;
private:
void CheckFocus();

@ -349,6 +349,7 @@ namespace lunarium { namespace editor
void ContentManager::MoveAsset(EditorAsset* asset, std::filesystem::path to)
{
std::filesystem::path from = mpProject->GetAssetDirectory() / asset->GetFileLocation();
to /= asset->GetFileLocation().filename();
// Not all assets will have files associated with them
if (std::filesystem::exists(from))

@ -53,6 +53,9 @@ namespace lunarium { namespace editor
/// file: the full path to the raw file
/// to_location: the location inside the project's asset directory to import to (this MUST be a relative path starting in the Asset dir)
[[nodiscard]] OpRes ImportFile(std::filesystem::path file, std::filesystem::path to_location, AssetType type, LUUID& id);
/// @brief Trashes an asset
/// @param asset_id the UUID of the asset to trash
void RemoveAsset(LUUID asset_id);
void MoveAsset(EditorAsset* asset, std::filesystem::path to);

@ -19,6 +19,12 @@ namespace lunarium { namespace editor
Script::Script(std::filesystem::path file_location, std::filesystem::path asset_dir)
: EditorAsset(AssetType::EATYPE_SCRIPT)
{
// This is an existing script and data will be set later
// NOTE: Kind of hacky...
if (file_location.string().size() < 1 && asset_dir.string().size() < 1)
return;
std::string full_path = (asset_dir / file_location).string();
if (!std::filesystem::exists(full_path))

@ -534,6 +534,12 @@ namespace editor
}
}
}
void Editor::OnAssetTrash(EditorAsset* pAsset)
{
ContentManager::GetInstance().RemoveAsset(pAsset->GetID());
}
void Editor::OnAssetSelected(EditorAsset* pAsset)
{

@ -62,6 +62,7 @@ namespace lunarium { namespace editor
void OnEntitySelect(lunarium::Entity* pEnt);
//void ChangeWorld(lunarium::World* pWorld);
void OnAssetOpen(EditorAsset* pAsset);
void OnAssetTrash(EditorAsset* pAsset);
void OnAssetSelected(EditorAsset* pAsset);
void OnNewAsset(EditorAsset* pAsset);
void OnAssetUpdate(EditorAsset* pAsset);

@ -27,7 +27,7 @@ namespace editor
{
AssetBrowser::AssetBrowser(std::filesystem::path dir, Editor* pEditor)
: Panel("Asset Browser", PanelDockZone::DDZ_BOTTOM, true, (ImGuiWindowFlags)ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoScrollbar),
mAssetDirectory(dir), mpEditor(pEditor), mSyncTree(false)
mAssetDirectory(dir), mpEditor(pEditor), mSyncTree(false), mpHoveredAsset(nullptr), mbMenusOpen(false)
{
DefinePopups();
}
@ -229,6 +229,9 @@ namespace editor
for (auto iter = assets.begin(); iter != assets.end(); iter++)
{
if ((*iter)->GetIsTrashed())
continue;
if (ImGui::Selectable((*iter)->GetFileLocation().stem().string().c_str()))
{
// Show properties if this is new selection (meaning wasn't selected last frame)
@ -252,10 +255,11 @@ namespace editor
mpEditor->OnAssetOpen((*iter));
}
if (ImGui::IsItemHovered() && ImGui::IsMouseClicked(ImGuiMouseButton_Right))
if (ImGui::IsItemHovered() && ImGui::IsItemClicked(ImGuiMouseButton_Right))
{
// TODO: CONTEXT MENU FOR ITEMS - Test Removing/Trashing
// Change context menu to apply to the hovered asset
mpHoveredAsset = (*iter);
}
}
@ -271,53 +275,82 @@ namespace editor
// CONTEXT MENUS
void AssetBrowser::DoContentContextMenu()
{
if (ImGui::BeginPopupContextWindow(0, 1, false))
if (ImGui::BeginPopupContextWindow(0, ImGuiPopupFlags_MouseButtonRight))
{
if (ImGui::Button("New Folder"))
if (mpHoveredAsset)
{
//mNewFolder = true;
OpenPopup(PopUp::NEW_FOLDER).LogIfFailed(Editor::LogCat);
mbMenusOpen = true;
DoHoveredContextMenu();
}
else
{
DoEmptySpaceContextMenu();
}
// TODO: Buttons for creating/importing new assets
ImGui::EndPopup();
}
else if (mbMenusOpen)
{
mbMenusOpen = false;
mpHoveredAsset = nullptr;
}
}
void AssetBrowser::DoHoveredContextMenu()
{
if (ImGui::Button("Trash Asset"))
{
mpEditor->OnAssetTrash(mpHoveredAsset);
ImGui::CloseCurrentPopup();
mpHoveredAsset = nullptr;
}
}
void AssetBrowser::DoEmptySpaceContextMenu()
{
if (ImGui::Button("New Folder"))
{
// mNewFolder = true;
OpenPopup(PopUp::NEW_FOLDER).LogIfFailed(Editor::LogCat);
}
if (ImGui::BeginMenu("New Asset"))
if (ImGui::BeginMenu("New Asset"))
{
if (ImGui::MenuItem("New World"))
{
if (ImGui::MenuItem("New World"))
{
OpenPopup(PopUp::NEW_WORLD).LogIfFailed(Editor::LogCat);
}
OpenPopup(PopUp::NEW_WORLD).LogIfFailed(Editor::LogCat);
}
if (ImGui::MenuItem("New Script"))
{
OpenPopup(PopUp::NEW_SCRIPT).LogIfFailed(Editor::LogCat);
}
ImGui::EndMenu();
if (ImGui::MenuItem("New Script"))
{
OpenPopup(PopUp::NEW_SCRIPT).LogIfFailed(Editor::LogCat);
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Import Asset"))
if (ImGui::BeginMenu("Import Asset"))
{
if (ImGui::MenuItem("Image"))
{
if (ImGui::MenuItem("Image"))
{
std::filesystem::path outPath;
std::filesystem::path outPath;
// prepare filters for the dialog
FileSystem::FilterItem filterItem[3] = {{"Image file", "png"}, {"Image File", "jpg"}, {"Image File", "jpeg"}};
// prepare filters for the dialog
FileSystem::FilterItem filterItem[3] = {{"Image file", "png"}, {"Image File", "jpg"}, {"Image File", "jpeg"}};
// show the dialog
FileSystem::DialogResult result = FileSystem::OpenFileDialog(outPath, filterItem, 3);
if (result == FileSystem::DialogResult::OK)
{
Logger::Info(Editor::LogCat, "Importing asset: %s", outPath.string().c_str());
// show the dialog
FileSystem::DialogResult result = FileSystem::OpenFileDialog(outPath, filterItem, 3);
if (result == FileSystem::DialogResult::OK)
{
Logger::Info(Editor::LogCat, "Importing asset: %s", outPath.string().c_str());
LUUID id = 0;
ContentManager::GetInstance().ImportFile(outPath, mSelectedDir / outPath.filename(),
AssetType::EATYPE_IMAGE, id).LogIfFailed(Editor::LogCat);
}
LUUID id = 0;
ContentManager::GetInstance().ImportFile(outPath, mSelectedDir / outPath.filename(),
AssetType::EATYPE_IMAGE, id)
.LogIfFailed(Editor::LogCat);
}
ImGui::EndMenu();
}
// TODO: Buttons for creating/importing new assets
ImGui::EndPopup();
ImGui::EndMenu();
}
}
@ -344,66 +377,75 @@ namespace editor
{
// New Folder
AddPopup(PopUp::NEW_FOLDER, "New Folder Name", [](Panel *p)
{
bool stay_open = true;
AssetBrowser* ab = (AssetBrowser*)p;
char name_buf[64] = "New Folder";
ImGui::TextUnformatted("Folder Name: ");
ImGui::SameLine();
if (ImGui::InputText("##Folder Name", name_buf, 64, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue))
{
bool stay_open = true;
AssetBrowser* ab = (AssetBrowser*)p;
char name_buf[64] = "New Folder";
ImGui::TextUnformatted("Folder Name: ");
ImGui::SameLine();
if (ImGui::InputText("##Folder Name", name_buf, 64, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue))
{
std::filesystem::create_directory(ab->mSelectedDir / name_buf);
stay_open = false;
ImGui::CloseCurrentPopup();
}
std::filesystem::create_directory(ab->mSelectedDir / name_buf);
stay_open = false;
ImGui::CloseCurrentPopup();
}
if (Core::Input().IsKeyDown(KeyCode::ESCAPE, true))
{
stay_open = false;
ImGui::CloseCurrentPopup();
}
return stay_open;
}).LogIfFailed(Editor::LogCat);
if (Core::Input().IsKeyDown(KeyCode::ESCAPE, true))
{
stay_open = false;
ImGui::CloseCurrentPopup();
}
return stay_open;
}).LogIfFailed(Editor::LogCat);
// New World
AddPopup(PopUp::NEW_WORLD, "New World Name", [](Panel *p)
// New World
AddPopup(PopUp::NEW_WORLD, "New World Name", [](Panel *p)
{
bool stay_open = true;
AssetBrowser* ab = (AssetBrowser*)p;
char name_buf[64] = "New World";
ImGui::TextUnformatted("World Name: ");
ImGui::SameLine();
if (ImGui::InputText("##World Name", name_buf, 64, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue))
{
bool stay_open = true;
AssetBrowser* ab = (AssetBrowser*)p;
char name_buf[64] = "New World";
ImGui::TextUnformatted("World Name: ");
ImGui::SameLine();
if (ImGui::InputText("##World Name", name_buf, 64, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue))
{
auto assets_dir = ab->mpEditor->GetProject()->MakeRelativeToAssets(ab->mSelectedDir);
EditorAsset* pAsset = new editor::World(assets_dir / name_buf);
LUUID id;
ContentManager::GetInstance().AddGeneratedAsset(pAsset, id).LogIfFailed(Editor::LogCat);
stay_open = false;
ImGui::CloseCurrentPopup();
}
auto assets_dir = ab->mpEditor->GetProject()->MakeRelativeToAssets(ab->mSelectedDir);
EditorAsset* pAsset = new editor::World(assets_dir / name_buf);
LUUID id;
ContentManager::GetInstance().AddGeneratedAsset(pAsset, id).LogIfFailed(Editor::LogCat);
stay_open = false;
ImGui::CloseCurrentPopup();
}
if (Core::Input().IsKeyDown(KeyCode::ESCAPE, true))
{
stay_open = false;
ImGui::CloseCurrentPopup();
}
return stay_open;
}).LogIfFailed(Editor::LogCat);
if (Core::Input().IsKeyDown(KeyCode::ESCAPE, true))
{
stay_open = false;
ImGui::CloseCurrentPopup();
}
return stay_open;
}).LogIfFailed(Editor::LogCat);
// New script asset
AddPopup(PopUp::NEW_SCRIPT, "New Script Name", [](Panel *p)
// New script asset
AddPopup(PopUp::NEW_SCRIPT, "New Script Name", [](Panel *p)
{
bool stay_open = true;
AssetBrowser* ab = (AssetBrowser*)p;
char name_buf[64] = "New Script";
ImGui::TextUnformatted("Script Name: ");
ImGui::SameLine();
if (ImGui::InputText("##Script Name", name_buf, 64, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue))
{
bool stay_open = true;
AssetBrowser* ab = (AssetBrowser*)p;
char name_buf[64] = "New Script";
ImGui::TextUnformatted("Script Name: ");
ImGui::SameLine();
if (ImGui::InputText("##Script Name", name_buf, 64, ImGuiInputTextFlags_AutoSelectAll | ImGuiInputTextFlags_EnterReturnsTrue))
auto assets_dir = ab->mpEditor->GetProject()->MakeRelativeToAssets(ab->mSelectedDir);
std::string sname_buf = name_buf;
if (sname_buf.find(' ')!= std::string::npos)
{
// This does not show up
ImGui::BeginTooltip();
ImGui::TextColored(ImVec4(1.0f, 0.0f, 0.0f, 1.0f), "Script names can not contain spaces!");
ImGui::EndTooltip();
}
else
{
auto assets_dir = ab->mpEditor->GetProject()->MakeRelativeToAssets(ab->mSelectedDir);
std::string sname_buf = name_buf;
sname_buf.append(".wren");
std::filesystem::path location = assets_dir / sname_buf;
EditorAsset* pAsset = new editor::Script(location, ab->mpEditor->GetProject()->GetAssetDirectory());
@ -413,14 +455,21 @@ namespace editor
stay_open = false;
ImGui::CloseCurrentPopup();
}
}
ImGui::SameLine();
if (ImGui::Button("X"))
{
stay_open = false;
ImGui::CloseCurrentPopup();
}
if (Core::Input().IsKeyDown(KeyCode::ESCAPE, true))
{
stay_open = false;
ImGui::CloseCurrentPopup();
}
return stay_open;
}).LogIfFailed(Editor::LogCat);
if (Core::Input().IsKeyDown(KeyCode::ESCAPE, true))
{
stay_open = false;
ImGui::CloseCurrentPopup();
}
return stay_open;
}).LogIfFailed(Editor::LogCat);
}

@ -36,6 +36,7 @@ namespace editor
std::filesystem::path mSelectedDir;
Editor* mpEditor;
bool mSyncTree;
EditorAsset* mpHoveredAsset;
private:
void DefinePopups();
@ -45,7 +46,10 @@ namespace editor
void DoContentArea(ImVec2 wind_size);
// Context menus
bool mbMenusOpen;
void DoContentContextMenu();
void DoHoveredContextMenu();
void DoEmptySpaceContextMenu();
// General Helpers
void HandleAssetDrop(std::filesystem::path dir);
@ -59,6 +63,7 @@ namespace editor
NEW_WORLD,
NEW_SCRIPT,
IMPORT_IMAGE,
TRASH_ASSET,
};
};

@ -15,7 +15,7 @@ namespace lunarium { namespace editor
{
EditorConsole::EditorConsole()
: Console("Console", PanelDockZone::DDZ_BOTTOM, true, (ImGuiWindowFlags)ImGuiWindowFlags_NoCollapse),
mGraphicsDebug(false), mInfoVerbose(false)
mGraphicsDebug(false), mInfoVerbose(false), mInfoDebug(false)
{
}
@ -62,6 +62,13 @@ namespace lunarium { namespace editor
ImGui::SameLine();
if (ImGuiExt::CheckBoxLeft("Info Debug", &mInfoDebug))
{
SetVerboseFlag(mInfoDebug);
}
ImGui::SameLine();
if (ImGui::Button("Clear"))
{
ClearMessageHistory();

@ -26,6 +26,7 @@ namespace lunarium { namespace editor
void DoToolBar();
bool mGraphicsDebug;
bool mInfoVerbose;
bool mInfoDebug;
};
}}

@ -16,6 +16,7 @@
#include <world/components.h>
#include <editor/contents/editor_asset.h>
#include <editor/component_guis.h>
#include <utils/helpers.h>
/////////////////////////////////////////////////////////////////////
// MACROS MACROS
@ -161,6 +162,22 @@ namespace lunarium { namespace editor
{
LUUID id = mpSelectedEntity->GetUUID();
ImGui::Text("UUID: %llu", (u64)id);
if (ImGui::BeginPopupContextWindow())
{
if (ImGui::Button("Copy UUID"))
{
ImGui::SetClipboardText(std::to_string(id).c_str());
ImGui::CloseCurrentPopup();
}
if (ImGui::IsKeyDown(ImGuiKey_Escape))
{
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
char buffer[256] = { 0 };
strcpy(buffer, mpSelectedEntity->GetName().c_str());
ImGui::Text("Name:");

@ -41,6 +41,10 @@ namespace lunarium
// Register Methods
sman.RegisterForeignMethod({"CoreAPI", "Core", true, "IsKeyDown(_)", (ForeignMethod)&CoreAPI::IsKeyDown});
sman.RegisterForeignMethod({"CoreAPI", "Core", true, "LogInfo(_)", (ForeignMethod)&CoreAPI::LogInfo});
sman.RegisterForeignMethod({"CoreAPI", "Core", true, "LogWarning(_)", (ForeignMethod)&CoreAPI::LogWarning});
sman.RegisterForeignMethod({"CoreAPI", "Core", true, "LogError(_)", (ForeignMethod)&CoreAPI::LogError});
sman.RegisterForeignMethod({"CoreAPI", "Core", true, "LogDebug(_)", (ForeignMethod)&CoreAPI::LogDebug});
// Generate Code
std::string keys_script = GenerateWrenKeyCodes();
@ -89,18 +93,18 @@ namespace lunarium
Core::MainWindow().Resize(w, h);
}
void CoreAPI::Log(int level, const char* msg)
{
switch (level)
{
case LogLevel::FATAL_ERROR: { Logger::Fatal(mpInstance->mCat, msg); break; }
case LogLevel::ERROR: { Logger::Error(mpInstance->mCat, msg); break; }
case LogLevel::WARNING: { Logger::Warn(mpInstance->mCat, msg); break; }
case LogLevel::INFO: { Logger::Info(mpInstance->mCat, msg); break; }
case LogLevel::DEBUG: { Logger::Debug(mpInstance->mCat, msg); break; }
default: { Logger::Trace(mpInstance->mCat, msg); break; }
}
}
// void CoreAPI::Log(int level, const char* msg)
// {
// switch (level)
// {
// case LogLevel::FATAL_ERROR: { Logger::Fatal(mpInstance->mCat, msg); break; }
// case LogLevel::ERROR: { Logger::Error(mpInstance->mCat, msg); break; }
// case LogLevel::WARNING: { Logger::Warn(mpInstance->mCat, msg); break; }
// case LogLevel::INFO: { Logger::Info(mpInstance->mCat, msg); break; }
// case LogLevel::DEBUG: { Logger::Debug(mpInstance->mCat, msg); break; }
// default: { Logger::Trace(mpInstance->mCat, msg); break; }
// }
// }
void CoreAPI::IsKeyDown(WrenVM* vm)
{
@ -108,4 +112,29 @@ namespace lunarium
bool result = Core::Input().IsKeyDown((KeyCode)key_code, true);
wrenSetSlotBool(vm, 0, result);
}
void CoreAPI::LogInfo(WrenVM* vm)
{
std::string msg = wrenGetSlotString(vm, 1);
Logger::Info(mpInstance->mCat, msg.c_str());
}
void CoreAPI::LogWarning(WrenVM* vm)
{
std::string msg = wrenGetSlotString(vm, 1);
Logger::Warn(mpInstance->mCat, msg.c_str());
}
void CoreAPI::LogError(WrenVM* vm)
{
std::string msg = wrenGetSlotString(vm, 1);
Logger::Error(mpInstance->mCat, msg.c_str());
}
void CoreAPI::LogDebug(WrenVM* vm)
{
std::string msg = wrenGetSlotString(vm, 1);
Logger::Debug(mpInstance->mCat, msg.c_str());
}
}

@ -47,7 +47,10 @@ namespace lunarium
public: // API
static void SetWindowSize(int w, int h);
static void Log(int level, const char* msg);
static void LogInfo(WrenVM* vm);
static void LogWarning(WrenVM* vm);
static void LogError(WrenVM* vm);
static void LogDebug(WrenVM* vm);
static void IsKeyDown(WrenVM* vm);

@ -31,4 +31,16 @@ foreign class BlockOutComponent {
// Returns the size as a list: [width, height]
foreign GetSize()
foreign SetSize(w, h)
}
}
// foreign class RigidBodyComponent {
// construct new(entity_id) {}
// }
// foreign class CollisionComponent {
// construct new(entity_id) {}
// }

@ -10,4 +10,8 @@ import "KeyCodes" for KeyCodes
class Core {
foreign static IsKeyDown(key)
foreign static LogInfo(msg)
foreign static LogWarning(msg)
foreign static LogError(msg)
foreign static LogDebug(msg)
}

@ -7,7 +7,7 @@
******************************************************************************/
import "Components" for VelocityComponent, BlockOutComponent
import "CoreAPI" for CoreAPI
import "CoreAPI" for Core
// Manages all of the EntityBehaviors
class WorldInterface {
@ -25,6 +25,8 @@ class WorldInterface {
__ScriptObjects[entity_id][script_name] = script_class.new(entity_id)
//System.print("Registered script: %(script_name) to entity: %(entity_id)")
var msg = "Registered script: %(script_name) to entity: %(entity_id)"
Core.LogDebug(msg)
}
/////////////////////////////////////////////////////////////////////

@ -21,6 +21,7 @@ namespace lunarium
WrenState WorldAPI::mScriptState;
World* WorldAPI::mpWorld = nullptr;
WorldAPI::ScriptEventHandles WorldAPI::mEventHandles;
std::vector<std::string> WorldAPI::mAlreadyRanScripts;
OpRes WorldAPI::Initialize(World* pWorld)
{
@ -65,6 +66,7 @@ namespace lunarium
void WorldAPI::Shutdown()
{
mAlreadyRanScripts.clear();
mpWorld = nullptr;
}
@ -76,26 +78,22 @@ namespace lunarium
void WorldAPI::RegisterScript(LUUID entity, WrenScript& script)
{
mScriptState.RunScript(&script);
// // Get Handle to script class type to use as second paraneter to RegisterScript
// WrenHandle* pScriptClass = mScriptState.GetWrenClassHandle("WorldInterface", script.GetScriptName());
// std::vector<WrenParameter> params;
// WrenParameter p;
// p.Type = WrenParamType::WPT_STR;
// p.As.String = std::to_string(entity).c_str();
// params.push_back(p);
// p.As.String = script.GetScriptName().c_str();
// params.push_back(p);
// p.Type = WrenParamType::WPT_HANDLE;
// p.As.Handle = pScriptClass;
// params.push_back(p);
// mScriptState.CallWrenMethod(mEventHandles.mWIRegisterScriptMethod, mEventHandles.mWIHandle, params, "WorldInterface.entity_id, script_name, script_class");
// Need to check if script was already run.
// In that case skip running and just make a new instance for this entity
// This allows multiple entities to have their own instances of the same script
std::string script_class = script.GetScriptName();
std::vector<WrenState::Import> modules_to_load;
if (!ScriptAlreadyRan(script.GetScriptName()))
{
mScriptState.RunScript(&script);
mAlreadyRanScripts.push_back(script.GetScriptName());
modules_to_load.push_back({"WorldInterface", "WorldInterface"});
modules_to_load.push_back({ script_class, script_class });
}
std::string module_name = "Register_" + script_class;
std::string code = "WorldInterface.RegisterScript(\"" + std::to_string(entity) + "\", \"" + script_class + "\", " + script_class + ")";
mScriptState.RunSnippet(module_name, {{"WorldInterface", "WorldInterface"}, { script_class, script_class }}, code);
mScriptState.RunSnippet(module_name, modules_to_load, code);
}
void WorldAPI::InvokeEvent(Event e, ...)
@ -118,6 +116,18 @@ namespace lunarium
}
}
bool WorldAPI::ScriptAlreadyRan(std::string name)
{
for (auto iter : mAlreadyRanScripts)
{
if (iter == name)
return true;
}
return false;
}
/////////////////////////////////////////////////////////////////////
// SCRIPT API
/////////////////////////////////////////////////////////////////////

@ -14,6 +14,8 @@
#include <scripting/wren_script.h>
#include <utils/op_res.h>
#include <vector>
namespace lunarium
{
class WorldAPI
@ -53,11 +55,14 @@ namespace lunarium
// Foreign classes
private: // HELPERS
static bool ScriptAlreadyRan(std::string name);
private:
static WrenState mScriptState;
static World* mpWorld;
static ScriptEventHandles mEventHandles;
static std::vector<std::string> mAlreadyRanScripts;
};
}

@ -42,6 +42,21 @@ namespace lunarium
return glsl_version;
}
void System::CopyToClipboard(std::string data)
{
#ifdef WIN32
HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, data.size() + 1);
memcpy(GlobalLock(hMem), data.c_str(), data.size() + 1);
GlobalUnlock(hMem);
OpenClipboard(0);
EmptyClipboard();
SetClipboardData(CF_TEXT, hMem);
CloseClipboard();
#else
#endif // WIN32
}
////////////////////////////////////////////////////////////
// FILE SYSTEM FUNCTIONS
////////////////////////////////////////////////////////////

@ -23,6 +23,7 @@ namespace lunarium
public:
static Sizei GetScreenResolution();
static std::string GetGLSLVersionString();
static void CopyToClipboard(std::string data);
};
class FileSystem

@ -14,19 +14,6 @@ namespace lunarium
std::mt19937_64 UUID::mt64(time(nullptr));
LUUID UUID::GetNewID()
{
// This is kind of hacky. Should probably try to remove the need for null ids.
// LUUID id = 0;
// while (0 == id)
// {
// id = mt64();
// }
// return id;
return mt64();
}
// LUUID UUID::GetNullID()
// {
// return 0;
// }
}

@ -479,6 +479,29 @@ namespace lunarium
Deserialize(state.State).LogIfFailed(LogCategory::GAME_SYSTEM, "Failed to deserialize the world state");
}
/////////////////////////////////////////////////////////////////////
// PHYSICS CALLBACKS
/////////////////////////////////////////////////////////////////////
void World::BeginContact(b2Contact* contact)
{
}
void World::EndContact(b2Contact* contact)
{
}
void World::PreSolve(b2Contact* contact, const b2Manifold* oldManifold)
{
}
void World::PostSolve(b2Contact* contact, const b2ContactImpulse* impulse)
{
}
/////////////////////////////////////////////////////////////////////
// SERIALIZING
/////////////////////////////////////////////////////////////////////

@ -52,7 +52,7 @@ namespace lunarium
int Index;
};
class World : public JSONSerializable
class World : public JSONSerializable, b2ContactListener
{
public:
struct Region
@ -105,6 +105,13 @@ namespace lunarium
float GetPhysicsScaleFactor() const;
void SetPhysicsScaleFactor(float factor);
// Physics Callbacks
void BeginContact(b2Contact* contact);
void EndContact(b2Contact* contact);
void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);
// Serializing
[[nodiscard]] virtual OpRes Serialize(nlohmann::ordered_json& node);
[[nodiscard]] virtual OpRes Deserialize(nlohmann::ordered_json& node);
@ -112,6 +119,7 @@ namespace lunarium
[[nodiscard]] virtual nlohmann::ordered_json AsJSON();
private:
LUUID mUUID;
std::string mName;

Loading…
Cancel
Save