Scripting system compiling

This commit is contained in:
Chewico 2026-02-03 00:49:34 +01:00
parent baba8f2e09
commit 84fa7a450b
83 changed files with 2003 additions and 1688 deletions

View File

@ -1,5 +1,4 @@
#pragma once #pragma once
#include "DeerCore/Tools/Memory.h"
#include "spdlog/sinks/stdout_color_sinks.h" #include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/spdlog.h" #include "spdlog/spdlog.h"
@ -10,32 +9,17 @@ namespace spdlog {
// Simple file to define logs functions optimized depending on the compilation // Simple file to define logs functions optimized depending on the compilation
namespace Deer { namespace Deer {
class Log { namespace Log {
public: void init();
static void init(); void shutdown();
static void shutdown();
static void coreTrace(const char* msg); void coreTrace(const char* msg);
static inline Ref<spdlog::logger>& getCoreLogger() { spdlog::logger* getCoreLogger();
return coreLogger; spdlog::logger* getClientLogger();
} spdlog::logger* getScriptLogger();
static inline Ref<spdlog::logger>& getClientLogger() { spdlog::logger* getEditorEngineLogger();
return clientLogger; }; // namespace Log
}
static inline Ref<spdlog::logger>& getScriptLogger() {
return scriptLogger;
}
static inline Ref<spdlog::logger>& getEditorEngineLogger() {
return EditorEngineLogger;
}
private:
static Ref<spdlog::logger> coreLogger;
static Ref<spdlog::logger> clientLogger;
static Ref<spdlog::logger> scriptLogger;
static Ref<spdlog::logger> EditorEngineLogger;
};
} // namespace Deer } // namespace Deer
#define DEER_CORE_TRACE(...) Deer::Log::getCoreLogger()->trace(__VA_ARGS__) #define DEER_CORE_TRACE(...) Deer::Log::getCoreLogger()->trace(__VA_ARGS__)

View File

@ -91,6 +91,13 @@ namespace Deer {
return resource; return resource;
} }
static Resource<T> getResource(const std::string& storageId) {
if (resourceCache.contains(storageId))
return resourceCache[storageId];
return Resource<T>();
}
static Resource<T> loadResourceFromData(const typename ResourceBuilder<T>::BaseDataType& resourceData, const std::string& storageId) { static Resource<T> loadResourceFromData(const typename ResourceBuilder<T>::BaseDataType& resourceData, const std::string& storageId) {
if (resourceCache.contains(storageId)) if (resourceCache.contains(storageId))
return resourceCache[storageId]; return resourceCache[storageId];

View File

@ -1,41 +0,0 @@
#pragma once
#include "DeerCore/Tools/Memory.h"
#include "DeerCore/Tools/TypeDefs.h"
#include "angelscript.h"
#include <string>
#include <vector>
class asIScriptEngine;
namespace Deer {
class ScriptEnvironment;
namespace ScriptSystem {
void init();
void shutdown();
asIScriptEngine* getScriptEngine();
Scope<ScriptEnvironment> createScriptEnvironment(const char* baseDataType);
} // namespace ScriptSystem
class EnvironmentSystems {
};
class ScriptInstance {
}
class EnvironmentInstances {
};
class ScriptEnvironment {
public:
private:
asIScriptContext* context;
std::string baseTypeName;
asITypeInfo* baseType;
ScriptEnvironment(asITypeInfo*);
friend Scope<ScriptEnvironment> Deer::ScriptSystem::createScriptEnvironment(const char* baseDataType);
};
} // namespace Deer

View File

@ -0,0 +1,114 @@
#pragma once
#include "DeerCore/Tools/Memory.h"
#include "DeerCore/Tools/Path.h"
#include "DeerCore/Tools/TypeDefs.h"
#include <string>
#include <vector>
class asIScriptEngine;
class asIScriptObject;
class asIScriptFunction;
class asITypeInfo;
class asIScriptContext;
class asIScriptModule;
namespace Deer {
class ScriptEnvironment;
class ScriptSystem;
class ScriptEnvironmentContextData;
class World;
namespace Scripting {
// The event type is necessary to know wich parameters to put
enum class EventType {
void_event // Defines a event with void as return and no parameter
};
struct SystemEvent {
EventType eventType;
std::string eventName;
SystemEvent(const std::string _name, EventType _type) : eventName(_name), eventType(_type) {}
};
struct SystemDescription {
std::string baseTypeName;
std::string moduleName;
std::vector<SystemEvent> events;
SystemDescription(const std::string& _baseTypeName, const std::string& _moduleName, const std::vector<SystemEvent>& _events = {}) : baseTypeName(_baseTypeName), moduleName(_moduleName), events(_events) {}
};
// Functions called by Engine
void init();
void shutdown();
void registerInterface(const char* name);
void registerInterfaceFunction(const char* name, const char* funcName, EventType funcType);
asIScriptEngine* getScriptEngine();
void compileFiles(const Path&, const char* moduleName);
Scope<ScriptEnvironment> createScriptEnvironment(const SystemDescription& systemDescription);
} // namespace Scripting
struct ScriptObjectGroup {
public:
// returns false if the object already existed
bool createScriptObject(size_t systemIndex);
void executeOnGroup_voidEvent(size_t eventIndex);
void executeOnObject_voidEvent(size_t systemIndex, size_t eventIndex);
private:
ScriptObjectGroup(ScriptEnvironment* env);
Scope<asIScriptObject*[]> systemInstances;
ScriptEnvironment* environment;
friend ScriptSystem;
friend ScriptEnvironment;
};
class ScriptSystem {
public:
const char* getSystemName();
private:
ScriptSystem(const Scripting::SystemDescription& desc, asITypeInfo* type);
asITypeInfo* systemType;
Scope<asIScriptFunction*[]> environmentFunctions;
friend ScriptEnvironment;
friend ScriptObjectGroup;
};
// Script Environment is based of one angelscript interface, the clas analizes all the classes that derives from that
// interface and calls them systems, I extract the functions as defined from system description and then the user can tell me to create a
// system group, a system group can have each system created or not
class ScriptEnvironment {
public:
~ScriptEnvironment();
ScriptObjectGroup* createGroupWithAllSystems();
ScriptObjectGroup* createEmptyGroup();
size_t getSystemCount();
ScriptSystem* getSystemByIndex(size_t index);
void tieWorld(World* world);
private:
Scripting::SystemDescription systemDescription;
asIScriptContext* context;
asIScriptModule* module;
asITypeInfo* baseType;
std::vector<Scope<ScriptSystem>> systems;
std::vector<Scope<ScriptObjectGroup>> systemGroups;
Scope<ScriptEnvironmentContextData> environmentContext;
ScriptEnvironment(const Scripting::SystemDescription&);
friend Scope<ScriptEnvironment> Scripting::createScriptEnvironment(const Scripting::SystemDescription& systemDescription);
friend ScriptObjectGroup;
};
} // namespace Deer

View File

@ -14,11 +14,6 @@ namespace Deer {
WorldHandle(uint32_t _worldId, uint32_t _generation) : worldId(_worldId), generation(_generation) {} WorldHandle(uint32_t _worldId, uint32_t _generation) : worldId(_worldId), generation(_generation) {}
}; };
struct EntityHandle {
uint32_t entityId = 0;
WorldHandle worldId;
};
WorldHandle createWorld(const WorldSettings&); WorldHandle createWorld(const WorldSettings&);
World& getWorld(WorldHandle); World& getWorld(WorldHandle);

View File

@ -3,23 +3,26 @@
#include "DeerRender/Events/KeyEvent.h" #include "DeerRender/Events/KeyEvent.h"
#include "DeerRender/Events/MouseEvent.h" #include "DeerRender/Events/MouseEvent.h"
struct ImFont;
namespace Deer { namespace Deer {
class Window; class Window;
class ImGuiLayer { namespace ImGuiLayer {
public: void init(Window& window);
~ImGuiLayer() = default; void shutdown();
void onAttach(Window& window);
void onDetach();
void begin(); void begin();
void end(); void end();
void onEvent(Event& event); void onEvent(Event& event);
private: void setTextFont(ImFont*);
bool onMouseButtonPressedEvent(MouseButtonPressedEvent& e); void setTitleFont(ImFont*);
ImFont* getTextFont();
ImFont* getTitleFont();
bool onMouseButtonPressedEvent(MouseButtonPressedEvent& e);
bool onMouseButtonReleasedEvent(MouseButtonReleasedEvent& e); bool onMouseButtonReleasedEvent(MouseButtonReleasedEvent& e);
bool onMouseMovedEvent(MouseMovedEvent& e); bool onMouseMovedEvent(MouseMovedEvent& e);
bool onMouseScrollEvent(MouseScrolledEvent& e); bool onMouseScrollEvent(MouseScrolledEvent& e);
@ -27,5 +30,5 @@ namespace Deer {
bool onKeyReleasedEvent(KeyReleasedEvent& e); bool onKeyReleasedEvent(KeyReleasedEvent& e);
bool onKeyTypedEvent(KeyTypedEvent& e); bool onKeyTypedEvent(KeyTypedEvent& e);
bool onWindowResizeEvent(WindowResizeEvent& e); bool onWindowResizeEvent(WindowResizeEvent& e);
}; }; // namespace ImGuiLayer
} // namespace Deer } // namespace Deer

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "DeerCore/Log.h" #include "DeerCore/Log.h"
#include "DeerRender/Resource.h"
#include <initializer_list> #include <initializer_list>
#include <vector> #include <vector>

View File

@ -1,7 +0,0 @@
#pragma once
#include "DeerCore/ScriptSystem.h"
namespace Deer {
namespace ScriptSystem {
}
} // namespace Deer

View File

@ -0,0 +1,7 @@
#pragma once
#include "DeerCore/Scripting.h"
namespace Deer {
namespace Scripting {
}
} // namespace Deer

View File

@ -1,10 +1,12 @@
#include "DeerCore/Log.h" #include "DeerCore/Log.h"
namespace Deer { namespace Deer {
std::shared_ptr<spdlog::logger> Log::coreLogger; namespace Log {
std::shared_ptr<spdlog::logger> Log::clientLogger; std::shared_ptr<spdlog::logger> coreLogger;
std::shared_ptr<spdlog::logger> Log::scriptLogger; std::shared_ptr<spdlog::logger> clientLogger;
std::shared_ptr<spdlog::logger> Log::EditorEngineLogger; std::shared_ptr<spdlog::logger> scriptLogger;
std::shared_ptr<spdlog::logger> EditorEngineLogger;
} // namespace Log
void Log::init() { void Log::init() {
// spdlog::set_pattern("%^[%T] %n: %v%$"); // spdlog::set_pattern("%^[%T] %n: %v%$");
@ -20,6 +22,18 @@ namespace Deer {
scriptLogger->set_level(spdlog::level::level_enum::trace); scriptLogger->set_level(spdlog::level::level_enum::trace);
EditorEngineLogger->set_level(spdlog::level::level_enum::trace); EditorEngineLogger->set_level(spdlog::level::level_enum::trace);
} }
spdlog::logger* Log::getCoreLogger() {
return coreLogger.get();
}
spdlog::logger* Log::getClientLogger() {
return clientLogger.get();
}
spdlog::logger* Log::getScriptLogger() {
return scriptLogger.get();
}
spdlog::logger* Log::getEditorEngineLogger() {
return EditorEngineLogger.get();
}
void Log::shutdown() { void Log::shutdown() {
coreLogger.reset(); coreLogger.reset();

View File

@ -1,91 +0,0 @@
#pragma once
#include "DeerCore/Universe.h"
#include "DeerRender/Mesh.h"
#include "DeerRender/Shader.h"
#include "DeerRender/Texture.h"
#include "glm/glm.hpp"
#include <stdint.h>
#include <string>
class asIScriptGeneric;
namespace Deer {
namespace StudioAPI {
Universe::EntityHandle entity_getSelf(Universe::EntityHandle);
std::string entity_getName(Universe::EntityHandle);
void entity_getName(std::string, Universe::EntityHandle);
bool entity_exists(Universe::EntityHandle);
bool entity_isRoot(Universe::EntityHandle);
void entity_destroy(Universe::EntityHandle);
Universe::EntityHandle entity_createChild(Universe::EntityHandle);
void entity_setParent(Universe::EntityHandle);
Universe::EntityHandle entity_getParent(Universe::EntityHandle);
bool entity_isDescendantOf(Universe::EntityHandle);
bool entity_opEquals(Universe::EntityHandle& other, Universe::EntityHandle);
bool entity_isDescendantOf(Universe::EntityHandle parent);
bool entity_opEquals(const Universe::EntityHandle& other);
void entity_addGenericComponent(asIScriptGeneric* generic);
void entity_removeGenericComponent(asIScriptGeneric* generic);
void entity_getGenericComponent(asIScriptGeneric* generic);
void entity_hasGenericComponent(asIScriptGeneric* generic);
struct TransformComponentStruct : Universe::EntityHandle {
glm::vec3 getPosition();
glm::vec3 getScale();
glm::vec3 getRotation();
void setPosition(glm::vec3);
void setScale(glm::vec3);
void setRotation(glm::vec3);
};
struct MeshComponentStruct : Universe::EntityHandle {
bool isActive();
void setActive(bool);
bool hasMesh();
void clear();
Resource<GPUMesh> getMesh();
void setMesh(Resource<GPUMesh>);
bool assertMeshComponent(const char* funcName);
};
struct ShaderComponentStruct : Universe::EntityHandle {
bool hasShader();
void clear();
Resource<Shader> getShader();
void setShader(Resource<Shader>);
Resource<Texture> getTexture();
void setTexture(Resource<Texture>);
bool assertShaderComponent(const char* funcName);
};
struct CameraComponentStruct : Universe::EntityHandle {
float getFov();
float getAspectRation();
float getNearZ();
float getFarZ();
void setFov(float);
void setAspectRation(float);
void setNearZ(float);
void setFarZ(float);
bool assertCameraComponent(const char* funcName);
};
Universe::EntityHandle getRoot();
void constructEntityStruct(int id, void* memory);
void copyEntityStruct(int id, void* memory);
} // namespace StudioAPI
} // namespace Deer

View File

@ -1,33 +0,0 @@
#pragma once
#include "DeerCore/Log.h"
#include "DeerCore/ScriptSystem.h"
#include "angelscript.h"
namespace Deer {
namespace ScriptSystem {
extern asIScriptEngine* scriptEngine;
}
Scope<ScriptEnvironment> ScriptSystem::createScriptEnvironment(const char* baseTypeName) {
asITypeInfo* baseType = scriptEngine->GetTypeInfoByDecl(baseTypeName);
if (!baseType) {
DEER_CORE_ERROR("Base type {} not found", baseTypeName);
return nullptr;
}
if (baseType->GetModule()) {
DEER_CORE_ERROR("Base type {} must be a engine type", baseTypeName);
return nullptr;
}
Scope<ScriptEnvironment> environment = MakeScope<ScriptEnvironment>(baseType);
return environment;
}
ScriptEnvironment::ScriptEnvironment(asITypeInfo* _baseType)
: baseType(_baseType), baseTypeName(_baseType->GetName()) {
ScriptSystem::scriptEngine->GetTypedefCount();
}
} // namespace Deer

View File

@ -1,8 +1,8 @@
#include "DeerCore/ScriptSystem/Helpers.h" #include "DeerCore/Scripting/Helpers.h"
#include "angelscript.h" #include "angelscript.h"
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
const char* getAngelScriptReturnCodeString(int code) { const char* getAngelScriptReturnCodeString(int code) {
switch (code) { switch (code) {
case asSUCCESS: case asSUCCESS:
@ -60,5 +60,5 @@ namespace Deer {
return false; return false;
} }
} // namespace ScriptSystem } // namespace Scripting
} // namespace Deer } // namespace Deer

View File

@ -3,10 +3,10 @@
#include "angelscript.h" #include "angelscript.h"
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
const char* getAngelScriptReturnCodeString(int code); const char* getAngelScriptReturnCodeString(int code);
bool ImplementsInterface(asITypeInfo* type, asITypeInfo* iface); bool ImplementsInterface(asITypeInfo* type, asITypeInfo* iface);
} // namespace ScriptSystem } // namespace Scripting
} // namespace Deer } // namespace Deer
#define REGISTER_GLOBAL_FUNC(scriptEngine, funcdef, func) \ #define REGISTER_GLOBAL_FUNC(scriptEngine, funcdef, func) \
@ -24,6 +24,11 @@ namespace Deer {
clasdef, funcdef, \ clasdef, funcdef, \
asFUNCTION(func), asCALL_CDECL_OBJLAST)) asFUNCTION(func), asCALL_CDECL_OBJLAST))
#define REGISTER_GENERIC_OBJECT_METHOD(scriptEngine, clasdef, funcdef, func) \
AS_CHECK(scriptEngine->RegisterObjectMethod( \
clasdef, funcdef, \
asFUNCTION(func), asCALL_GENERIC))
#define REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, clasdef, funcdef, func) \ #define REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, clasdef, funcdef, func) \
AS_CHECK(scriptEngine->RegisterObjectBehaviour( \ AS_CHECK(scriptEngine->RegisterObjectBehaviour( \
clasdef, asBEHAVE_CONSTRUCT, funcdef, \ clasdef, asBEHAVE_CONSTRUCT, funcdef, \
@ -33,25 +38,25 @@ namespace Deer {
clasdef, asBEHAVE_DESTRUCT, funcdef, \ clasdef, asBEHAVE_DESTRUCT, funcdef, \
asFUNCTION(func), asCALL_CDECL_OBJLAST)) asFUNCTION(func), asCALL_CDECL_OBJLAST))
#define AS_CHECK(f) \ #define AS_CHECK(f) \
{ \ { \
int __r = f; \ int __r = f; \
if (__r < 0) { \ if (__r < 0) { \
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::ScriptSystem::getAngelScriptReturnCodeString(__r)); \ DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::Scripting::getAngelScriptReturnCodeString(__r)); \
} \ } \
} }
#define AS_CHECK_ADDITIONAL_INFO(f, i) \ #define AS_CHECK_ADDITIONAL_INFO(f, i) \
{ \ { \
int __r = f; \ int __r = f; \
if (__r < 0) { \ if (__r < 0) { \
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2} \n {3}", __FILE__, __LINE__, Deer::ScriptSystem::getAngelScriptReturnCodeString(__r), i); \ DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2} \n {3}", __FILE__, __LINE__, Deer::Scripting::getAngelScriptReturnCodeString(__r), i); \
} \ } \
} }
#define AS_RET_CHECK(f) \ #define AS_RET_CHECK(f) \
{ \ { \
int __r = f; \ int __r = f; \
if (__r < 0) { \ if (__r < 0) { \
DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::ScriptSystem::getAngelScriptReturnCodeString(__r)); \ DEER_EDITOR_ENGINE_ERROR("Error at line: {0}:{1} -> {2}", __FILE__, __LINE__, Deer::Scripting::getAngelScriptReturnCodeString(__r)); \
return; \ return; \
} \ } \
} }

View File

@ -1,4 +1,4 @@
#include "DeerCore/ScriptSystem/InternalAPI/Engine.h" #include "DeerCore/Scripting/InternalAPI/Engine.h"
#include "DeerRender/Tools/Path.h" #include "DeerRender/Tools/Path.h"
#include "angelscript.h" #include "angelscript.h"
@ -8,7 +8,7 @@
#include <string> #include <string>
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
extern asIScriptEngine* scriptEngine; extern asIScriptEngine* scriptEngine;
std::string getParentPath(std::string& path) { std::string getParentPath(std::string& path) {
@ -37,5 +37,5 @@ namespace Deer {
return array; return array;
} }
} // namespace ScriptSystem } // namespace Scripting
} // namespace Deer } // namespace Deer

View File

@ -4,10 +4,10 @@
class CScriptArray; class CScriptArray;
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
CScriptArray* dividePath_angelscript(std::string&); CScriptArray* dividePath_angelscript(std::string&);
std::string getParentPath(std::string&); std::string getParentPath(std::string&);
std::string getParentPathName(std::string&); std::string getParentPathName(std::string&);
std::string getPathName(std::string&); std::string getPathName(std::string&);
} // namespace ScriptSystem } // namespace Scripting
} // namespace Deer } // namespace Deer

View File

@ -0,0 +1,228 @@
#include "DeerCore/Scripting/InternalAPI/Entity.h"
#include "DeerCore/Scripting/ScriptEnvironmentContextData.h"
#include "DeerCore/EntityEnviroment.h"
#include "angelscript.h"
#ifdef DEER_RENDER
#include "DeerRender/Mesh.h"
#include "DeerRender/Shader.h"
#include "DeerRender/Texture.h"
#include "DeerRender/World.h"
#endif
namespace Deer {
Entity& Scripting::getContextEntity(EntityHandle handle) {
asIScriptContext* context = asGetActiveContext();
ScriptEnvironmentContextData* environmentData = (ScriptEnvironmentContextData*)context->GetUserData();
if (handle.environmentId == 0) {
return environmentData->world->entityEnvironment->getEntity(handle.entityId);
}
// Implement entity reference of other environments
return environmentData->world->entityEnvironment->getEntity(handle.entityId);
}
EntityEnvironment& Scripting::getContextEntityEnvironment(EntityHandle handle) {
asIScriptContext* context = asGetActiveContext();
ScriptEnvironmentContextData* environmentData = (ScriptEnvironmentContextData*)context->GetUserData();
if (handle.environmentId == 0) {
return *environmentData->world->entityEnvironment.get();
}
// Implement entity reference of other environments
return *environmentData->world->entityEnvironment.get();
}
template <typename T>
T& Scripting::getContextEntityComponent(EntityHandle handle) {
asIScriptContext* context = asGetActiveContext();
ScriptEnvironmentContextData* environmentData = (ScriptEnvironmentContextData*)context->GetUserData();
if (handle.environmentId == 0) {
return environmentData->world->entityEnvironment->getEntity(handle.entityId).getComponent<T>();
}
// Implement entity reference of other environments
return environmentData->world->entityEnvironment->getEntity(handle.entityId).getComponent<T>();
}
EntityHandle Scripting::entity_getSelf(EntityHandle& handle) {
return handle;
}
std::string Scripting::entity_getName(EntityHandle& handle) {
return getContextEntity(handle).getComponent<TagComponent>().tag;
}
void Scripting::entity_setName(std::string& name, EntityHandle& handle) {
getContextEntity(handle).getComponent<TagComponent>().tag = name;
}
bool Scripting::entity_exists(EntityHandle& handle) {
return getContextEntityEnvironment(handle).entityExists(handle.entityId);
}
bool Scripting::entity_isRoot(EntityHandle& handle) {
return handle.entityId == 0;
}
void Scripting::entity_destroy(EntityHandle& handle) {
getContextEntity(handle).destroy();
}
EntityHandle Scripting::entity_createChild(EntityHandle& handle) {
Entity& child = getContextEntityEnvironment(handle).createEntity();
Entity& self = getContextEntity(handle);
child.setParent(self);
return EntityHandle(child.getId(), handle.environmentId);
}
void Scripting::entity_setParent(EntityHandle other_handle, EntityHandle& self_handle) {
Entity& child = getContextEntity(other_handle);
Entity& self = getContextEntity(self_handle);
self.setParent(child);
}
EntityHandle Scripting::entity_getParent(EntityHandle& handle) {
return EntityHandle(getContextEntity(handle).getParentId(), handle.environmentId);
}
bool Scripting::entity_isDescendantOf(EntityHandle other_handle, EntityHandle& self_handle) {
Entity& child = getContextEntity(other_handle);
Entity& self = getContextEntity(self_handle);
return self.isDescendantOf(child);
}
bool Scripting::entity_opEquals(EntityHandle& other, EntityHandle& self_handle) {
return other.entityId == self_handle.entityId and other.environmentId == self_handle.environmentId;
}
void Scripting::entity_addGenericComponent(asIScriptGeneric* generic) {
asITypeInfo* componentType = generic->GetFunction()->GetSubType();
std::string componentName = componentType->GetName();
EntityHandle handle = *(EntityHandle*)generic->GetObject();
Entity& self_entity = getContextEntity(handle);
EntityHandle* return_handle = (EntityHandle*)generic->GetAddressOfReturnLocation();
*return_handle = handle;
if (componentName == "TransformComponent") {
self_entity.addComponent<TransformComponent>();
#ifdef DEER_RENDER
} else if (componentName == "MeshComponent") {
self_entity.addComponent<MeshComponent>();
} else if (componentName == "ShaderComponent") {
self_entity.addComponent<ShaderComponent>();
} else if (componentName == "CameraComponent") {
self_entity.addComponent<CameraComponent>();
#endif
} else {
DEER_SCRIPT_ERROR("Type {} not suported for {}", componentType->GetName(), generic->GetFunction()->GetDeclaration());
}
}
void Scripting::entity_removeGenericComponent(asIScriptGeneric* generic) {
asITypeInfo* componentType = generic->GetFunction()->GetSubType();
std::string componentName = componentType->GetName();
EntityHandle handle = *(EntityHandle*)generic->GetObject();
Entity& self_entity = getContextEntity(handle);
if (componentName == "TransformComponent") {
self_entity.removeComponent<TransformComponent>();
#ifdef DEER_RENDER
} else if (componentName == "MeshComponent") {
self_entity.removeComponent<MeshComponent>();
} else if (componentName == "ShaderComponent") {
self_entity.removeComponent<ShaderComponent>();
} else if (componentName == "CameraComponent") {
self_entity.removeComponent<CameraComponent>();
#endif
} else {
DEER_SCRIPT_ERROR("Type {} not suported for {}", componentType->GetName(), generic->GetFunction()->GetDeclaration());
}
}
void Scripting::entity_getGenericComponent(asIScriptGeneric* generic) {
asITypeInfo* componentType = generic->GetFunction()->GetSubType();
std::string componentName = componentType->GetName();
EntityHandle handle = *(EntityHandle*)generic->GetObject();
Entity& self_entity = getContextEntity(handle);
EntityHandle* return_handle = (EntityHandle*)generic->GetAddressOfReturnLocation();
*return_handle = handle;
if (componentName == "TransformComponent") {
// Some checks
} else if (componentName == "MeshComponent") {
// Some checks
} else if (componentName == "ShaderComponent") {
// Some checks
} else if (componentName == "CameraComponent") {
// Some checks
} else {
DEER_SCRIPT_ERROR("Type {} not suported for {}", componentType->GetName(), generic->GetFunction()->GetDeclaration());
}
}
void Scripting::entity_hasGenericComponent(asIScriptGeneric* generic) {
asITypeInfo* componentType = generic->GetFunction()->GetSubType();
std::string componentName = componentType->GetName();
EntityHandle handle = *(EntityHandle*)generic->GetObject();
Entity& self_entity = getContextEntity(handle);
if (componentName == "TransformComponent") {
generic->SetReturnByte(self_entity.hasComponent<TransformComponent>());
#ifdef DEER_RENDER
} else if (componentName == "MeshComponent") {
generic->SetReturnByte(self_entity.hasComponent<MeshComponent>());
} else if (componentName == "ShaderComponent") {
generic->SetReturnByte(self_entity.hasComponent<ShaderComponent>());
} else if (componentName == "CameraComponent") {
generic->SetReturnByte(self_entity.hasComponent<CameraComponent>());
#endif
} else {
DEER_SCRIPT_ERROR("Type {} not suported for {}", componentType->GetName(), generic->GetFunction()->GetDeclaration());
}
}
// SPECIFIC TRANSFORM SECTION
glm::vec3 Scripting::transform_getPosition(EntityHandle& handle) {
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
return transformComponent.position;
}
glm::vec3 Scripting::transform_getScale(EntityHandle& handle) {
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
return transformComponent.scale;
}
glm::vec3 Scripting::transform_getRotation(EntityHandle& handle) {
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
return transformComponent.getEulerAngles();
}
void Scripting::transform_setPosition(glm::vec3 position, EntityHandle& handle) {
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
transformComponent.position = position;
}
void Scripting::transform_setScale(glm::vec3 scale, EntityHandle& handle) {
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
transformComponent.scale = scale;
}
void Scripting::transform_setRotation(glm::vec3 rotation, EntityHandle& handle) {
TransformComponent& transformComponent = getContextEntityComponent<TransformComponent>(handle);
transformComponent.setEulerAngles(rotation);
}
void Scripting::constructEntityStruct(void* memory) {
new (memory) EntityHandle();
}
} // namespace Deer

View File

@ -0,0 +1,56 @@
#pragma once
#include "glm/glm.hpp"
#include <stdint.h>
#include <string>
class asIScriptGeneric;
namespace Deer {
class Entity;
class EntityEnvironment;
struct EntityHandle {
uint32_t entityId = 0;
uint32_t environmentId = 0;
EntityHandle(uint32_t _id = 0, uint32_t _env = 0) : entityId(_id), environmentId(_env) {}
};
namespace Scripting {
// SPECIFIC ENTITY SECTION
Entity& getContextEntity(EntityHandle);
EntityEnvironment& getContextEntityEnvironment(EntityHandle);
template <typename T>
T& getContextEntityComponent(EntityHandle handle);
EntityHandle entity_getSelf(EntityHandle&);
std::string entity_getName(EntityHandle&);
void entity_setName(std::string&, EntityHandle&);
bool entity_exists(EntityHandle&);
bool entity_isRoot(EntityHandle&);
void entity_destroy(EntityHandle&);
EntityHandle entity_createChild(EntityHandle&);
void entity_setParent(EntityHandle, EntityHandle&);
EntityHandle entity_getParent(EntityHandle&);
bool entity_isDescendantOf(EntityHandle, EntityHandle&);
bool entity_opEquals(EntityHandle& other, EntityHandle&);
void entity_addGenericComponent(asIScriptGeneric* generic);
void entity_removeGenericComponent(asIScriptGeneric* generic);
void entity_getGenericComponent(asIScriptGeneric* generic);
void entity_hasGenericComponent(asIScriptGeneric* generic);
// SPECIFIC TRANSFORM SECTION
glm::vec3 transform_getPosition(EntityHandle&);
glm::vec3 transform_getScale(EntityHandle&);
glm::vec3 transform_getRotation(EntityHandle&);
void transform_setPosition(glm::vec3, EntityHandle&);
void transform_setScale(glm::vec3, EntityHandle&);
void transform_setRotation(glm::vec3, EntityHandle&);
void constructEntityStruct(void* memory);
} // namespace Scripting
} // namespace Deer

View File

@ -1,9 +1,9 @@
#include "DeerCore/ScriptSystem/InternalAPI/InternalFunctions.h" #include "DeerCore/Scripting/InternalAPI/InternalFunctions.h"
#include "DeerRender/Log.h" #include "DeerRender/Log.h"
#include "angelscript.h" #include "angelscript.h"
namespace Deer { namespace Deer {
void ScriptSystem::errorCallback_angelscript(const asSMessageInfo* msg, void* param) { void Scripting::errorCallback_angelscript(const asSMessageInfo* msg, void* param) {
if (msg->type == asMSGTYPE_WARNING) { if (msg->type == asMSGTYPE_WARNING) {
DEER_EDITOR_ENGINE_WARN("{0}:{1}:{2}) : {3}", msg->section, msg->row, msg->col, msg->message); DEER_EDITOR_ENGINE_WARN("{0}:{1}:{2}) : {3}", msg->section, msg->row, msg->col, msg->message);
} else if (msg->type == asMSGTYPE_INFORMATION) { } else if (msg->type == asMSGTYPE_INFORMATION) {
@ -15,7 +15,7 @@ namespace Deer {
} }
} }
void ScriptSystem::print(std::string& msg) { void Scripting::print(std::string& msg) {
DEER_EDITOR_ENGINE_INFO("{0}", msg.c_str()); DEER_EDITOR_ENGINE_INFO("{0}", msg.c_str());
} }
} // namespace Deer } // namespace Deer

View File

@ -1,9 +1,11 @@
#pragma once #pragma once
struct asSMessageInfo; struct asSMessageInfo;
#include <string>
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
void errorCallback_angelscript(const asSMessageInfo* msg, void* param); void errorCallback_angelscript(const asSMessageInfo* msg, void* param);
void print(std::string& msg); void print(std::string& msg);
} // namespace ScriptSystem } // namespace Scripting
} // namespace Deer } // namespace Deer

View File

@ -1,8 +1,8 @@
#include "DeerCore/ScriptSystem/InternalAPI/Math.h" #include "DeerCore/Scripting/InternalAPI/Math.h"
#include "glm/glm.hpp" #include "glm/glm.hpp"
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
void vec3_constructor_params(float x, float y, float z, void* mem) { void vec3_constructor_params(float x, float y, float z, void* mem) {
new (mem) glm::vec3(x, y, z); new (mem) glm::vec3(x, y, z);
} }
@ -62,5 +62,5 @@ namespace Deer {
void sceneCamera_Construct(WorldCamera* mem) { void sceneCamera_Construct(WorldCamera* mem) {
new (mem) WorldCamera(); new (mem) WorldCamera();
} }
} // namespace ScriptSystem } // namespace Scripting
} // namespace Deer } // namespace Deer

View File

@ -6,7 +6,7 @@
#include "DeerRender/World.h" #include "DeerRender/World.h"
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
void vec3_constructor(void*); void vec3_constructor(void*);
void vec3_constructor_params(float, float, float, void*); void vec3_constructor_params(float, float, float, void*);
@ -30,5 +30,5 @@ namespace Deer {
glm::vec3 transform_relative(glm::vec3, TransformComponent*); glm::vec3 transform_relative(glm::vec3, TransformComponent*);
void emptyDestructor(); void emptyDestructor();
} // namespace ScriptSystem } // namespace Scripting
} // namespace Deer } // namespace Deer

View File

@ -2,7 +2,7 @@
#include "DeerCore/Universe.h" #include "DeerCore/Universe.h"
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
Universe::WorldHandle getExecutingWorld(); Universe::WorldHandle getExecutingWorld();
} }
} // namespace Deer } // namespace Deer

View File

@ -0,0 +1,292 @@
#include "DeerRender/Log.h"
#include "angelscript.h"
#include <iso646.h>
#include <sstream>
#include <string>
#include <string_view>
#include "DeerRender/Tools/Path.h"
#include <angelscript.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <string_view>
namespace Deer {
namespace Scripting {
extern asIScriptEngine* scriptEngine;
static std::stringstream stream;
static std::string str;
void printFuncList(const asIScriptEngine& engine) {
for (int i = 0; i < engine.GetFuncdefCount(); ++i) {
asITypeInfo* t = engine.GetFuncdefByIndex(i);
if (!t)
continue;
asIScriptFunction* func = t->GetFuncdefSignature();
if (!func || func->GetSubType())
continue;
std::string decl = func->GetDeclaration(true, true, true);
// Detect class-scoped funcdefs by presence of "::" in the declaration
size_t scopePos = decl.find("::");
if (scopePos != std::string::npos)
continue;
stream << "funcdef " << decl << ";\n";
}
}
void printEnumList(const asIScriptEngine& engine) {
for (int i = 0; i < engine.GetEnumCount(); ++i) {
const auto e = engine.GetEnumByIndex(i);
if (!e)
continue;
std::string_view ns = e->GetNamespace();
if (!ns.empty())
stream << "namespace " << ns << " {\n";
stream << "enum " << e->GetName() << " {\n";
for (int j = 0; j < e->GetEnumValueCount(); ++j) {
int value;
stream << "\t" << e->GetEnumValueByIndex(j, &value) << " = "
<< value;
if (j < e->GetEnumValueCount() - 1)
stream << ",";
stream << "\n";
}
stream << "}\n";
if (!ns.empty())
stream << "}\n\n";
}
}
void writeParameters(asIScriptFunction* function) {
for (int n = 0; n < function->GetParamCount(); n++) {
int typeId;
asDWORD flags;
const char* name;
const char* defaultArgument;
function->GetParam(n, &typeId, &flags, &name, &defaultArgument);
if (typeId == -1) {
stream << "?";
} else {
asITypeInfo* ti = function->GetEngine()->GetTypeInfoById(typeId);
if (ti && (ti->GetFlags() & asOBJ_FUNCDEF)) {
stream << ti->GetName();
} else {
const char* typeName = function->GetEngine()->GetTypeDeclaration(typeId, false);
stream << typeName;
}
}
if (flags & asTM_INREF)
stream << " &in ";
else if (flags & asTM_OUTREF)
stream << " &out ";
else if (flags & asTM_INOUTREF)
stream << " &inout ";
if (name) {
stream << " " << name;
}
if (n != function->GetParamCount() - 1)
stream << ", ";
}
}
void printClassTypeList(const asIScriptEngine& engine) {
for (int i = 0; i < engine.GetObjectTypeCount(); ++i) {
asITypeInfo* t = engine.GetObjectTypeByIndex(i);
if (!t)
continue;
std::string_view ns = t->GetNamespace();
if (!ns.empty())
stream << "namespace " << ns << " {\n";
stream << "class " << t->GetName();
if (std::string("any") == t->GetName())
stream << " ";
if (t->GetSubTypeCount() > 0) {
stream << "<";
for (int sub = 0; sub < t->GetSubTypeCount(); ++sub) {
if (sub > 0)
stream << ", ";
const auto st = t->GetSubType(sub);
stream << st->GetName();
}
stream << ">";
}
stream << " {\n";
for (int i = 0; i < t->GetChildFuncdefCount(); ++i) {
asITypeInfo* ftype = t->GetChildFuncdef(i);
asIScriptFunction* func = ftype->GetFuncdefSignature();
std::string decl = func->GetDeclaration(false, false, true);
stream << "\tfuncdef " << decl << ";\n";
}
for (int j = 0; j < t->GetFactoryCount(); ++j) {
asIScriptFunction* f = t->GetFactoryByIndex(j);
stream << "\t" << t->GetName() << "(";
writeParameters(f);
stream << ");\n";
}
for (int j = 0; j < t->GetBehaviourCount(); ++j) {
asEBehaviours behaviours;
const auto f = t->GetBehaviourByIndex(j, &behaviours);
if (behaviours == asBEHAVE_CONSTRUCT ||
behaviours == asBEHAVE_DESTRUCT ||
behaviours == asBEHAVE_FACTORY)
stream << "\t" << f->GetDeclaration(false, false, true)
<< ";\n";
}
for (int j = 0; j < t->GetMethodCount(); ++j) {
const auto m = t->GetMethodByIndex(j);
stream << "\t";
int methodReturnId = m->GetReturnTypeId();
if (methodReturnId == -1) {
stream << "? ";
} else {
stream << t->GetEngine()->GetTypeDeclaration(methodReturnId) << " ";
}
stream << m->GetName() << "(";
writeParameters(m);
stream << ")";
// stream << "\t" << m->GetDeclaration(false, false, true);
if (m->IsProperty())
stream << " property";
stream << ";\n";
}
for (int j = 0; j < t->GetPropertyCount(); ++j) {
stream << "\t" << t->GetPropertyDeclaration(j, false) << ";\n";
}
for (int j = 0; j < t->GetChildFuncdefCount(); ++j) {
stream
<< "\tfuncdef "
<< t->GetChildFuncdef(j)->GetFuncdefSignature()->GetDeclaration(
false)
<< ";\n";
}
stream << "}\n";
if (!ns.empty())
stream << "}\n\n";
}
}
void printGlobalFunctionList(const asIScriptEngine& engine) {
for (int i = 0; i < engine.GetGlobalFunctionCount(); ++i) {
const auto f = engine.GetGlobalFunctionByIndex(i);
std::string_view ns = f->GetNamespace();
if (!ns.empty())
stream << "namespace " << ns << " { ";
int methodReturnId = f->GetReturnTypeId();
if (methodReturnId == -1) {
stream << "? ";
} else {
stream << f->GetEngine()->GetTypeDeclaration(methodReturnId) << " ";
}
stream << f->GetName() << "(";
writeParameters(f);
stream << ")";
// stream << "\t" << m->GetDeclaration(false, false, true);
if (f->IsProperty())
stream << " property";
stream << ";";
if (!ns.empty())
stream << "\t}";
stream << "\n";
}
}
void printGlobalPropertyList(const asIScriptEngine& engine) {
for (int i = 0; i < engine.GetGlobalPropertyCount(); ++i) {
const char* name;
const char* ns0;
int type;
engine.GetGlobalPropertyByIndex(i, &name, &ns0, &type, nullptr, nullptr,
nullptr, nullptr);
std::string t = engine.GetTypeDeclaration(type, true);
if (t.empty())
continue;
std::string_view ns = ns0;
if (!ns.empty())
stream << "namespace " << ns << " { ";
stream << t << " " << name << ";";
if (!ns.empty())
stream << " }";
stream << "\n";
}
}
void printGlobalTypedef(const asIScriptEngine& engine) {
for (int i = 0; i < engine.GetTypedefCount(); ++i) {
const auto type = engine.GetTypedefByIndex(i);
if (!type)
continue;
std::string_view ns = type->GetNamespace();
if (!ns.empty())
stream << "namespace " << ns << " {\n";
stream << "typedef "
<< engine.GetTypeDeclaration(type->GetTypedefTypeId()) << " "
<< type->GetName() << ";\n";
if (!ns.empty())
stream << "}\n";
}
}
void generatePredefined(const Path& root) {
stream.clear();
stream.str("");
str.clear();
stream << "// This file is autogenerated\n";
printFuncList(*scriptEngine);
printEnumList(*scriptEngine);
printClassTypeList(*scriptEngine);
printGlobalFunctionList(*scriptEngine);
printGlobalPropertyList(*scriptEngine);
printGlobalTypedef(*scriptEngine);
Path path = root / "as.predefined";
std::ofstream predefinedFile(path);
std::string info = stream.str();
predefinedFile.write(info.c_str(), info.size());
predefinedFile.close();
}
} // namespace Scripting
} // namespace Deer

View File

@ -1,5 +1,5 @@
#include "DeerCore/Log.h" #include "DeerCore/Log.h"
#include "DeerCore/ScriptSystem.h" #include "DeerCore/Scripting.h"
#include "DeerCore/Tools/Memory.h" #include "DeerCore/Tools/Memory.h"
#include "angelscript.h" #include "angelscript.h"
@ -7,12 +7,12 @@
#include <string> #include <string>
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
extern asIScriptEngine* scriptEngine; extern asIScriptEngine* scriptEngine;
} // namespace ScriptSystem } // namespace Scripting
asIScriptEngine* ScriptSystem::getScriptEngine() { asIScriptEngine* Scripting::getScriptEngine() {
return scriptEngine; return scriptEngine;
} }

View File

@ -1,36 +1,32 @@
#include "DeerCore/ScriptSystem.h" #include "DeerCore/Scripting.h"
#include "DeerCore/ScriptSystem/Helpers.h" #include "DeerCore/Scripting/Helpers.h"
#include "DeerCore/ScriptSystem/InternalAPI/Engine.h" #include "DeerCore/Scripting/InternalAPI/Engine.h"
#include "angelscript.h" #include "angelscript.h"
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
extern asIScriptEngine* scriptEngine; extern asIScriptEngine* scriptEngine;
void registerEngine(); void registerEngine();
void registerEngineFunctions(); void registerEngineFunctions();
void registerEngineStructs(); void registerEngineStructs();
} // namespace ScriptSystem } // namespace Scripting
void ScriptSystem::registerEngineFunctions() { void Scripting::registerEngineFunctions() {
REGISTER_GLOBAL_FUNC(scriptEngine, "string getParent(const string&in path)", getParentPath); REGISTER_GLOBAL_FUNC(scriptEngine, "string getParent(const string&in path)", getParentPath);
REGISTER_GLOBAL_FUNC(scriptEngine, "string getParentName(const string&in path)", getParentPathName); REGISTER_GLOBAL_FUNC(scriptEngine, "string getParentName(const string&in path)", getParentPathName);
REGISTER_GLOBAL_FUNC(scriptEngine, "string getName(const string&in path)", getPathName); REGISTER_GLOBAL_FUNC(scriptEngine, "string getName(const string&in path)", getPathName);
REGISTER_GLOBAL_FUNC(scriptEngine, "array<string>@ divide(const string&in path)", dividePath_angelscript); REGISTER_GLOBAL_FUNC(scriptEngine, "array<string>@ divide(const string&in path)", dividePath_angelscript);
} }
void ScriptSystem::registerEngineStructs() { void Scripting::registerEngineStructs() {
AS_RET_CHECK(scriptEngine->RegisterInterface("Panel"));
AS_RET_CHECK(scriptEngine->RegisterInterfaceMethod("Panel", "void render()"));
AS_RET_CHECK(scriptEngine->RegisterInterface("Service"));
AS_CHECK(scriptEngine->RegisterFuncdef("void SimpleFunction()")); AS_CHECK(scriptEngine->RegisterFuncdef("void SimpleFunction()"));
AS_CHECK(scriptEngine->RegisterFuncdef("void ReciverFunction(any@)")); AS_CHECK(scriptEngine->RegisterFuncdef("void ReciverFunction(any@)"));
AS_CHECK(scriptEngine->RegisterFuncdef("void TransferFunction(any@, any@)")); AS_CHECK(scriptEngine->RegisterFuncdef("void TransferFunction(any@, any@)"));
} }
void ScriptSystem::registerEngine() { void Scripting::registerEngine() {
registerEngineStructs(); registerEngineStructs();
scriptEngine->SetDefaultNamespace("Path"); scriptEngine->SetDefaultNamespace("Path");
registerEngineFunctions(); registerEngineFunctions();

View File

@ -0,0 +1,52 @@
#include "DeerCore/Scripting/Helpers.h"
#include "DeerCore/Scripting/InternalAPI/Entity.h"
namespace Deer {
namespace Scripting {
extern asIScriptEngine* scriptEngine;
void registerEntity();
void registerEntityFunctions();
void registerEntityStructs();
} // namespace Scripting
void Scripting::registerEntity() {
registerEntityStructs();
registerEntityFunctions();
}
void Scripting::registerEntityFunctions() {
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "string get_name() const property", entity_getName);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "void set_name(string& in) property", entity_setName);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "Entity createChild(const string& in)", entity_createChild);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "bool get_isRoot() const property", entity_isRoot);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "void destroy()", entity_destroy);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "bool get_exists() const property", entity_exists);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "Entity get_parent() property", entity_getParent);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "void set_parent(Entity) property", entity_setParent);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "bool isDescendantOf(Entity)", entity_isDescendantOf);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Entity", "bool opEquals(const Entity &in) const", entity_opEquals);
REGISTER_GENERIC_OBJECT_METHOD(scriptEngine, "Entity", "T getComponent<T>()", entity_getGenericComponent);
REGISTER_GENERIC_OBJECT_METHOD(scriptEngine, "Entity", "T addComponent<T>()", entity_addGenericComponent);
REGISTER_GENERIC_OBJECT_METHOD(scriptEngine, "Entity", "void removeComponent<T>()", entity_removeGenericComponent);
REGISTER_GENERIC_OBJECT_METHOD(scriptEngine, "Entity", "bool hasComponent<T>()", entity_hasGenericComponent);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "TransformComponent", "vec3 get_position() const property", transform_getPosition);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "TransformComponent", "vec3 get_scale() const property", transform_getScale);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "TransformComponent", "vec3 get_rotation() const property", transform_getRotation);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "TransformComponent", "void set_position(const vec3) property", transform_setPosition);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "TransformComponent", "void set_scale(const vec3) property", transform_setScale);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "TransformComponent", "void set_rotation(const vec3) property", transform_setRotation);
}
void Scripting::registerEntityStructs() {
AS_CHECK(scriptEngine->RegisterObjectType("Entity", sizeof(EntityHandle), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_C));
AS_CHECK(scriptEngine->RegisterObjectType("TransformComponent", sizeof(EntityHandle), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_C));
REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "Entity", "void f()", constructEntityStruct);
REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "TransformComponent", "void f()", constructEntityStruct);
}
} // namespace Deer

View File

@ -1,24 +1,23 @@
#include "DeerCore/ScriptSystem.h" #include "DeerCore/Scripting.h"
#include "DeerCore/ScriptSystem/Helpers.h" #include "DeerCore/Scripting/Helpers.h"
#include "DeerCore/ScriptSystem/InternalAPI/Math.h" #include "DeerCore/Scripting/InternalAPI/Math.h"
#include "angelscript.h" #include "angelscript.h"
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
extern asIScriptEngine* scriptEngine; extern asIScriptEngine* scriptEngine;
void registerMath(); void registerMath();
void registerMathStructs(); void registerMathStructs();
void registerMathFunctions(); void registerMathFunctions();
} // namespace ScriptSystem } // namespace Scripting
void ScriptSystem::registerMathStructs() { void Scripting::registerMathStructs() {
scriptEngine->RegisterObjectType("quat", sizeof(glm::vec3), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<glm::quat>() | asOBJ_APP_CLASS_ALLFLOATS); scriptEngine->RegisterObjectType("vec3", sizeof(glm::vec3), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<glm::quat>() | asOBJ_APP_CLASS_ALLFLOATS);
scriptEngine->RegisterObjectProperty("vec3", "float x", asOFFSET(glm::vec3, x)); scriptEngine->RegisterObjectProperty("vec3", "float x", asOFFSET(glm::vec3, x));
scriptEngine->RegisterObjectProperty("vec3", "float y", asOFFSET(glm::vec3, y)); scriptEngine->RegisterObjectProperty("vec3", "float y", asOFFSET(glm::vec3, y));
scriptEngine->RegisterObjectProperty("vec3", "float z", asOFFSET(glm::vec3, z)); scriptEngine->RegisterObjectProperty("vec3", "float z", asOFFSET(glm::vec3, z));
REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "vec3", "void f()", vec3_constructor); REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "vec3", "void f(float = 0, float = 0, float = 0)", vec3_constructor_params);
REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "vec3", "void f(float, float = 0, float = 0)", vec3_constructor_params);
scriptEngine->RegisterObjectType("quat", sizeof(glm::quat), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<glm::quat>() | asOBJ_APP_CLASS_ALLFLOATS); scriptEngine->RegisterObjectType("quat", sizeof(glm::quat), asOBJ_VALUE | asOBJ_POD | asGetTypeTraits<glm::quat>() | asOBJ_APP_CLASS_ALLFLOATS);
scriptEngine->RegisterObjectProperty("quat", "float x", asOFFSET(glm::quat, x)); scriptEngine->RegisterObjectProperty("quat", "float x", asOFFSET(glm::quat, x));
@ -47,7 +46,7 @@ namespace Deer {
REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "WorldCamera", "void f()", sceneCamera_Construct); REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "WorldCamera", "void f()", sceneCamera_Construct);
} }
void ScriptSystem::registerMathFunctions() { void Scripting::registerMathFunctions() {
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "vec3", "vec3 opAdd(const vec3 &in)", vec3_add); REGISTER_EXT_OBJECT_METHOD(scriptEngine, "vec3", "vec3 opAdd(const vec3 &in)", vec3_add);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "vec3", "vec3 opSub(const vec3 &in) const", vec3_sub); REGISTER_EXT_OBJECT_METHOD(scriptEngine, "vec3", "vec3 opSub(const vec3 &in) const", vec3_sub);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "vec3", "vec3 opNeg() const", vec3_neg); REGISTER_EXT_OBJECT_METHOD(scriptEngine, "vec3", "vec3 opNeg() const", vec3_neg);
@ -61,7 +60,7 @@ namespace Deer {
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Transform", "vec3 relative(vec3)", transform_relative); REGISTER_EXT_OBJECT_METHOD(scriptEngine, "Transform", "vec3 relative(vec3)", transform_relative);
} }
void ScriptSystem::registerMath() { void Scripting::registerMath() {
registerMathStructs(); registerMathStructs();
registerMathFunctions(); registerMathFunctions();
} }

View File

@ -0,0 +1,33 @@
#include "DeerCore/Scripting.h"
#include "DeerCore/Tools/Path.h"
#include "angelscript.h"
#include "scriptbuilder.h"
#include <filesystem>
namespace fs = std::filesystem;
namespace Deer {
namespace Scripting {
extern asIScriptEngine* scriptEngine;
void generatePredefined(const Path&);
} // namespace Scripting
void Scripting::compileFiles(const Path& path, const char* moduleName) {
CScriptBuilder scriptBuilder;
generatePredefined(path);
scriptBuilder.StartNewModule(scriptEngine, moduleName);
for (const auto& entry : fs::recursive_directory_iterator(path)) {
if (!entry.is_regular_file())
continue;
if (entry.path().extension() == ".as") {
scriptBuilder.AddSectionFromFile(entry.path().string().c_str());
}
}
scriptBuilder.BuildModule();
}
} // namespace Deer

View File

@ -0,0 +1,167 @@
#include "DeerCore/Log.h"
#include "DeerCore/Scripting.h"
#include "DeerCore/Scripting/Helpers.h"
#include "DeerCore/Scripting/ScriptEnvironmentContextData.h"
#include "angelscript.h"
namespace Deer {
namespace Scripting {
extern asIScriptEngine* scriptEngine;
bool typeImplementsInterface(asITypeInfo* type, asITypeInfo* interface);
std::string getFactoryDeclaration(asITypeInfo* type);
} // namespace Scripting
std::string Scripting::getFactoryDeclaration(asITypeInfo* type) {
std::string factory = type->GetName();
factory += " @";
factory += type->GetName();
factory += "()";
return factory;
}
Scope<ScriptEnvironment> Scripting::createScriptEnvironment(const SystemDescription& systemDescription) {
return Scope<ScriptEnvironment>(new ScriptEnvironment(systemDescription));
}
ScriptObjectGroup::ScriptObjectGroup(ScriptEnvironment* env) : environment(env) {
systemInstances = MakeScope<asIScriptObject*[]>(environment->systemDescription.events.size());
}
ScriptEnvironment::ScriptEnvironment(const Scripting::SystemDescription& desc) : systemDescription(desc) {
module = Scripting::scriptEngine->GetModule(systemDescription.moduleName.c_str());
baseType = Scripting::scriptEngine->GetTypeInfoByName(systemDescription.baseTypeName.c_str());
context = Scripting::scriptEngine->CreateContext();
if (!baseType) {
DEER_CORE_ERROR("Could not find {} on script environment", systemDescription.baseTypeName.c_str());
return;
}
size_t typeCount = module->GetObjectTypeCount();
std::vector<asITypeInfo*> types;
for (int i = 0; i < typeCount; i++) {
asITypeInfo* type = module->GetObjectTypeByIndex(i);
if (Scripting::typeImplementsInterface(type, baseType))
systems.push_back(Scope<ScriptSystem>(new ScriptSystem(systemDescription, type)));
}
}
ScriptEnvironment::~ScriptEnvironment() {
context->Release();
}
bool Scripting::typeImplementsInterface(asITypeInfo* type, asITypeInfo* interface) {
size_t interfaceCount = type->GetInterfaceCount();
for (int i = 0; i < interfaceCount; i++) {
asITypeInfo* subInterface = type->GetInterface(i);
if (subInterface->GetTypeId() == interface->GetTypeId())
return true;
}
return false;
}
ScriptSystem::ScriptSystem(const Scripting::SystemDescription& desc, asITypeInfo* type)
: systemType(type) {
environmentFunctions = MakeScope<asIScriptFunction*[]>(desc.events.size());
for (size_t i = 0; i < desc.events.size(); i++) {
const Scripting::SystemEvent& event = desc.events[i];
asIScriptFunction* eventFunc = type->GetMethodByName(event.eventName.c_str());
environmentFunctions[i] = eventFunc;
}
}
const char* ScriptSystem::getSystemName() {
return systemType->GetName();
}
size_t ScriptEnvironment::getSystemCount() {
return systems.size();
}
ScriptSystem* ScriptEnvironment::getSystemByIndex(size_t index) {
return systems[index].get();
}
ScriptObjectGroup* ScriptEnvironment::createGroupWithAllSystems() {
systemGroups.push_back(Scope<ScriptObjectGroup>(new ScriptObjectGroup(this)));
ScriptObjectGroup* systemGroup = systemGroups.back().get();
for (size_t i = 0; i < systems.size(); i++) {
systemGroup->createScriptObject(i);
}
return systemGroup;
}
ScriptObjectGroup* ScriptEnvironment::createEmptyGroup() {
systemGroups.push_back(Scope<ScriptObjectGroup>(new ScriptObjectGroup(this)));
ScriptObjectGroup* systemGroup = systemGroups.back().get();
return systemGroup;
}
bool ScriptObjectGroup::createScriptObject(size_t systemIndex) {
if (systemInstances[systemIndex])
return false;
ScriptSystem& system = *environment->systems[systemIndex];
std::string factoryDeclaration = Scripting::getFactoryDeclaration(system.systemType);
asIScriptFunction* factory = system.systemType->GetFactoryByDecl(factoryDeclaration.c_str());
if (!factory) {
DEER_SCRIPT_ERROR("Could not create system {}, factory declaration not found", factoryDeclaration.c_str());
return false;
}
environment->context->Prepare(factory);
environment->context->Execute();
asIScriptObject* object = *(asIScriptObject**)environment->context->GetAddressOfReturnValue();
systemInstances[systemIndex] = object;
object->AddRef();
environment->context->Unprepare();
return true;
}
void ScriptObjectGroup::executeOnObject_voidEvent(size_t systemIndex, size_t eventIndex) {
if (!systemInstances[systemIndex])
return;
ScriptSystem* system = environment->systems[systemIndex].get();
asIScriptFunction* function = system->environmentFunctions[eventIndex];
if (!function)
return;
environment->context->Prepare(function);
environment->context->SetObject(systemInstances[systemIndex]);
environment->context->Execute();
environment->context->Unprepare();
}
void ScriptObjectGroup::executeOnGroup_voidEvent(size_t eventIndex) {
for (size_t i = 0; i < environment->systems.size(); i++) {
if (!systemInstances[i])
continue;
ScriptSystem* system = environment->systems[i].get();
asIScriptFunction* function = system->environmentFunctions[eventIndex];
if (!function)
return;
environment->context->Prepare(function);
environment->context->SetObject(systemInstances[i]);
environment->context->Execute();
}
environment->context->Unprepare();
}
} // namespace Deer

View File

@ -0,0 +1,13 @@
#pragma once
namespace Deer {
class ScriptEnvironment;
class World;
struct ScriptEnvironmentContextData {
ScriptEnvironmentContextData();
ScriptEnvironment* environment;
World* world;
};
} // namespace Deer

View File

@ -1,6 +1,6 @@
#include "DeerCore/ScriptSystem.h" #include "DeerCore/Scripting.h"
#include "DeerCore/ScriptSystem/Helpers.h" #include "DeerCore/Scripting/Helpers.h"
#include "DeerCore/ScriptSystem/InternalAPI/InternalFunctions.h" #include "DeerCore/Scripting/InternalAPI/InternalFunctions.h"
#include "angelscript.h" #include "angelscript.h"
#include "scriptany.h" #include "scriptany.h"
@ -14,37 +14,63 @@
#include <string> #include <string>
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
asIScriptEngine* scriptEngine; asIScriptEngine* scriptEngine;
void registerMath(); void registerMath();
void registerEngine(); void registerEngine();
void registerEntity();
#ifdef DEER_RENDER #ifdef DEER_RENDER
void registerResources(); void registerResources();
void registerEntity_Render();
#endif #endif
}; // namespace ScriptSystem }; // namespace Scripting
void ScriptSystem::init() { void Scripting::init() {
asPrepareMultithread(); asPrepareMultithread();
scriptEngine = asCreateScriptEngine(); scriptEngine = asCreateScriptEngine();
AS_CHECK(scriptEngine->SetMessageCallback(asFUNCTION(Deer::ScriptSystem::errorCallback_angelscript), 0, asCALL_CDECL)); AS_CHECK(scriptEngine->SetMessageCallback(asFUNCTION(Deer::Scripting::errorCallback_angelscript), 0, asCALL_CDECL));
REGISTER_GLOBAL_FUNC(scriptEngine, "void print(const string&in text)", print);
RegisterStdString(scriptEngine);
REGISTER_GLOBAL_FUNC(scriptEngine, "void print(const string&in text)", print);
RegisterScriptHandle(scriptEngine); RegisterScriptHandle(scriptEngine);
RegisterScriptAny(scriptEngine); RegisterScriptAny(scriptEngine);
RegisterStdString(scriptEngine);
RegisterScriptArray(scriptEngine, true); RegisterScriptArray(scriptEngine, true);
RegisterScriptDictionary(scriptEngine); RegisterScriptDictionary(scriptEngine);
registerMath(); registerMath();
registerEngine(); registerEngine();
registerEntity();
#ifdef DEER_RENDER #ifdef DEER_RENDER
registerResources(); registerResources();
registerEntity_Render();
#endif #endif
} }
void ScriptSystem::shutdown() { void Scripting::shutdown() {
asUnprepareMultithread(); asUnprepareMultithread();
} }
void Scripting::registerInterface(const char* name) {
AS_CHECK(scriptEngine->RegisterInterface(name));
}
void Scripting::registerInterfaceFunction(const char* name, const char* funcName, EventType funcType) {
std::string decl;
switch (funcType) {
case EventType::void_event:
decl += "void ";
decl += funcName;
decl += "()";
break;
default:
break;
}
AS_CHECK(scriptEngine->RegisterInterfaceMethod(name, decl.c_str()));
}
} // namespace Deer } // namespace Deer

View File

@ -3,7 +3,7 @@
#include "DeerCore/Log.h" #include "DeerCore/Log.h"
namespace Deer { namespace Deer {
Entity::Entity(entt::entity handle, EntityEnvironment* scene, uint16_t entityID) Entity::Entity(entt::entity handle, EntityEnvironment* scene, uint32_t entityID)
: entHandle(handle), : entHandle(handle),
environment(scene), environment(scene),
entId(entityID) {} entId(entityID) {}

View File

@ -1,6 +1,7 @@
#include "DeerCore/EntityEnviroment.h" #include "DeerCore/EntityEnviroment.h"
namespace Deer { namespace Deer {
template <>
Scope<EntityEnvironment> ResourceBuilder<EntityEnvironment>::buildResource(const BaseDataType& baseData) { Scope<EntityEnvironment> ResourceBuilder<EntityEnvironment>::buildResource(const BaseDataType& baseData) {
Scope<EntityEnvironment> env = MakeScope<EntityEnvironment>(); Scope<EntityEnvironment> env = MakeScope<EntityEnvironment>();
return env; return env;

View File

@ -2,8 +2,8 @@
#include "DeerRender/Engine.h" #include "DeerRender/Engine.h"
#include "DeerRender/Log.h" #include "DeerRender/Log.h"
#include "DeerRender/ImGui/ImGuiLayer.h" #include "DeerRender/ImGuiLayer.h"
#include "DeerRender/ScriptSystem.h" #include "DeerRender/Scripting.h"
#include "DeerRender/Universe.h" #include "DeerRender/Universe.h"
#include "DeerRender/Window.h" #include "DeerRender/Window.h"
#include "DeerRender/World.h" #include "DeerRender/World.h"
@ -25,7 +25,6 @@ namespace Deer {
EventFunction eventCallback; EventFunction eventCallback;
Scope<Window> window = nullptr; Scope<Window> window = nullptr;
Scope<ImGuiLayer> imGuiLayer = nullptr;
bool running = true; bool running = true;
void internalEventCallback(Event& e); void internalEventCallback(Event& e);
@ -52,14 +51,12 @@ namespace Deer {
if (eventCallback) if (eventCallback)
eventCallback(e); eventCallback(e);
imGuiLayer->onEvent(e); ImGuiLayer::onEvent(e);
} }
void Engine::init() { void Engine::init() {
Log::init(); Log::init();
ScriptSystem::init(); Scripting::init();
imGuiLayer = MakeScope<ImGuiLayer>();
window = Scope<Window>(Window::create()); window = Scope<Window>(Window::create());
window->setEventCallback(Engine::internalEventCallback); window->setEventCallback(Engine::internalEventCallback);
@ -68,8 +65,7 @@ namespace Deer {
RenderCommand::init(); RenderCommand::init();
RenderUtils::initializeRenderUtils(); RenderUtils::initializeRenderUtils();
imGuiLayer = MakeScope<ImGuiLayer>(); ImGuiLayer::init(*window);
imGuiLayer->onAttach(*window);
} }
void Engine::shutdown() { void Engine::shutdown() {
@ -80,11 +76,10 @@ namespace Deer {
ResourceManager<FrameBuffer>::unloadResources(); ResourceManager<FrameBuffer>::unloadResources();
ResourceManager<Texture>::unloadResources(); ResourceManager<Texture>::unloadResources();
imGuiLayer->onDetach(); ImGuiLayer::shutdown();
imGuiLayer.reset();
window.reset(); window.reset();
ScriptSystem::shutdown(); Scripting::shutdown();
RenderUtils::deinitializeRenderUtils(); RenderUtils::deinitializeRenderUtils();
Log::shutdown(); Log::shutdown();
} }
@ -95,11 +90,11 @@ namespace Deer {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
io.DeltaTime = 1.0f / 60; io.DeltaTime = 1.0f / 60;
imGuiLayer->begin(); ImGuiLayer::begin();
} }
void Engine::endRender() { void Engine::endRender() {
imGuiLayer->end(); ImGuiLayer::end();
window->onRender(); window->onRender();
window->resolveEvents(); window->resolveEvents();
} }

View File

@ -1,4 +1,4 @@
#include "DeerRender/ImGui/ImGuiLayer.h" #include "DeerRender/ImGuiLayer.h"
#include "DeerRender/Events/Event.h" #include "DeerRender/Events/Event.h"
#include "DeerRender/Input.h" #include "DeerRender/Input.h"
@ -20,7 +20,31 @@
#include "ImGuizmo.h" #include "ImGuizmo.h"
namespace Deer { namespace Deer {
void ImGuiLayer::onAttach(Window& window) { namespace ImGuiLayer {
ImFont* textFont = nullptr;
ImFont* titleFont = nullptr;
} // namespace ImGuiLayer
void ImGuiLayer::setTextFont(ImFont* font) {
textFont = textFont;
}
void ImGuiLayer::setTitleFont(ImFont* font) {
titleFont = font;
}
ImFont* ImGuiLayer::getTextFont() {
if (!textFont)
return ImGui::GetFont();
return textFont;
}
ImFont* ImGuiLayer::getTitleFont() {
if (!titleFont)
return ImGui::GetFont();
return titleFont;
}
void ImGuiLayer::init(Window& window) {
ImGui::CreateContext(); ImGui::CreateContext();
ImGui::StyleColorsDark(); ImGui::StyleColorsDark();
@ -35,8 +59,6 @@ namespace Deer {
io.DisplaySize = ImVec2(window.getWitdth(), window.getHeight()); io.DisplaySize = ImVec2(window.getWitdth(), window.getHeight());
} }
void ImGuiLayer::onDetach() {}
void ImGuiLayer::begin() { void ImGuiLayer::begin() {
ImGui_ImplOpenGL3_NewFrame(); ImGui_ImplOpenGL3_NewFrame();
ImGui::NewFrame(); ImGui::NewFrame();
@ -53,21 +75,7 @@ namespace Deer {
void ImGuiLayer::onEvent(Event& e) { void ImGuiLayer::onEvent(Event& e) {
EventDispatcher dispacher(e); EventDispatcher dispacher(e);
dispacher.dispatch<WindowResizeEvent>(ImGuiLayer::onWindowResizeEvent);
// dispacher.dispatch<MouseButtonPressedEvent>(std::bind(&ImGuiLayer::onMouseButtonPressedEvent,
// this, std::placeholders::_1));
// dispacher.dispatch<MouseButtonReleasedEvent>(std::bind(&ImGuiLayer::onMouseButtonReleasedEvent,
// this, std::placeholders::_1));
// dispacher.dispatch<MouseMovedEvent>(std::bind(&ImGuiLayer::onMouseMovedEvent,
// this, std::placeholders::_1));
// dispacher.dispatch<MouseScrolledEvent>(std::bind(&ImGuiLayer::onMouseScrollEvent,
// this, std::placeholders::_1));
// dispacher.dispatch<KeyPressedEvent>(std::bind(&ImGuiLayer::onKeyPressedEvent,
// this, std::placeholders::_1));
// dispacher.dispatch<KeyTypedEvent>(std::bind(&ImGuiLayer::onKeyTypedEvent,
// this, std::placeholders::_1));
dispacher.dispatch<WindowResizeEvent>(std::bind(
&ImGuiLayer::onWindowResizeEvent, this, std::placeholders::_1));
} }
bool ImGuiLayer::onMouseButtonPressedEvent(MouseButtonPressedEvent& e) { bool ImGuiLayer::onMouseButtonPressedEvent(MouseButtonPressedEvent& e) {
@ -96,6 +104,9 @@ namespace Deer {
return false; return false;
} }
void ImGuiLayer::shutdown() {
}
bool ImGuiLayer::onKeyPressedEvent(KeyPressedEvent& e) { bool ImGuiLayer::onKeyPressedEvent(KeyPressedEvent& e) {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGuiKey key = static_cast<ImGuiKey>(e.getKeyCode()); ImGuiKey key = static_cast<ImGuiKey>(e.getKeyCode());

View File

@ -1,32 +0,0 @@
#pragma once
#include "scriptarray.h"
#include "scriptdictionary.h"
#include <stdint.h>
#include <string>
namespace Deer {
namespace ScriptSystem {
template <typename T>
std::string resource_getPath(Resource<T> resource) {
return ResourceManager<T>::getStorageId(resource);
}
template <typename T>
std::string resource_getName(Resource<T> resource) {
return ResourceManager<T>::getStorageId(resource).stem().string();
}
enum ResourceType : uint32_t {
NONE = 0,
MESH = 1,
SHADER = 2,
TEXTURE = 3,
};
CScriptArray* getResourceFolders(std::string& path);
CScriptArray* getResourceFiles(std::string& path);
ResourceType getResourceType(std::string&);
} // namespace ScriptSystem
} // namespace Deer

View File

@ -0,0 +1,54 @@
#include "DeerCore/Scripting/Helpers.h"
#include "DeerRender/Scripting/InternalAPI/Entity.h"
namespace Deer {
namespace Scripting {
extern asIScriptEngine* scriptEngine;
void registerEntity_Render();
void registerEntityFunctions_Render();
void registerEntityStructs_Render();
} // namespace Scripting
void Scripting::registerEntity_Render() {
registerEntityStructs_Render();
registerEntityFunctions_Render();
}
void Scripting::registerEntityFunctions_Render() {
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "MeshComponent", "bool get_isActive() const property", mesh_isActive);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "MeshComponent", "bool get_hasMesh() const property", mesh_hasMesh);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "MeshComponent", "void clear()", mesh_clear);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "MeshComponent", "GPUMesh get_meshResource() property", mesh_getMesh);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "MeshComponent", "void set_meshResource(GPUMesh) property", mesh_setMesh);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "MeshComponent", "void set_isActive(const bool) const property", mesh_setActive);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "ShaderComponent", "bool get_hasShader() const property", shader_hasShader);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "ShaderComponent", "void clear()", shader_clear);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "ShaderComponent", "Shader get_shader() const property", shader_getShader);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "ShaderComponent", "void set_shader(Shader) property", shader_setShader);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "ShaderComponent", "Texture get_texture() const property", shader_getTexture);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "ShaderComponent", "void set_texture(Texture) property", shader_setTexture);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "CameraComponent", "float get_fov() const property", camera_getFov);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "CameraComponent", "float get_aspectRatio() const property", camera_getAspectRation);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "CameraComponent", "float get_nearZ() const property", camera_getNearZ);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "CameraComponent", "float get_farZ() const property", camera_getFarZ);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "CameraComponent", "void set_fov(float) property", camera_setFov);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "CameraComponent", "void set_aspectRatio(float) property", camera_setAspectRation);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "CameraComponent", "void set_nearZ(float) property", camera_setNearZ);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "CameraComponent", "void set_farZ(float) property", camera_setFarZ);
}
void Scripting::registerEntityStructs_Render() {
AS_CHECK(scriptEngine->RegisterObjectType("MeshComponent", sizeof(EntityHandle), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_C));
AS_CHECK(scriptEngine->RegisterObjectType("ShaderComponent", sizeof(EntityHandle), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_C));
AS_CHECK(scriptEngine->RegisterObjectType("CameraComponent", sizeof(EntityHandle), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asOBJ_APP_CLASS_C));
REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "MeshComponent", "void f()", constructEntityStruct);
REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "ShaderComponent", "void f()", constructEntityStruct);
REGISTER_EXT_OBJECT_CONSTRUCTOR(scriptEngine, "CameraComponent", "void f()", constructEntityStruct);
}
} // namespace Deer

View File

@ -0,0 +1,108 @@
#include "DeerRender/Scripting/InternalAPI/Entity.h"
#include "DeerCore/Scripting/ScriptEnvironmentContextData.h"
#include "DeerCore/EntityEnviroment.h"
#include "angelscript.h"
namespace Deer {
template <typename T>
T& Scripting::getContextEntityComponent(EntityHandle handle) {
asIScriptContext* context = asGetActiveContext();
ScriptEnvironmentContextData* environmentData = (ScriptEnvironmentContextData*)context->GetUserData();
if (handle.environmentId == 0) {
return environmentData->world->entityEnvironment->getEntity(handle.entityId).getComponent<T>();
}
// Implement entity reference of other environments
return environmentData->world->entityEnvironment->getEntity(handle.entityId).getComponent<T>();
}
// MESH COMPONENT
bool Scripting::mesh_isActive(EntityHandle& handle) {
MeshComponent& meshComponent = getContextEntityComponent<MeshComponent>(handle);
return meshComponent.active;
}
void Scripting::mesh_setActive(bool state, EntityHandle& handle) {
MeshComponent& meshComponent = getContextEntityComponent<MeshComponent>(handle);
meshComponent.active = state;
}
bool Scripting::mesh_hasMesh(EntityHandle& handle) {
MeshComponent& meshComponent = getContextEntityComponent<MeshComponent>(handle);
return meshComponent.mesh.isValid();
}
void Scripting::mesh_clear(EntityHandle& handle) {
MeshComponent& meshComponent = getContextEntityComponent<MeshComponent>(handle);
meshComponent.mesh = Resource<GPUMesh>();
}
Resource<GPUMesh> Scripting::mesh_getMesh(EntityHandle& handle) {
MeshComponent& meshComponent = getContextEntityComponent<MeshComponent>(handle);
return meshComponent.mesh;
}
void Scripting::mesh_setMesh(Resource<GPUMesh> mesh, EntityHandle& handle) {
MeshComponent& meshComponent = getContextEntityComponent<MeshComponent>(handle);
meshComponent.mesh = mesh;
}
// SHADER
bool Scripting::shader_hasShader(EntityHandle& handle) {
ShaderComponent& shaderComponent = getContextEntityComponent<ShaderComponent>(handle);
return shaderComponent.shader.isValid();
}
void Scripting::shader_clear(EntityHandle& handle) {
ShaderComponent& shaderComponent = getContextEntityComponent<ShaderComponent>(handle);
shaderComponent.shader = Resource<Shader>();
}
Resource<Shader> Scripting::shader_getShader(EntityHandle& handle) {
ShaderComponent& shaderComponent = getContextEntityComponent<ShaderComponent>(handle);
return shaderComponent.shader;
}
void Scripting::shader_setShader(Resource<Shader> shader, EntityHandle& handle) {
ShaderComponent& shaderComponent = getContextEntityComponent<ShaderComponent>(handle);
shaderComponent.shader = shader;
}
Resource<Texture> Scripting::shader_getTexture(EntityHandle& handle) {
ShaderComponent& shaderComponent = getContextEntityComponent<ShaderComponent>(handle);
return shaderComponent.texture;
}
void Scripting::shader_setTexture(Resource<Texture> texture, EntityHandle& handle) {
ShaderComponent& shaderComponent = getContextEntityComponent<ShaderComponent>(handle);
shaderComponent.texture = texture;
}
// CAMERA
float Scripting::camera_getFov(EntityHandle& handle) {
CameraComponent& cameraComponent = getContextEntityComponent<CameraComponent>(handle);
return cameraComponent.fov;
}
float Scripting::camera_getAspectRation(EntityHandle& handle) {
CameraComponent& cameraComponent = getContextEntityComponent<CameraComponent>(handle);
return cameraComponent.aspect;
}
float Scripting::camera_getNearZ(EntityHandle& handle) {
CameraComponent& cameraComponent = getContextEntityComponent<CameraComponent>(handle);
return cameraComponent.nearZ;
}
float Scripting::camera_getFarZ(EntityHandle& handle) {
CameraComponent& cameraComponent = getContextEntityComponent<CameraComponent>(handle);
return cameraComponent.farZ;
}
void Scripting::camera_setFov(float fov, EntityHandle& handle) {
CameraComponent& cameraComponent = getContextEntityComponent<CameraComponent>(handle);
cameraComponent.fov = fov;
}
void Scripting::camera_setAspectRation(float ratio, EntityHandle& handle) {
CameraComponent& cameraComponent = getContextEntityComponent<CameraComponent>(handle);
cameraComponent.aspect = ratio;
}
void Scripting::camera_setNearZ(float nearZ, EntityHandle& handle) {
CameraComponent& cameraComponent = getContextEntityComponent<CameraComponent>(handle);
cameraComponent.nearZ = nearZ;
}
void Scripting::camera_setFarZ(float farZ, EntityHandle& handle) {
CameraComponent& cameraComponent = getContextEntityComponent<CameraComponent>(handle);
cameraComponent.farZ = farZ;
}
} // namespace Deer

View File

@ -0,0 +1,41 @@
#pragma once
#include "DeerCore/Scripting/InternalAPI/Entity.h"
#include "DeerRender/Mesh.h"
#include "DeerRender/Resource.h"
#include "DeerRender/Shader.h"
#include "DeerRender/Texture.h"
namespace Deer {
class Entity;
class EntityEnvironment;
namespace Scripting {
// MESH COMPONENT
bool mesh_isActive(EntityHandle&);
void mesh_setActive(bool, EntityHandle&);
bool mesh_hasMesh(EntityHandle&);
void mesh_clear(EntityHandle&);
Resource<GPUMesh> mesh_getMesh(EntityHandle&);
void mesh_setMesh(Resource<GPUMesh>, EntityHandle&);
// SHADER
bool shader_hasShader(EntityHandle&);
void shader_clear(EntityHandle&);
Resource<Shader> shader_getShader(EntityHandle&);
void shader_setShader(Resource<Shader>, EntityHandle&);
Resource<Texture> shader_getTexture(EntityHandle&);
void shader_setTexture(Resource<Texture>, EntityHandle&);
// CAMERA
float camera_getFov(EntityHandle&);
float camera_getAspectRation(EntityHandle&);
float camera_getNearZ(EntityHandle&);
float camera_getFarZ(EntityHandle&);
void camera_setFov(float, EntityHandle&);
void camera_setAspectRation(float, EntityHandle&);
void camera_setNearZ(float, EntityHandle&);
void camera_setFarZ(float, EntityHandle&);
} // namespace Scripting
} // namespace Deer

View File

@ -1,11 +1,12 @@
#include "DeerStudio/StudioAPI/UI.h"
#include "DeerRender/FrameBuffer.h" #include "DeerRender/FrameBuffer.h"
#include "DeerRender/Log.h" #include "DeerRender/Log.h"
#include "DeerStudio/AngelScriptEngine.h" #include "DeerCore/Scripting/Helpers.h"
#include "DeerStudio/AngelScriptEngine/ErrorHandle.h" #include "DeerRender/Texture.h"
#include "glm/glm.hpp"
#include "DeerStudio/Fonts.h" #include "DeerRender/ImGuiLayer.h"
#include "DeerRender/Scripting/InternalAPI/ImGUI.h"
#include "angelscript.h" #include "angelscript.h"
#include "imgui.h" #include "imgui.h"
#include "scriptany.h" #include "scriptany.h"
@ -13,7 +14,7 @@
#include <string> #include <string>
namespace Deer { namespace Deer {
namespace StudioAPI { namespace Scripting {
namespace DragDropPayload { namespace DragDropPayload {
CScriptAny* payload; CScriptAny* payload;
} }
@ -21,25 +22,25 @@ namespace Deer {
void separator() { ImGui::Separator(); } void separator() { ImGui::Separator(); }
void title(std::string& txt) { void title(std::string& txt) {
ImGui::PushFont(titleText); ImGui::PushFont(ImGuiLayer::getTitleFont());
ImGui::Text("%s", txt.c_str()); ImGui::Text("%s", txt.c_str());
ImGui::PopFont(); ImGui::PopFont();
} }
void titleEnd(std::string& txt) { void titleEnd(std::string& txt) {
ImGui::PushFont(titleText); ImGui::PushFont(ImGuiLayer::getTitleFont());
textEnd(txt); textEnd(txt);
ImGui::PopFont(); ImGui::PopFont();
} }
void titleCenter(std::string& txt) { void titleCenter(std::string& txt) {
ImGui::PushFont(titleText); ImGui::PushFont(ImGuiLayer::getTitleFont());
textCenter(txt); textCenter(txt);
ImGui::PopFont(); ImGui::PopFont();
} }
void titleCenterY(std::string& txt, int height) { void titleCenterY(std::string& txt, int height) {
ImGui::PushFont(titleText); ImGui::PushFont(ImGuiLayer::getTitleFont());
float textHeight = ImGui::GetFontSize(); float textHeight = ImGui::GetFontSize();
float yOffset = (height - textHeight) * 0.5f; float yOffset = (height - textHeight) * 0.5f;
@ -118,9 +119,9 @@ namespace Deer {
p.x + (itemWidth - iconSize) * 0.5f, p.x + (itemWidth - iconSize) * 0.5f,
p.y + 2.0f + offset); p.y + 2.0f + offset);
int texId = StudioAPI::getIconId("Icons/" + icon); Resource<Texture> texture = ResourceManager<Texture>::getResource(icon);
dl->AddImage( dl->AddImage(
(ImTextureID)texId, (ImTextureID)texture.getData().getTextureID(),
iconPos, iconPos,
ImVec2(iconPos.x + iconSize, iconPos.y + iconSize), ImVec2(iconPos.x + iconSize, iconPos.y + iconSize),
ImVec2(0, 1), ImVec2(0, 1),
@ -137,7 +138,7 @@ namespace Deer {
return pressed; return pressed;
} }
bool cartIconButton_frameBuffer(const std::string& label, FrameBufferHandleStruct icon, int iconSize, int width) { bool cartIconButton_frameBuffer(const std::string& label, Resource<FrameBuffer> icon, int iconSize, int width) {
ImGui::BeginGroup(); ImGui::BeginGroup();
int offset = 16; int offset = 16;
@ -165,7 +166,7 @@ namespace Deer {
p.x + (itemWidth - iconSize) * 0.5f, p.x + (itemWidth - iconSize) * 0.5f,
p.y + 2.0f + offset); p.y + 2.0f + offset);
FrameBuffer& frameBuffer = Resource<FrameBuffer>::unsafeFromId(icon.frameBufferId).getData(); FrameBuffer& frameBuffer = icon.getData();
frameBuffer.bind(); frameBuffer.bind();
ImTextureID texId = frameBuffer.getTextureBufferID(); ImTextureID texId = frameBuffer.getTextureBufferID();
dl->AddImage( dl->AddImage(
@ -233,15 +234,9 @@ namespace Deer {
} }
void drawIcon(std::string& name, int size) { void drawIcon(std::string& name, int size) {
int iconId = StudioAPI::getIconId("Icons/" + name); Resource<Texture> texture = ResourceManager<Texture>::getResource(name);
if (iconId < 0) { ImGui::Image((void*)(uint64_t)texture.getData().getTextureID(), ImVec2(size, size), ImVec2(0, 1), ImVec2(1, 0));
DEER_EDITOR_ENGINE_ERROR("Invalid icon name {0}", name.c_str());
StudioAPI::raiseError();
return;
}
ImGui::Image((void*)(uint64_t)iconId, ImVec2(size, size), ImVec2(0, 1), ImVec2(1, 0));
} }
void drawIcon_resource(Resource<Texture> texture, int size) { void drawIcon_resource(Resource<Texture> texture, int size) {
@ -254,20 +249,19 @@ namespace Deer {
} }
void drawIconHighlight(std::string& name, int size) { void drawIconHighlight(std::string& name, int size) {
int iconId = StudioAPI::getIconId(name); Resource<Texture> texture = ResourceManager<Texture>::getResource(name);
int iconId = texture.getData().getTextureID();
if (iconId < 0) { if (iconId < 0) {
DEER_EDITOR_ENGINE_ERROR("Invalid icon name {0}", name.c_str()); DEER_EDITOR_ENGINE_ERROR("Invalid icon name {0}", name.c_str());
StudioAPI::raiseError();
return; return;
} }
ImGui::Image((void*)(uint64_t)iconId, ImVec2(size, size), ImVec2(0, 1), ImVec2(1, 0), ImVec4(0.5f, 0.6f, 0.8f, 1.0f), ImVec4(0, 0, 0, 0)); ImGui::Image((void*)(uint64_t)iconId, ImVec2(size, size), ImVec2(0, 1), ImVec2(1, 0), ImVec4(0.5f, 0.6f, 0.8f, 1.0f), ImVec4(0, 0, 0, 0));
} }
void drawFrameBuffer(FrameBufferHandleStruct frameBuffer_handle, int sizeX, int sizeY) { void drawFrameBuffer(Resource<FrameBuffer> frameBufferResource, int sizeX, int sizeY) {
Resource<FrameBuffer> frameBufferResource = Resource<FrameBuffer>::unsafeFromId(frameBuffer_handle.frameBufferId);
FrameBuffer& frameBuffer = frameBufferResource.getData(); FrameBuffer& frameBuffer = frameBufferResource.getData();
frameBuffer.bind(); frameBuffer.bind();
int frameBufferId = frameBuffer.getTextureBufferID(0); int frameBufferId = frameBuffer.getTextureBufferID(0);
@ -276,8 +270,7 @@ namespace Deer {
frameBuffer.unbind(); frameBuffer.unbind();
} }
void drawFrameBufferCentered(FrameBufferHandleStruct frameBuffer_handle, int _x, int _y) { void drawFrameBufferCentered(Resource<FrameBuffer> frameBufferResource, int _x, int _y) {
Resource<FrameBuffer> frameBufferResource = Resource<FrameBuffer>::unsafeFromId(frameBuffer_handle.frameBufferId);
FrameBuffer& frameBuffer = frameBufferResource.getData(); FrameBuffer& frameBuffer = frameBufferResource.getData();
int frameBufferId = frameBuffer.getTextureBufferID(); int frameBufferId = frameBuffer.getTextureBufferID();
@ -314,10 +307,10 @@ namespace Deer {
} }
void drawIconCentered(std::string& name, int size) { void drawIconCentered(std::string& name, int size) {
int iconId = StudioAPI::getIconId("Icons/" + name); Resource<Texture> texture = ResourceManager<Texture>::getResource(name);
int iconId = texture.getData().getTextureID();
if (iconId < 0) { if (iconId < 0) {
DEER_EDITOR_ENGINE_ERROR("Invalid icon name {0}", name.c_str()); DEER_EDITOR_ENGINE_ERROR("Invalid icon name {0}", name.c_str());
StudioAPI::raiseError();
return; return;
} }
@ -352,10 +345,10 @@ namespace Deer {
} }
void drawIconCenteredHighlight(std::string& name, int size) { void drawIconCenteredHighlight(std::string& name, int size) {
int iconId = StudioAPI::getIconId("Icons/" + name); Resource<Texture> texture = ResourceManager<Texture>::getResource(name);
int iconId = texture.getData().getTextureID();
if (iconId < 0) { if (iconId < 0) {
DEER_EDITOR_ENGINE_ERROR("Invalid icon name {0}", name.c_str()); DEER_EDITOR_ENGINE_ERROR("Invalid icon name {0}", name.c_str());
StudioAPI::raiseError();
return; return;
} }
@ -384,13 +377,13 @@ namespace Deer {
void subMenu(std::string& txt, asIScriptFunction* func) { void subMenu(std::string& txt, asIScriptFunction* func) {
if (ImGui::BeginMenu(txt.c_str())) { if (ImGui::BeginMenu(txt.c_str())) {
if (StudioAPI::scriptContext && asIScriptContext* scriptContext = asGetActiveContext();
StudioAPI::scriptContext->PushState() == asSUCCESS) { if (scriptContext->PushState() == asSUCCESS) {
AS_CHECK(StudioAPI::scriptContext->Prepare(func)); AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(StudioAPI::scriptContext->Execute()); AS_CHECK(scriptContext->Execute());
StudioAPI::scriptContext->PopState(); scriptContext->PopState();
} }
ImGui::EndMenu(); ImGui::EndMenu();
} }
@ -430,14 +423,15 @@ namespace Deer {
if (ImGui::AcceptDragDropPayload(id.c_str()) && if (ImGui::AcceptDragDropPayload(id.c_str()) &&
DragDropPayload::payload) { DragDropPayload::payload) {
if (StudioAPI::scriptContext && asIScriptContext* scriptContext = asGetActiveContext();
StudioAPI::scriptContext->PushState() == asSUCCESS) {
AS_CHECK(StudioAPI::scriptContext->Prepare(func)); if (scriptContext->PushState() == asSUCCESS) {
AS_CHECK(StudioAPI::scriptContext->SetArgObject(0, DragDropPayload::payload));
AS_CHECK(StudioAPI::scriptContext->Execute());
StudioAPI::scriptContext->PopState(); AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->SetArgObject(0, DragDropPayload::payload));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} }
DragDropPayload::payload->Release(); DragDropPayload::payload->Release();
@ -635,5 +629,313 @@ namespace Deer {
// value); // value);
//} //}
} }
} // namespace StudioAPI
void treeNodeLeaf(std::string& txt, bool active) {
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf |
ImGuiTreeNodeFlags_NoTreePushOnOpen |
ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Bullet |
ImGuiTreeNodeFlags_DrawLinesToNodes;
if (active)
flags |= ImGuiTreeNodeFlags_Selected;
ImGui::TreeNodeEx(txt.c_str(), flags);
}
bool treeNode(std::string& txt, bool active, asIScriptFunction& func) {
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnDoubleClick |
ImGuiTreeNodeFlags_OpenOnArrow |
ImGuiTreeNodeFlags_SpanFullWidth |
ImGuiTreeNodeFlags_DefaultOpen |
ImGuiTreeNodeFlags_DrawLinesToNodes;
if (active)
flags |= ImGuiTreeNodeFlags_Selected;
if (ImGui::TreeNodeEx(txt.c_str(), flags)) {
ImGui::PushID(txt.c_str());
asIScriptContext* scriptContext = asGetActiveContext();
if (scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(&func));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::PopID();
ImGui::TreePop();
ImGui::PopStyleVar();
return true;
}
ImGui::PopStyleVar();
return false;
}
bool componentNode(std::string& txt, asIScriptFunction* func) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_SpanAvailWidth |
ImGuiTreeNodeFlags_Framed |
ImGuiTreeNodeFlags_AllowOverlap |
ImGuiTreeNodeFlags_FramePadding |
ImGuiTreeNodeFlags_DefaultOpen;
if (ImGui::TreeNodeEx(txt.c_str(), flags)) {
ImGui::Dummy(ImVec2(0, 10));
ImGui::PushID(txt.c_str());
asIScriptContext* scriptContext = asGetActiveContext();
if (scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::Dummy(ImVec2(0, 10));
ImGui::PopID();
ImGui::TreePop();
ImGui::PopStyleVar(2);
return true;
}
ImGui::PopStyleVar(2);
return false;
}
bool componentNodeContextMenu(std::string& txt, asIScriptFunction* func, asIScriptFunction* menu) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_SpanAvailWidth |
ImGuiTreeNodeFlags_Framed |
ImGuiTreeNodeFlags_AllowOverlap |
ImGuiTreeNodeFlags_FramePadding |
ImGuiTreeNodeFlags_DefaultOpen;
if (ImGui::TreeNodeEx(txt.c_str(), flags)) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,
ImVec2(10, 10));
if (ImGui::BeginPopupContextItem(txt.c_str())) {
asIScriptContext* scriptContext = asGetActiveContext();
if (scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(menu));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
ImGui::Dummy(ImVec2(0, 10));
ImGui::PushID(txt.c_str());
asIScriptContext* scriptContext = asGetActiveContext();
if (scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::Dummy(ImVec2(0, 10));
ImGui::PopID();
ImGui::TreePop();
ImGui::PopStyleVar(2);
return true;
}
ImGui::PopStyleVar(2);
return false;
}
void columns(int i) { ImGui::Columns(i, nullptr, false); }
void automaticColumns(int pixelSize) {
float width = ImGui::GetWindowContentRegionMax().x;
if (width < pixelSize) {
ImGui::Columns();
return;
}
int cols = (int)(width / (pixelSize));
float componentWidth = width / (float)cols;
ImGui::Columns(cols, 0, false);
}
void childWindow(CScriptAny* data, asIScriptFunction* func, int width,
int height, bool border) {}
void endColumns() { ImGui::Columns(); }
void nextColumn() { ImGui::NextColumn(); }
void space() { ImGui::Dummy(ImVec2(10, 10)); }
void space_params(int x, int y) { ImGui::Dummy(ImVec2(x, y)); }
namespace MenuContext {
CScriptAny* payload = nullptr;
std::string menuId;
} // namespace MenuContext
void contextItemPopup(std::string& menu_id, asIScriptFunction* func) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopupContextItem(menu_id.c_str())) {
asIScriptContext* scriptContext = asGetActiveContext();
if (scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
}
void contextMenuPopup(std::string& menu_id, asIScriptFunction* func) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopupContextWindow(menu_id.c_str())) {
asIScriptContext* scriptContext = asGetActiveContext();
if (scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
}
void closePopup() {
if (MenuContext::payload) {
MenuContext::payload->Release();
MenuContext::payload = nullptr;
}
MenuContext::menuId = "";
ImGui::CloseCurrentPopup();
}
void openPopup(std::string& menu_id, CScriptAny* data) {
if (MenuContext::payload) {
MenuContext::payload->Release();
}
data->AddRef();
MenuContext::payload = data;
MenuContext::menuId = menu_id;
}
void modalPopup(std::string& menu_id, asIScriptFunction* func) {
if (!ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopup) &&
MenuContext::menuId == menu_id) {
ImGui::OpenPopup(menu_id.c_str());
MenuContext::menuId = "";
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopupModal(menu_id.c_str())) {
// This should not happen
if (!MenuContext::payload) {
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
ImGui::PopStyleVar();
return;
}
asIScriptContext* scriptContext = asGetActiveContext();
if (scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->SetArgObject(0, MenuContext::payload));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
}
void simplePopup(std::string& menu_id, asIScriptFunction* func) {
if (!ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopup)) {
if (MenuContext::menuId == menu_id) {
ImGui::OpenPopup(menu_id.c_str());
MenuContext::menuId = "";
ImVec2 mouse_pos = ImGui::GetMousePos();
ImVec2 popup_size = ImVec2(200, 0);
ImVec2 popup_pos = ImVec2(mouse_pos.x - popup_size.x * 0.5f, mouse_pos.y);
ImGui::SetNextWindowSize(popup_size);
ImGui::SetNextWindowPos(popup_pos, ImGuiCond_Appearing);
// In the case a payload is loaded we unload it
} else if (MenuContext::payload && MenuContext::menuId == "") {
MenuContext::payload->Release();
MenuContext::payload = nullptr;
}
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopup(menu_id.c_str())) {
// This should not happen
if (!MenuContext::payload) {
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
ImGui::PopStyleVar();
return;
}
asIScriptContext* scriptContext = asGetActiveContext();
if (scriptContext->PushState() == asSUCCESS) {
AS_CHECK(scriptContext->Prepare(func));
AS_CHECK(scriptContext->Execute());
scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
}
} // namespace Scripting
} // namespace Deer } // namespace Deer

View File

@ -0,0 +1,123 @@
#pragma once
#include "DeerRender/FrameBuffer.h"
#include "DeerRender/Texture.h"
#include "glm/glm.hpp"
#include <string>
class asIScriptFunction;
class CScriptAny;
namespace Deer {
namespace Scripting {
namespace DragDropPayload {
extern CScriptAny* payload;
}
// Text & titles
void text(std::string&);
void textCenter(std::string&);
void textEnd(std::string&);
void textColor(float r, float g, float b, std::string& msg);
void title(std::string&);
void titleCenter(std::string&);
void titleEnd(std::string&);
void titleCenterY(std::string&, int);
// Buttons
bool button(std::string&);
bool buttonCenter(std::string&);
bool buttonEnd(std::string&);
bool cartIconButton(const std::string& label, const std::string& icon, int iconSize, int width);
bool cartIconButton_frameBuffer(const std::string& label, Resource<FrameBuffer> frameBuffer, int iconSize, int width);
// Icons
void drawIcon(std::string& iconId, int size);
void drawIconCentered(std::string& iconId, int size);
void drawIconHighlight(std::string& iconId, int size);
void drawIconCenteredHighlight(std::string& iconId, int size);
void drawIcon_resource(Resource<Texture> texture, int size);
void drawIconCentered_resource(Resource<Texture> texture, int size);
void drawIconHighlight_resource(Resource<Texture> texture, int size);
void drawIconCenteredHighlight_resource(Resource<Texture> texture, int size);
int getIconId(const std::string& name);
// Layout & panel
void sameline();
void separator();
void disablePanelPadding(bool);
void space();
void space_params(int x, int y);
int getAvailableSizeX();
int getAvailableSizeY();
bool isPanelActive();
// Input widgets
bool inputText(std::string& label, std::string&, std::string&);
bool checkbox(std::string& label, bool);
bool checkboxDisabled(std::string& label, bool);
float slider(std::string&, float, float, float);
int sliderInt(std::string&, int, int, int);
float magicSlider(std::string&, float, float);
glm::vec3 magicSlider3(std::string&, glm::vec3, float);
// Menus
bool menuItem(std::string&);
void menuItemDisabled(std::string&);
void subMenu(std::string&, asIScriptFunction*);
// Drag & Drop
void dragDropSource(std::string&, CScriptAny*, std::string&);
void dragDropTarget(std::string&, asIScriptFunction*);
// Mouse & keyboard input state
bool isItemClicked(int mouse);
bool isMouseDoubleClicked(int mouse);
bool isMouseDragging(int);
float getMouseDragDeltaX();
float getMouseDragDeltaY();
float getMouseDeltaX();
float getMouseDeltaY();
bool isKeyDown(int);
bool isKeyPressed(int);
// Rendering helpers
void drawFrameBuffer(Resource<FrameBuffer> frameBuffer, int sizeX, int sizeY);
void drawFrameBufferCentered(Resource<FrameBuffer> frameBuffer, int sizeX, int sizeY);
void automaticColumns(int pixelSize);
void columns(int);
void nextColumn();
void endColumns();
bool componentNode(std::string&, asIScriptFunction*);
bool componentNodeContextMenu(std::string&, asIScriptFunction*, asIScriptFunction*);
void treeNodeLeaf(std::string&, bool);
bool treeNode(std::string&, bool, asIScriptFunction&);
void childWindow(CScriptAny*, asIScriptFunction*, int, int, bool);
void space();
void space_params(int, int);
void contextItemPopup(std::string&, asIScriptFunction*);
void contextMenuPopup(std::string&, asIScriptFunction*);
void modalPopup(std::string&, asIScriptFunction*);
void simplePopup(std::string&, asIScriptFunction*);
void openPopup(std::string&, CScriptAny*);
void closePopup();
} // namespace Scripting
} // namespace Deer

View File

@ -1,6 +1,7 @@
#include "DeerRender/ScriptSystem/InternalAPI/Resources.h" #include "DeerRender/Scripting/InternalAPI/Resources.h"
#include "DeerRender/ScriptSystem.h" #include "DeerRender/Scripting.h"
#include "DeerRender/FrameBuffer.h"
#include "DeerRender/Log.h" #include "DeerRender/Log.h"
#include "DeerRender/Tools/Path.h" #include "DeerRender/Tools/Path.h"
@ -11,7 +12,7 @@
#include <string> #include <string>
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
extern asIScriptEngine* scriptEngine; extern asIScriptEngine* scriptEngine;
ResourceType getResourceType(std::string& dir) { ResourceType getResourceType(std::string& dir) {
@ -75,5 +76,26 @@ namespace Deer {
return array; return array;
} }
} // namespace ScriptSystem Resource<FrameBuffer> createFrameBuffer(std::string& name, int width, int height) {
FrameBufferData spec(width, height, 1, FrameBufferData::FrameBufferType::RGBA8);
return ResourceManager<FrameBuffer>::loadResourceFromData(spec, name);
}
int frameBuffer_getWidth(Resource<FrameBuffer>& frameBuffer) {
return frameBuffer.getData().getSpecification().width;
}
int frameBuffer_getHeight(Resource<FrameBuffer>& frameBuffer) {
return frameBuffer.getData().getSpecification().height;
}
void frameBuffer_clearRGBA(int r, int g, int b, int a, Resource<FrameBuffer>& frameBuffer) {
int data[] = {r, g, b, a};
frameBuffer.getData().clearBuffer(0, data);
}
bool frameBuffer_isValid(Resource<FrameBuffer>& frameBuffer) {
return frameBuffer.isValid();
}
void frameBuffer_resize(int x, int y, Resource<FrameBuffer>& frameBuffer) {
frameBuffer.getData().resize(x, y);
}
} // namespace Scripting
} // namespace Deer } // namespace Deer

View File

@ -0,0 +1,52 @@
#pragma once
#include "DeerRender/Resource.h"
#include "scriptarray.h"
#include "scriptdictionary.h"
#include <stdint.h>
#include <string>
#include "DeerRender/Resource.h"
namespace Deer {
class FrameBuffer;
namespace Scripting {
template <typename T>
std::string resource_getPath(Resource<T> resource) {
return ResourceManager<T>::getStorageId(resource);
}
template <typename T>
std::string resource_getName(Resource<T> resource) {
return ResourceManager<T>::getStorageId(resource).stem().string();
}
enum ResourceType : uint32_t {
NONE = 0,
MESH = 1,
SHADER = 2,
TEXTURE = 3,
};
CScriptArray* getResourceFolders(std::string& path);
CScriptArray* getResourceFiles(std::string& path);
// GENERIC RESOURCE
template <typename T>
bool resource_isValid(Resource<T>& resource) { return resource.isValid(); }
template <typename T>
std::string resource_getPath(Resource<T>& resource) { return resource.getStorageId(); }
template <typename T>
std::string resource_getName(Resource<T>& resource) { return Path(resource.getStorageId()).stem().string(); }
// Frame Buffer
int frameBuffer_getWidth(Resource<FrameBuffer>&);
int frameBuffer_getHeight(Resource<FrameBuffer>&);
void frameBuffer_clearRGBA(int, int, int, int, Resource<FrameBuffer>&);
bool frameBuffer_isValid(Resource<FrameBuffer>&);
void frameBuffer_resize(int, int, Resource<FrameBuffer>&);
Resource<FrameBuffer> createFrameBuffer(std::string& name, int sixeX, int sizeY);
} // namespace Scripting
} // namespace Deer

View File

@ -1,7 +1,8 @@
#include "DeerCore/ScriptSystem/Helpers.h" #include "DeerCore/Scripting/Helpers.h"
#include "DeerRender/ScriptSystem.h" #include "DeerRender/Scripting.h"
#include "DeerRender/ScriptSystem/InternalAPI/Resources.h" #include "DeerRender/Scripting/InternalAPI/Resources.h"
#include "DeerRender/FrameBuffer.h"
#include "DeerRender/Mesh.h" #include "DeerRender/Mesh.h"
#include "DeerRender/Resource.h" #include "DeerRender/Resource.h"
#include "DeerRender/Shader.h" #include "DeerRender/Shader.h"
@ -9,7 +10,7 @@
#include "angelscript.h" #include "angelscript.h"
namespace Deer { namespace Deer {
namespace ScriptSystem { namespace Scripting {
extern asIScriptEngine* scriptEngine; extern asIScriptEngine* scriptEngine;
void registerResources(); void registerResources();
@ -19,17 +20,17 @@ namespace Deer {
template <class T> template <class T>
void registerResourceBasics(const char* objName) { void registerResourceBasics(const char* objName) {
REGISTER_OBJECT_METHOD(scriptEngine, objName, "bool isValid() const", Resource<T>, isValid); REGISTER_EXT_OBJECT_METHOD(scriptEngine, objName, "bool isValid() const", static_cast<bool (*)(Resource<T>&)>(&resource_isValid<T>));
REGISTER_OBJECT_METHOD(scriptEngine, objName, "int get_resourceId() const property", Resource<T>, getResourceId); REGISTER_EXT_OBJECT_METHOD(scriptEngine, objName, "string get_name() const property", static_cast<std::string (*)(Resource<T>&)>(&resource_getName<T>));
REGISTER_EXT_OBJECT_METHOD(scriptEngine, objName, "string get_name() const property", resource_getName); REGISTER_EXT_OBJECT_METHOD(scriptEngine, objName, "string get_path() const property", static_cast<std::string (*)(Resource<T>&)>(&resource_getPath<T>));
REGISTER_EXT_OBJECT_METHOD(scriptEngine, objName, "string get_path() const property", resource_getPath);
} }
} // namespace ScriptSystem } // namespace Scripting
void ScriptSystem::registerResourceStructs() { void Scripting::registerResourceStructs() {
AS_CHECK(scriptEngine->RegisterObjectType("GPUMesh", sizeof(Resource<GPUMesh>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<GPUMesh>>())); AS_CHECK(scriptEngine->RegisterObjectType("GPUMesh", sizeof(Resource<GPUMesh>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<GPUMesh>>()));
AS_CHECK(scriptEngine->RegisterObjectType("Shader", sizeof(Resource<Shader>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<Shader>>())); AS_CHECK(scriptEngine->RegisterObjectType("Shader", sizeof(Resource<Shader>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<Shader>>()));
AS_CHECK(scriptEngine->RegisterObjectType("Texture", sizeof(Resource<Texture>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<Texture>>())); AS_CHECK(scriptEngine->RegisterObjectType("Texture", sizeof(Resource<Texture>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<Texture>>()));
AS_CHECK(scriptEngine->RegisterObjectType("FrameBuffer", sizeof(Resource<FrameBuffer>), asOBJ_VALUE | asOBJ_POD | asOBJ_APP_CLASS_ALLINTS | asGetTypeTraits<Resource<FrameBuffer>>()));
scriptEngine->RegisterEnum("ResourceType"); scriptEngine->RegisterEnum("ResourceType");
scriptEngine->RegisterEnumValue("ResourceType", "None", (int)ResourceType::NONE); scriptEngine->RegisterEnumValue("ResourceType", "None", (int)ResourceType::NONE);
@ -37,6 +38,25 @@ namespace Deer {
scriptEngine->RegisterEnumValue("ResourceType", "Shader", (int)ResourceType::SHADER); scriptEngine->RegisterEnumValue("ResourceType", "Shader", (int)ResourceType::SHADER);
scriptEngine->RegisterEnumValue("ResourceType", "Texture", (int)ResourceType::TEXTURE); scriptEngine->RegisterEnumValue("ResourceType", "Texture", (int)ResourceType::TEXTURE);
} }
int frameBuffer_getWidth(Resource<FrameBuffer>&);
int frameBuffer_getHeight(Resource<FrameBuffer>&);
void frameBuffer_clearRGBA(int, int, int, int, Resource<FrameBuffer>&);
bool frameBuffer_isValid(Resource<FrameBuffer>&);
void frameBuffer_resize(int, int, Resource<FrameBuffer>&);
Resource<FrameBuffer> createFrameBuffer(const std::string name, int sixeX, int sizeY);
void Scripting::registerResourceFunctions() {
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "int get_width() const property", frameBuffer_getWidth);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "int get_height() const property", frameBuffer_getHeight);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "bool isValid()", frameBuffer_isValid);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "void resize(int, int)", frameBuffer_resize);
REGISTER_EXT_OBJECT_METHOD(scriptEngine, "FrameBuffer", "void clearRGBA(int, int, int, int)", frameBuffer_clearRGBA);
scriptEngine->SetDefaultNamespace("Resource");
REGISTER_GLOBAL_FUNC(scriptEngine, "FrameBuffer createFrameBuffer(string&in name, int sizeX, int sizeY)", createFrameBuffer);
scriptEngine->SetDefaultNamespace("");
}
/* /*
void ScriptSystem::registerResourceFunctions() { void ScriptSystem::registerResourceFunctions() {
scriptEngine->SetDefaultNamespace("Resource"); scriptEngine->SetDefaultNamespace("Resource");
@ -51,10 +71,12 @@ namespace Deer {
} }
*/ */
void ScriptSystem::registerResources() { void Scripting::registerResources() {
registerResourceStructs(); registerResourceStructs();
registerResourceBasics<GPUMesh>("GPUMesh"); registerResourceBasics<GPUMesh>("GPUMesh");
registerResourceBasics<Shader>("Shader"); registerResourceBasics<Shader>("Shader");
registerResourceBasics<Texture>("Texture"); registerResourceBasics<Texture>("Texture");
registerResourceBasics<FrameBuffer>("FrameBuffer");
registerResourceFunctions();
} }
} // namespace Deer } // namespace Deer

View File

@ -5,7 +5,7 @@
namespace Deer { namespace Deer {
class OpenGLFrameBuffer : public FrameBuffer { class OpenGLFrameBuffer : public FrameBuffer {
public: public:
OpenGLFrameBuffer(const FrameBufferSpecification& frameBufferSpecification); OpenGLFrameBuffer(const FrameBufferSpecification& frameBufferSpecification);
~OpenGLFrameBuffer() override; ~OpenGLFrameBuffer() override;
@ -21,14 +21,15 @@ namespace Deer {
int getTextureBufferPixel(int id, unsigned int x, unsigned int y) override; int getTextureBufferPixel(int id, unsigned int x, unsigned int y) override;
const FrameBufferSpecification& getSpecification() override { return m_specification; } const FrameBufferSpecification& getSpecification() override { return m_specification; }
private:
private:
void invalidate(); void invalidate();
private:
private:
FrameBufferSpecification m_specification; FrameBufferSpecification m_specification;
std::vector<unsigned int> m_colorsAttachments; std::vector<unsigned int> m_colorsAttachments;
unsigned int m_frameBuffer = 0; unsigned int m_frameBuffer = 0;
unsigned int m_depthAttachment = 0; unsigned int m_depthAttachment = 0;
}; };
} } // namespace Deer

View File

@ -1,15 +0,0 @@
#pragma once
#include "DeerRender/ScriptSystem.h"
namespace Deer {
namespace StudioAPI {
extern ScriptSystem::Registry* engineRegistry;
extern ScriptSystem::Registry* uiRegistry;
extern ScriptSystem::Registry* entityRegistry;
extern ScriptSystem::Registry* mathRegistry;
extern ScriptSystem::Registry* resourceRegistry;
void registerStudioAPI();
} // namespace StudioAPI
} // namespace Deer

View File

@ -1,117 +0,0 @@
#pragma once
#include "DeerStudio/StudioAPI/GenericRefStructs.h"
#include "DeerRender/Mesh.h"
#include "DeerRender/Shader.h"
#include "DeerRender/Texture.h"
#include "glm/glm.hpp"
#include <stdint.h>
#include <string>
namespace Deer {
namespace StudioAPI {
struct EntityStruct;
extern EntityStruct activeEntity;
struct EntityStruct : EntityHandleStruct {
EntityStruct(uint16_t entId = 0, int32_t envId = -1);
std::string getName();
void setName(std::string&);
int getId();
bool exists();
bool isRoot();
void destroy();
EntityHandleStruct createChild(std::string&);
void setParent(EntityHandleStruct parent);
EntityHandleStruct getParent();
bool isDescendantOf(EntityHandleStruct parent);
bool opEquals(const EntityHandleStruct& other);
// COMPONENTS
EntityHandleStruct getMeshComponent();
EntityHandleStruct createMeshComponent();
bool hasMeshComponent();
void removeMeshComponent();
EntityHandleStruct getShaderComponent();
EntityHandleStruct createShaderComponent();
bool hasShaderComponent();
void removeShaderComponent();
EntityHandleStruct getCameraComponent();
EntityHandleStruct createCameraComponent();
bool hasCameraComponent();
void removeCameraComponent();
// This function can be adapted to get a specific transform since
// the data is the same
EntityHandleStruct getSelf();
};
struct EntityChildArrayStruct : EntityHandleStruct {
int getChildCount();
EntityHandleStruct getChild(int);
};
struct TransformComponentStruct : EntityHandleStruct {
glm::vec3 getPosition();
glm::vec3 getScale();
glm::vec3 getRotation();
void setPosition(glm::vec3);
void setScale(glm::vec3);
void setRotation(glm::vec3);
};
struct MeshComponentStruct : EntityHandleStruct {
bool isActive();
void setActive(bool);
bool hasMesh();
void clear();
Resource<GPUMesh> getMesh();
void setMesh(Resource<GPUMesh>);
bool assertMeshComponent(const char* funcName);
};
struct ShaderComponentStruct : EntityHandleStruct {
bool hasShader();
void clear();
Resource<Shader> getShader();
void setShader(Resource<Shader>);
Resource<Texture> getTexture();
void setTexture(Resource<Texture>);
bool assertShaderComponent(const char* funcName);
};
struct CameraComponentStruct : EntityHandleStruct {
float getFov();
float getAspectRation();
float getNearZ();
float getFarZ();
void setFov(float);
void setAspectRation(float);
void setNearZ(float);
void setFarZ(float);
bool assertCameraComponent(const char* funcName);
};
EntityHandleStruct getRoot();
void constructEntityStruct(int id, void* memory);
void copyEntityStruct(int id, void* memory);
} // namespace StudioAPI
} // namespace Deer

View File

@ -1,20 +0,0 @@
#pragma once
#include "GenericRefStructs.h"
#include <string>
// #include "DeerRender/World.h"
namespace Deer {
class WorldCamera;
namespace StudioAPI {
struct EntityEnvironmentStruct : EntityEnvironmentHandleStruct {
void render(FrameBufferHandleStruct, WorldCamera&);
EntityHandleStruct getRootEntity();
EntityHandleStruct getEntity(int);
};
EntityEnvironmentHandleStruct getMainEntityEnvironment();
EntityEnvironmentHandleStruct createLoadEntityEnvironment(std::string& envId);
} // namespace StudioAPI
} // namespace Deer

View File

@ -1,30 +0,0 @@
#pragma once
#include "DeerRender/Tools/TypeDefs.h"
namespace Deer {
class EntityEnvironment;
namespace StudioAPI {
struct EntityEnvironmentHandleStruct {
EntityEnvironmentHandleStruct(int32_t _id = -1) : environmentId(_id) {}
int32_t environmentId;
};
struct EntityHandleStruct {
EntityHandleStruct(int _entId = 0, int _envId = -1) : entityId(_entId), environmentId(_envId) {}
int32_t entityId;
int32_t environmentId;
bool assertEntity(const char* funcName);
EntityEnvironment* getEntityEnvironment();
};
struct FrameBufferHandleStruct {
FrameBufferHandleStruct(int _id = 0) : frameBufferId(_id) {}
int32_t frameBufferId = 0;
};
} // namespace StudioAPI
} // namespace Deer

View File

@ -1,33 +0,0 @@
#pragma once
#include <string>
class asIScriptFunction;
class CScriptAny;
namespace Deer {
namespace StudioAPI {
// Set up the colums to fit the pixelSize elements
void automaticColumns(int pixelSize);
// Set up the colums to the number
void columns(int);
// Iterates to the next column
void nextColumn();
// Ends the columns made with columns
void endColumns();
// Renders a component node
bool componentNode(std::string&, asIScriptFunction*);
// Renders a component node with option to menu
bool componentNodeContextMenu(std::string&, asIScriptFunction*, asIScriptFunction*);
// Renders a tree leaf
void treeNodeLeaf(std::string&, bool);
// Renders a tree node with its sub nodes
bool treeNode(std::string&, bool, asIScriptFunction&);
// Data, Call, x, y, border
void childWindow(CScriptAny*, asIScriptFunction*, int, int, bool);
void space();
void space_params(int, int);
} // namespace StudioAPI
} // namespace Deer

View File

@ -1,17 +0,0 @@
#pragma once
#include <string>
class asIScriptFunction;
class CScriptAny;
namespace Deer {
namespace StudioAPI {
void contextItemPopup(std::string&, asIScriptFunction*);
void contextMenuPopup(std::string&, asIScriptFunction*);
void modalPopup(std::string&, asIScriptFunction*);
void simplePopup(std::string&, asIScriptFunction*);
void openPopup(std::string&, CScriptAny*);
void closePopup();
} // namespace StudioAPI
} // namespace Deer

View File

@ -95,5 +95,27 @@ namespace Deer {
void drawFrameBuffer(FrameBufferHandleStruct frameBuffer, int sizeX, int sizeY); void drawFrameBuffer(FrameBufferHandleStruct frameBuffer, int sizeX, int sizeY);
void drawFrameBufferCentered(FrameBufferHandleStruct frameBuffer, int sizeX, int sizeY); void drawFrameBufferCentered(FrameBufferHandleStruct frameBuffer, int sizeX, int sizeY);
void automaticColumns(int pixelSize);
void columns(int);
void nextColumn();
void endColumns();
bool componentNode(std::string&, asIScriptFunction*);
bool componentNodeContextMenu(std::string&, asIScriptFunction*, asIScriptFunction*);
void treeNodeLeaf(std::string&, bool);
bool treeNode(std::string&, bool, asIScriptFunction&);
void childWindow(CScriptAny*, asIScriptFunction*, int, int, bool);
void space();
void space_params(int, int);
void contextItemPopup(std::string&, asIScriptFunction*);
void contextMenuPopup(std::string&, asIScriptFunction*);
void modalPopup(std::string&, asIScriptFunction*);
void simplePopup(std::string&, asIScriptFunction*);
void openPopup(std::string&, CScriptAny*);
void closePopup();
} // namespace StudioAPI } // namespace StudioAPI
} // namespace Deer } // namespace Deer

View File

@ -2,6 +2,7 @@
// #include "DeerStudio/AngelScriptEngine.h" // #include "DeerStudio/AngelScriptEngine.h"
#include "DeerRender/Engine.h" #include "DeerRender/Engine.h"
#include "DeerRender/Scripting.h"
#include "DeerRender/Universe.h" #include "DeerRender/Universe.h"
#include "DeerRender/World.h" #include "DeerRender/World.h"
@ -10,14 +11,15 @@
#include "DeerStudio/Style.h" #include "DeerStudio/Style.h"
// TMP // TMP
#include "DeerStudio/StudioAPI.h"
namespace Deer { namespace Deer {
class FrameBuffer; class FrameBuffer;
namespace DeerStudio { namespace DeerStudio {
Universe::WorldHandle mainWorld; Universe::WorldHandle mainWorld;
Scope<ScriptEnvironment> editorScriptModules;
ScriptObjectGroup* editorInstance;
void onUpdate(); void onUpdate();
void onRender(); void onRender();
void onEvent(Event& e); void onEvent(Event& e);
@ -26,12 +28,27 @@ namespace Deer {
void worldRender(World& world); void worldRender(World& world);
void worldUpdate(World& world); void worldUpdate(World& world);
void initEditorScriptModules() {
Scripting::registerInterface("Panel");
Scripting::registerInterfaceFunction("Panel", "onImGui", Scripting::EventType::void_event);
Scripting::compileFiles("Editor/Scripts", "Editor");
Scripting::SystemDescription systemDescription("Panel", "Editor");
systemDescription.events.push_back(Scripting::SystemEvent("onInit", Scripting::EventType::void_event));
systemDescription.events.push_back(Scripting::SystemEvent("onShutdown", Scripting::EventType::void_event));
systemDescription.events.push_back(Scripting::SystemEvent("onDrawUI", Scripting::EventType::void_event));
systemDescription.events.push_back(Scripting::SystemEvent("onUpdate", Scripting::EventType::void_event));
editorScriptModules = Scripting::createScriptEnvironment(systemDescription);
editorInstance = editorScriptModules->createGroupWithAllSystems();
editorInstance->executeOnGroup_voidEvent(0);
}
void main() { void main() {
Engine::init(); Engine::init();
Engine::setEventCallback(DeerStudio::onEvent); Engine::setEventCallback(DeerStudio::onEvent);
StudioAPI::registerStudioAPI();
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20)); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(20, 20));
initializeFonts(); initializeFonts();
SetupImGuiStyle(); SetupImGuiStyle();
@ -43,15 +60,15 @@ namespace Deer {
.renderFrequency = 144, .renderFrequency = 144,
}; };
mainWorld = Universe::createWorld(worldSettings); initEditorScriptModules();
Universe::getWorld(mainWorld).execute();
mainWorld = Universe::createWorld(worldSettings);
// Universe::getWorld(mainWorld).execute();
StudioAPI::deinitialize();
Engine::shutdown(); Engine::shutdown();
} // namespace DeerStudio } // namespace DeerStudio
void worldUpdate(World& world) { void worldUpdate(World& world) {
StudioAPI::update();
} }
void worldRender(World& world) { void worldRender(World& world) {
@ -104,7 +121,6 @@ namespace Deer {
// TerrainEditor::onImGui(); // TerrainEditor::onImGui();
// viewport_onImGui(); // viewport_onImGui();
StudioAPI::render();
ImGui::End(); ImGui::End();
Engine::endRender(); Engine::endRender();

View File

@ -1,4 +1,6 @@
#include "Fonts.h" #include "Fonts.h"
#include "DeerRender/ImGuiLayer.h"
#include "DeerRender/Tools/Path.h"
namespace Deer { namespace Deer {
ImFont* normalText; ImFont* normalText;
@ -41,8 +43,10 @@ namespace Deer {
io.Fonts->AddFontFromFileTTF(faNPath.generic_string().c_str(), 20, &cfg); io.Fonts->AddFontFromFileTTF(faNPath.generic_string().c_str(), 20, &cfg);
} }
io.Fonts->AddFontFromFileTTF(faPath.generic_string().c_str(), 18); normalText = io.Fonts->AddFontFromFileTTF(faPath.generic_string().c_str(), 18);
io.Fonts->Build(); io.Fonts->Build();
ImGuiLayer::setTextFont(normalText);
ImGuiLayer::setTitleFont(titleText);
} }
} // namespace Deer } // namespace Deer

View File

@ -4,16 +4,16 @@
namespace Deer { namespace Deer {
namespace StudioAPI { namespace StudioAPI {
ScriptSystem::Registry* engineRegistry = nullptr; Scripting::Registry* engineRegistry = nullptr;
ScriptSystem::Registry* uiRegistry = nullptr; Scripting::Registry* uiRegistry = nullptr;
ScriptSystem::Registry* entityRegistry = nullptr; Scripting::Registry* entityRegistry = nullptr;
ScriptSystem::Registry* resourceRegistry = nullptr; Scripting::Registry* resourceRegistry = nullptr;
ScriptSystem::Registry* math = nullptr; Scripting::Registry* math = nullptr;
} // namespace StudioAPI } // namespace StudioAPI
void StudioAPI::registerStudioAPI() { void StudioAPI::registerStudioAPI() {
uiRegistry = ScriptSystem::createRegistry("UI"); uiRegistry = Scripting::createRegistry("UI");
entityRegistry = ScriptSystem::createRegistry("Entity"); entityRegistry = Scripting::createRegistry("Entity");
registerStructs(); registerStructs();
registerFunctions(); registerFunctions();

View File

@ -1,8 +1,8 @@
#include "DeerStudio/StudioAPI/UI.h"
#include "DeerStudio/AngelScriptEngine/AngelScriptRegisters.h" #include "DeerStudio/AngelScriptEngine/AngelScriptRegisters.h"
#include "DeerStudio/StudioAPI/Layout.h" #include "DeerStudio/StudioAPI/Layout.h"
#include "DeerStudio/StudioAPI/Menu.h" #include "DeerStudio/StudioAPI/Menu.h"
#include "DeerStudio/StudioAPI/Resources.h" #include "DeerStudio/StudioAPI/Resources.h"
#include "DeerStudio/StudioAPI/UI.h"
#include "imgui.h" #include "imgui.h"
namespace Deer { namespace Deer {

View File

@ -1,30 +0,0 @@
#include "DeerStudio/StudioAPI/Debug.h"
#include "DeerRender/Log.h"
#include "angelscript.h"
#include "imgui.h"
namespace Deer {
namespace StudioAPI {
void errorCallback_angelscript(const asSMessageInfo* msg, void* param) {
if (msg->type == asMSGTYPE_WARNING) {
DEER_EDITOR_ENGINE_WARN("{0}:{1}:{2}) : {3}", msg->section,
msg->row, msg->col, msg->message);
} else if (msg->type == asMSGTYPE_INFORMATION) {
DEER_EDITOR_ENGINE_INFO("{0}:{1}:{2}) : {3}", msg->section,
msg->row, msg->col, msg->message);
} else if (msg->type == asMSGTYPE_ERROR) {
DEER_EDITOR_ENGINE_ERROR("{0}:{1}:{2}) : {3}", msg->section,
msg->row, msg->col, msg->message);
} else {
DEER_EDITOR_ENGINE_INFO("{0}:{1}:{2}) : {3}", msg->section,
msg->row, msg->col, msg->message);
}
}
void print(std::string& msg) {
DEER_EDITOR_ENGINE_INFO("{0}", msg.c_str());
}
} // namespace StudioAPI
} // namespace Deer

View File

@ -1,39 +0,0 @@
#include "DeerStudio/StudioAPI/Engine.h"
#include "DeerRender/Tools/Path.h"
#include "DeerStudio/AngelScriptEngine.h"
#include "angelscript.h"
#include "scriptarray.h"
#include "scriptstdstring.h"
#include <string>
namespace Deer {
namespace StudioAPI {
std::string getParentPath(std::string& path) {
return Path(path).parent_path().string();
}
std::string getParentPathName(std::string& path) {
return Path(path).parent_path().stem().string();
}
std::string getPathName(std::string& path) {
return Path(path).stem().string();
}
CScriptArray* dividePath_angelscript(std::string& path_s) {
CScriptArray* array = CScriptArray::Create(StudioAPI::arrayStringBaseType);
Path path_p(path_s);
for (const auto& part : path_p) {
std::string s = part.string();
array->Resize(array->GetSize() + 1);
array->SetValue(array->GetSize() - 1, &s);
}
return array;
}
} // namespace StudioAPI
} // namespace Deer

View File

@ -1,558 +0,0 @@
#include "DeerStudio/StudioAPI/Entity.h"
#include "DeerStudio/AngelScriptEngine.h"
#include "DeerRender/Components.h"
#include "DeerRender/Engine.h"
#include "DeerRender/EntityEnviroment.h"
#include "DeerRender/World.h"
#include "DeerRender/Resource.h"
#include <vector>
#define GET_ENV(env) ((env < 0) ? *(Engine::getMainWorld().entityEnvironment.get()) : Deer::Resource<EntityEnvironment>::unsafeFromId(environmentId).getData())
#define GET_ENTITY(env, id) GET_ENV(env).getEntity(id)
#define GET_MESH_COMPONENT(env, id) \
GET_ENV(env).getEntity(id).getComponent<MeshComponent>()
#define GET_SHADER_COMPONENT(env, id) \
GET_ENV(env).getEntity(id).getComponent<ShaderComponent>()
#define GET_CAMERA_COMPONENT(env, id) \
GET_ENV(env).getEntity(id).getComponent<CameraComponent>()
#define ASSERT_ENTITY(func, ret) \
if (!assertEntity(func)) \
ret;
#define ASSERT_MESH_COMPONENT(func, ret) \
if (!assertMeshComponent(func)) \
ret;
#define ASSERT_SHADER_COMPONENT(func, ret) \
if (!assertShaderComponent(func)) \
ret;
#define ASSERT_CAMERA_COMPONENT(func, ret) \
if (!assertCameraComponent(func)) \
ret;
namespace Deer {
namespace StudioAPI {
extern std::vector<Scope<EntityEnvironment>> environments;
EntityHandleStruct getRoot() { return EntityStruct(0); }
void constructEntityStruct(int id, void* memory) {
new (memory) EntityStruct(id);
}
int EntityStruct::getId() { return entityId; }
EntityStruct::EntityStruct(uint16_t _entId, int32_t _envId) : EntityHandleStruct(_entId, _envId) {}
EntityEnvironment* EntityHandleStruct::getEntityEnvironment() {
if (environmentId < 0)
return Engine::getMainWorld().entityEnvironment.get();
return &Resource<EntityEnvironment>::unsafeFromId(environmentId).getData();
}
bool EntityHandleStruct::assertEntity(const char* funcName) {
EntityEnvironment* env = getEntityEnvironment();
if (!env->entityExists(entityId)) {
DEER_EDITOR_ENGINE_ERROR(
"Error, invalid entity calling {0}, entityId : {1}, environmentId : {2}",
funcName, entityId, environmentId);
StudioAPI::raiseError();
return false;
}
return true;
}
std::string EntityStruct::getName() {
ASSERT_ENTITY("getName()", return "NULL");
return ((environmentId < 0) ? *Engine::getMainWorld().entityEnvironment.get() : Deer::Resource<EntityEnvironment>::unsafeFromId(environmentId).getData()).getEntity(entityId).getComponent<TagComponent>().tag;
}
void EntityStruct::setName(std::string& name) {
ASSERT_ENTITY("setName()", return);
GET_ENTITY(environmentId, entityId)
.getComponent<TagComponent>()
.tag = name;
}
void EntityStruct::destroy() {
ASSERT_ENTITY("destroy()", return);
GET_ENTITY(environmentId, entityId).destroy();
}
bool EntityStruct::isRoot() {
ASSERT_ENTITY("isRoot()", return false);
return entityId == 0;
}
bool EntityStruct::exists() {
ASSERT_ENTITY("exists()", return false);
return Engine::getMainWorld().entityEnvironment->entityExists(entityId);
}
void EntityStruct::setParent(EntityHandleStruct parent_struct) {
ASSERT_ENTITY("setParent()", return);
Entity& parent =
GET_ENTITY(parent_struct.environmentId, parent_struct.entityId);
GET_ENTITY(environmentId, entityId).setParent(parent);
}
EntityHandleStruct EntityStruct::getParent() {
ASSERT_ENTITY("getParent()", return *this);
Entity& self = GET_ENTITY(environmentId, entityId);
if (self.isRoot())
return *this;
return EntityStruct(self.getParentId());
}
bool EntityStruct::isDescendantOf(EntityHandleStruct parent_struct) {
ASSERT_ENTITY("isDescendantOf()", return false);
Entity& parent =
GET_ENTITY(parent_struct.environmentId, parent_struct.entityId);
return GET_ENTITY(environmentId, entityId).isDescendantOf(parent);
}
bool EntityStruct::opEquals(const EntityHandleStruct& other) {
ASSERT_ENTITY("opEquals()", return false);
return entityId == other.entityId;
}
EntityHandleStruct EntityStruct::getSelf() {
ASSERT_ENTITY("getSelf()", return *this);
return *this;
}
glm::vec3 TransformComponentStruct::getPosition() {
ASSERT_ENTITY("getPosition()", return glm::vec3());
return GET_ENTITY(environmentId, entityId)
.getComponent<TransformComponent>()
.position;
}
glm::vec3 TransformComponentStruct::getScale() {
ASSERT_ENTITY("getScale()", return glm::vec3());
return GET_ENTITY(environmentId, entityId)
.getComponent<TransformComponent>()
.scale;
}
glm::vec3 TransformComponentStruct::getRotation() {
ASSERT_ENTITY("getRotation()", return glm::vec3());
return GET_ENTITY(environmentId, entityId)
.getComponent<TransformComponent>()
.getEulerAngles();
}
void TransformComponentStruct::setPosition(glm::vec3 value) {
ASSERT_ENTITY("setPosition()", return);
GET_ENTITY(environmentId, entityId)
.getComponent<TransformComponent>()
.position = value;
}
void TransformComponentStruct::setScale(glm::vec3 value) {
ASSERT_ENTITY("setScale()", return);
GET_ENTITY(environmentId, entityId)
.getComponent<TransformComponent>()
.scale = value;
}
void TransformComponentStruct::setRotation(glm::vec3 value) {
ASSERT_ENTITY("setRotation()", return);
GET_ENTITY(environmentId, entityId)
.getComponent<TransformComponent>()
.setEulerAngles(value);
}
int EntityChildArrayStruct::getChildCount() {
ASSERT_ENTITY("getChildCount()", return 0);
return GET_ENTITY(environmentId, entityId)
.getComponent<RelationshipComponent>()
.getChildCount();
}
bool MeshComponentStruct::assertMeshComponent(const char* funcName) {
if (!assertEntity(funcName))
return false;
EntityEnvironment* env;
if (environmentId < 0)
env = Engine::getMainWorld().entityEnvironment.get();
else
env = &Resource<EntityEnvironment>::unsafeFromId(environmentId).getData();
Entity& ent = env->getEntity(entityId);
if (!ent.hasComponent<MeshComponent>()) {
DEER_EDITOR_ENGINE_ERROR(
"Error, calling MeshComponent.{0} entity {1} with id {2} "
"has no MeshComponent",
funcName, ent.getComponent<TagComponent>().tag.c_str(),
entityId);
StudioAPI::raiseError();
return false;
}
return true;
}
EntityHandleStruct EntityChildArrayStruct::getChild(int i) {
ASSERT_ENTITY("getChild()", return *this);
RelationshipComponent& rc =
GET_ENTITY(environmentId, entityId)
.getComponent<RelationshipComponent>();
if (i < 0 || i >= rc.getChildCount()) {
DEER_EDITOR_ENGINE_ERROR(
"Error while executing EntityChild.getChild(..), id {0} is "
"invalid for child count of {1}",
i, rc.getChildCount());
StudioAPI::raiseError();
return EntityStruct(0);
}
return EntityStruct(rc.getChildId(i));
}
EntityHandleStruct EntityStruct::createChild(std::string& name) {
ASSERT_ENTITY("createChild()", return *this);
EntityEnvironment* entityEnv = getEntityEnvironment();
Entity& newEnt = entityEnv->createEntity(name);
Entity& me = GET_ENTITY(environmentId, entityId);
newEnt.setParent(me);
return EntityStruct(newEnt.getId(), environmentId);
}
EntityHandleStruct EntityStruct::getMeshComponent() {
ASSERT_ENTITY("getMeshComponent()", return *this);
Entity& self = GET_ENTITY(environmentId, entityId);
if (!self.hasComponent<MeshComponent>()) {
DEER_CORE_ERROR(
"Error, entity {0} with id {1} does not have MeshComponent",
GET_ENTITY(environmentId, entityId)
.getComponent<TagComponent>()
.tag.c_str(),
entityId);
StudioAPI::raiseError();
}
return *this;
}
EntityHandleStruct EntityStruct::createMeshComponent() {
ASSERT_ENTITY("createMeshComponent()", return *this);
Entity& self = GET_ENTITY(environmentId, entityId);
if (!self.hasComponent<MeshComponent>()) {
self.addComponent<MeshComponent>();
}
return *this;
}
bool EntityStruct::hasMeshComponent() {
ASSERT_ENTITY("hasMeshComponent()", return false);
Entity& self = GET_ENTITY(environmentId, entityId);
return self.hasComponent<MeshComponent>();
}
void EntityStruct::removeMeshComponent() {
ASSERT_ENTITY("removeMeshComponent()", return);
Entity& self = GET_ENTITY(environmentId, entityId);
if (self.hasComponent<MeshComponent>()) {
self.removeComponent<MeshComponent>();
}
}
EntityHandleStruct EntityStruct::getCameraComponent() {
ASSERT_ENTITY("getCameraComponent()", return *this);
Entity& self = GET_ENTITY(environmentId, entityId);
if (!self.hasComponent<CameraComponent>()) {
DEER_CORE_ERROR("Error, entity {0} with id {1} does not have "
"Camera Component",
GET_ENTITY(environmentId, entityId)
.getComponent<TagComponent>()
.tag.c_str(),
entityId);
StudioAPI::raiseError();
}
return *this;
}
EntityHandleStruct EntityStruct::createCameraComponent() {
ASSERT_ENTITY("createCameraComponent()", return *this);
Entity& self = GET_ENTITY(environmentId, entityId);
if (!self.hasComponent<CameraComponent>()) {
self.addComponent<CameraComponent>();
}
return *this;
}
bool EntityStruct::hasCameraComponent() {
ASSERT_ENTITY("hasCameraComponent()", return false);
Entity& self = GET_ENTITY(environmentId, entityId);
return self.hasComponent<CameraComponent>();
}
void EntityStruct::removeCameraComponent() {
ASSERT_ENTITY("removeMeshComponent()", return);
Entity& self = GET_ENTITY(environmentId, entityId);
if (self.hasComponent<CameraComponent>()) {
self.removeComponent<CameraComponent>();
}
}
EntityHandleStruct EntityStruct::getShaderComponent() {
ASSERT_ENTITY("getShaderComponent()", return *this);
Entity& self = GET_ENTITY(environmentId, entityId);
if (!self.hasComponent<ShaderComponent>()) {
DEER_CORE_ERROR("Error, entity {0} with id {1} does not have "
"Shader Component",
GET_ENTITY(environmentId, entityId)
.getComponent<TagComponent>()
.tag.c_str(),
entityId);
StudioAPI::raiseError();
}
return *this;
}
EntityHandleStruct EntityStruct::createShaderComponent() {
ASSERT_ENTITY("createShaderComponent()", return *this);
Entity& self = GET_ENTITY(environmentId, entityId);
if (!self.hasComponent<ShaderComponent>()) {
self.addComponent<ShaderComponent>();
}
return *this;
}
bool EntityStruct::hasShaderComponent() {
ASSERT_ENTITY("hasShaderComponent()", return false);
Entity& self = GET_ENTITY(environmentId, entityId);
return self.hasComponent<ShaderComponent>();
}
void EntityStruct::removeShaderComponent() {
ASSERT_ENTITY("removeShaderComponent()", return);
Entity& self = GET_ENTITY(environmentId, entityId);
if (self.hasComponent<ShaderComponent>()) {
self.removeComponent<ShaderComponent>();
}
}
bool MeshComponentStruct::isActive() {
ASSERT_MESH_COMPONENT("isActive()", return false);
return GET_MESH_COMPONENT(environmentId, entityId).active;
}
void MeshComponentStruct::setActive(bool value) {
ASSERT_MESH_COMPONENT("setActive(bool)", return);
GET_MESH_COMPONENT(environmentId, entityId).active = value;
}
Resource<GPUMesh> MeshComponentStruct::getMesh() {
ASSERT_MESH_COMPONENT("getMesh()", return Resource<GPUMesh>());
return GET_MESH_COMPONENT(environmentId, entityId).mesh;
}
bool MeshComponentStruct::hasMesh() {
ASSERT_MESH_COMPONENT("hasMesh()", return false);
return (bool)GET_MESH_COMPONENT(environmentId, entityId).mesh;
}
void MeshComponentStruct::setMesh(Resource<GPUMesh> mesh) {
ASSERT_MESH_COMPONENT("setMesh()", return);
GET_MESH_COMPONENT(environmentId, entityId).mesh = mesh;
}
void MeshComponentStruct::clear() {
ASSERT_MESH_COMPONENT("clear()", return);
GET_MESH_COMPONENT(environmentId, entityId).mesh = Resource<GPUMesh>();
}
bool ShaderComponentStruct::hasShader() {
ASSERT_ENTITY("hasShader()", return false);
return (bool)GET_SHADER_COMPONENT(environmentId, entityId).shader;
}
bool ShaderComponentStruct::assertShaderComponent(const char* funcName) {
if (!assertEntity(funcName))
return false;
EntityEnvironment* env = getEntityEnvironment();
Entity& ent = env->getEntity(entityId);
if (!ent.hasComponent<ShaderComponent>()) {
DEER_EDITOR_ENGINE_ERROR(
"Error, calling ShaderComponent.{0} entity {1} with id {2} "
"has no ShaderComponent",
funcName, ent.getComponent<TagComponent>().tag.c_str(),
entityId);
StudioAPI::raiseError();
return false;
}
return true;
}
void ShaderComponentStruct::clear() {
ASSERT_SHADER_COMPONENT("clear()", return);
GET_SHADER_COMPONENT(environmentId, entityId).shader = Resource<Shader>();
}
Resource<Shader> ShaderComponentStruct::getShader() {
ASSERT_SHADER_COMPONENT("getShader()", return Resource<Shader>());
return GET_SHADER_COMPONENT(environmentId, entityId).shader;
}
void ShaderComponentStruct::setShader(Resource<Shader> shader) {
ASSERT_SHADER_COMPONENT("setShader()", return);
GET_SHADER_COMPONENT(environmentId, entityId).shader = shader;
}
Resource<Texture> ShaderComponentStruct::getTexture() {
ASSERT_SHADER_COMPONENT("getTexture()", return Resource<Texture>());
return GET_SHADER_COMPONENT(environmentId, entityId).texture;
}
void ShaderComponentStruct::setTexture(Resource<Texture> texture) {
ASSERT_SHADER_COMPONENT("setTexture()", return);
GET_SHADER_COMPONENT(environmentId, entityId).texture = texture;
}
bool CameraComponentStruct::assertCameraComponent(const char* funcName) {
if (!assertEntity(funcName))
return false;
EntityEnvironment* env = getEntityEnvironment();
Entity& ent = env->getEntity(entityId);
if (!ent.hasComponent<CameraComponent>()) {
DEER_EDITOR_ENGINE_ERROR(
"Error, calling CameraComponent.{0} entity {1} with id {2} "
"has no CameraComponent",
funcName, ent.getComponent<TagComponent>().tag.c_str(),
entityId);
StudioAPI::raiseError();
return false;
}
return true;
}
float CameraComponentStruct::getFov() {
ASSERT_CAMERA_COMPONENT("getFov()", return 0);
return GET_CAMERA_COMPONENT(environmentId, entityId).fov / 3.141f *
180.0f;
}
float CameraComponentStruct::getAspectRation() {
ASSERT_CAMERA_COMPONENT("getAspectRation()", return 0);
return GET_CAMERA_COMPONENT(environmentId, entityId).aspect;
}
float CameraComponentStruct::getNearZ() {
ASSERT_CAMERA_COMPONENT("getNearZ()", return 0);
return GET_CAMERA_COMPONENT(environmentId, entityId).nearZ;
}
float CameraComponentStruct::getFarZ() {
ASSERT_CAMERA_COMPONENT("getFarZ()", return 0);
return GET_CAMERA_COMPONENT(environmentId, entityId).farZ;
}
void CameraComponentStruct::setFov(float v) {
ASSERT_CAMERA_COMPONENT("getFarZ()", return);
GET_CAMERA_COMPONENT(environmentId, entityId).fov =
v * 3.141f / 180.0f;
}
void CameraComponentStruct::setAspectRation(float v) {
ASSERT_CAMERA_COMPONENT("setAspectRation()", return);
GET_CAMERA_COMPONENT(environmentId, entityId).aspect = v;
}
void CameraComponentStruct::setNearZ(float v) {
ASSERT_CAMERA_COMPONENT("setNearZ()", return);
GET_CAMERA_COMPONENT(environmentId, entityId).nearZ = v;
}
void CameraComponentStruct::setFarZ(float v) {
ASSERT_CAMERA_COMPONENT("setFarZ()", return);
GET_CAMERA_COMPONENT(environmentId, entityId).farZ = v;
}
} // namespace StudioAPI
} // namespace Deer

View File

@ -1,174 +0,0 @@
#include "DeerStudio/StudioAPI/Layout.h"
#include "DeerStudio/AngelScriptEngine.h"
#include "DeerStudio/AngelScriptEngine/ErrorHandle.h"
#include "angelscript.h"
#include "imgui.h"
#include "scriptany.h"
namespace Deer {
namespace StudioAPI {
void treeNodeLeaf(std::string& txt, bool active) {
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_Leaf |
ImGuiTreeNodeFlags_NoTreePushOnOpen |
ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_Bullet |
ImGuiTreeNodeFlags_DrawLinesToNodes;
if (active)
flags |= ImGuiTreeNodeFlags_Selected;
ImGui::TreeNodeEx(txt.c_str(), flags);
}
bool treeNode(std::string& txt, bool active, asIScriptFunction& func) {
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnDoubleClick |
ImGuiTreeNodeFlags_OpenOnArrow |
ImGuiTreeNodeFlags_SpanFullWidth |
ImGuiTreeNodeFlags_DefaultOpen |
ImGuiTreeNodeFlags_DrawLinesToNodes;
if (active)
flags |= ImGuiTreeNodeFlags_Selected;
if (ImGui::TreeNodeEx(txt.c_str(), flags)) {
ImGui::PushID(txt.c_str());
if (StudioAPI::scriptContext && StudioAPI::scriptContext->PushState() == asSUCCESS) {
AS_CHECK_ADDITIONAL_INFO(StudioAPI::scriptContext->Prepare(&func), func.GetDeclaration());
AS_CHECK_ADDITIONAL_INFO(StudioAPI::scriptContext->Execute(), func.GetDeclaration());
StudioAPI::scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::PopID();
ImGui::TreePop();
ImGui::PopStyleVar();
return true;
}
ImGui::PopStyleVar();
return false;
}
bool componentNode(std::string& txt, asIScriptFunction* func) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_SpanAvailWidth |
ImGuiTreeNodeFlags_Framed |
ImGuiTreeNodeFlags_AllowOverlap |
ImGuiTreeNodeFlags_FramePadding |
ImGuiTreeNodeFlags_DefaultOpen;
if (ImGui::TreeNodeEx(txt.c_str(), flags)) {
ImGui::Dummy(ImVec2(0, 10));
ImGui::PushID(txt.c_str());
if (StudioAPI::scriptContext &&
StudioAPI::scriptContext->PushState() == asSUCCESS) {
AS_CHECK(StudioAPI::scriptContext->Prepare(func));
AS_CHECK(StudioAPI::scriptContext->Execute());
StudioAPI::scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::Dummy(ImVec2(0, 10));
ImGui::PopID();
ImGui::TreePop();
ImGui::PopStyleVar(2);
return true;
}
ImGui::PopStyleVar(2);
return false;
}
bool componentNodeContextMenu(std::string& txt, asIScriptFunction* func, asIScriptFunction* menu) {
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(4, 4));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0));
ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_SpanAvailWidth |
ImGuiTreeNodeFlags_Framed |
ImGuiTreeNodeFlags_AllowOverlap |
ImGuiTreeNodeFlags_FramePadding |
ImGuiTreeNodeFlags_DefaultOpen;
if (ImGui::TreeNodeEx(txt.c_str(), flags)) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,
ImVec2(10, 10));
if (ImGui::BeginPopupContextItem(txt.c_str())) {
if (StudioAPI::scriptContext &&
StudioAPI::scriptContext->PushState() == asSUCCESS) {
AS_CHECK(StudioAPI::scriptContext->Prepare(menu));
AS_CHECK(StudioAPI::scriptContext->Execute());
StudioAPI::scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
ImGui::Dummy(ImVec2(0, 10));
ImGui::PushID(txt.c_str());
if (StudioAPI::scriptContext &&
StudioAPI::scriptContext->PushState() == asSUCCESS) {
AS_CHECK(StudioAPI::scriptContext->Prepare(func));
AS_CHECK(StudioAPI::scriptContext->Execute());
StudioAPI::scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::Dummy(ImVec2(0, 10));
ImGui::PopID();
ImGui::TreePop();
ImGui::PopStyleVar(2);
return true;
}
ImGui::PopStyleVar(2);
return false;
}
void columns(int i) { ImGui::Columns(i, nullptr, false); }
void automaticColumns(int pixelSize) {
float width = ImGui::GetWindowContentRegionMax().x;
if (width < pixelSize) {
ImGui::Columns();
return;
}
int cols = (int)(width / (pixelSize));
float componentWidth = width / (float)cols;
ImGui::Columns(cols, 0, false);
}
void childWindow(CScriptAny* data, asIScriptFunction* func, int width,
int height, bool border) {}
void endColumns() { ImGui::Columns(); }
void nextColumn() { ImGui::NextColumn(); }
void space() { ImGui::Dummy(ImVec2(10, 10)); }
void space_params(int x, int y) { ImGui::Dummy(ImVec2(x, y)); }
} // namespace StudioAPI
} // namespace Deer

View File

@ -1,57 +0,0 @@
#include "DeerStudio/StudioAPI/Math.h"
#include "glm/glm.hpp"
namespace Deer {
namespace StudioAPI {
void vec3_constructor(void* mem) { new (mem) glm::vec3(0, 0, 0); }
void vec3_constructor_params(float x, float y, float z, void* mem) {
new (mem) glm::vec3(x, y, z);
}
glm::vec3 vec3_add(glm::vec3& value, glm::vec3& self) {
return self + value;
}
glm::vec3 vec3_sub(const glm::vec3& value, glm::vec3& self) {
return self - value;
}
glm::vec3 vec3_neg(glm::vec3& self) { return -self; }
glm::vec3 vec3_mult(float value, glm::vec3& self) {
return self * value;
}
void quat_construct(glm::quat* mem) { new (mem) glm::quat(); }
void quat_copyConstruct(glm::quat* data, glm::quat* mem) {
new (mem) glm::quat(*data);
}
void quat_destruct(glm::quat* mem) {}
void quat_constructFromValue(float x, float y, float z, float w,
glm::quat* mem) {
new (mem) glm::quat(x, y, z, w);
}
glm::vec3 quat_getEuler(glm::quat* mem) {
return glm::degrees(glm::eulerAngles(*mem));
}
void quat_setEuler(glm::vec3 euler, glm::quat* mem) {
new (mem) glm::quat(glm::radians(euler));
}
glm::quat quat_multiply(glm::quat* data, glm::quat* mem) {
return *mem * *data;
}
glm::vec3 transform_relative(glm::vec3 pos,
TransformComponent* transform) {
return transform->getMatrix() * glm::vec4(pos, 1.0f);
}
void transform_construct(TransformComponent* mem) {
new (mem) TransformComponent();
}
void camera_construct(CameraComponent* mem) {
new (mem) CameraComponent();
}
void sceneCamera_Construct(WorldCamera* mem) {
new (mem) WorldCamera();
}
} // namespace StudioAPI
} // namespace Deer

View File

@ -1,158 +0,0 @@
#include "DeerStudio/StudioAPI/Menu.h"
#include "angelscript.h"
#include "imgui.h"
#include "scriptany.h"
#include "DeerStudio/AngelScriptEngine.h"
#include "DeerStudio/AngelScriptEngine/ErrorHandle.h"
namespace Deer {
namespace StudioAPI {
namespace MenuContext {
CScriptAny* payload = nullptr;
std::string menuId;
} // namespace MenuContext
void contextItemPopup(std::string& menu_id, asIScriptFunction* func) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopupContextItem(menu_id.c_str())) {
if (StudioAPI::scriptContext &&
StudioAPI::scriptContext->PushState() == asSUCCESS) {
AS_CHECK(StudioAPI::scriptContext->Prepare(func));
AS_CHECK(StudioAPI::scriptContext->Execute());
StudioAPI::scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
}
void contextMenuPopup(std::string& menu_id, asIScriptFunction* func) {
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopupContextWindow(menu_id.c_str())) {
if (StudioAPI::scriptContext &&
StudioAPI::scriptContext->PushState() == asSUCCESS) {
AS_CHECK(StudioAPI::scriptContext->Prepare(func));
AS_CHECK(StudioAPI::scriptContext->Execute());
StudioAPI::scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
}
void closePopup() {
if (MenuContext::payload) {
MenuContext::payload->Release();
MenuContext::payload = nullptr;
}
MenuContext::menuId = "";
ImGui::CloseCurrentPopup();
}
void openPopup(std::string& menu_id, CScriptAny* data) {
if (MenuContext::payload) {
MenuContext::payload->Release();
}
data->AddRef();
MenuContext::payload = data;
MenuContext::menuId = menu_id;
}
void modalPopup(std::string& menu_id, asIScriptFunction* func) {
if (!ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopup) &&
MenuContext::menuId == menu_id) {
ImGui::OpenPopup(menu_id.c_str());
MenuContext::menuId = "";
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopupModal(menu_id.c_str())) {
// This should not happen
if (!MenuContext::payload) {
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
ImGui::PopStyleVar();
return;
}
if (StudioAPI::scriptContext &&
StudioAPI::scriptContext->PushState() == asSUCCESS) {
AS_CHECK(StudioAPI::scriptContext->Prepare(func));
AS_CHECK(StudioAPI::scriptContext->SetArgObject(
0, MenuContext::payload));
AS_CHECK(StudioAPI::scriptContext->Execute());
StudioAPI::scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
}
void simplePopup(std::string& menu_id, asIScriptFunction* func) {
if (!ImGui::IsPopupOpen("", ImGuiPopupFlags_AnyPopup)) {
if (MenuContext::menuId == menu_id) {
ImGui::OpenPopup(menu_id.c_str());
MenuContext::menuId = "";
ImVec2 mouse_pos = ImGui::GetMousePos();
ImVec2 popup_size = ImVec2(200, 0);
ImVec2 popup_pos =
ImVec2(mouse_pos.x - popup_size.x * 0.5f, mouse_pos.y);
ImGui::SetNextWindowSize(popup_size);
ImGui::SetNextWindowPos(popup_pos, ImGuiCond_Appearing);
// In the case a payload is loaded we unload it
} else if (MenuContext::payload && MenuContext::menuId == "") {
MenuContext::payload->Release();
MenuContext::payload = nullptr;
}
}
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(10, 10));
if (ImGui::BeginPopup(menu_id.c_str())) {
// This should not happen
if (!MenuContext::payload) {
ImGui::CloseCurrentPopup();
ImGui::EndPopup();
ImGui::PopStyleVar();
return;
}
if (StudioAPI::scriptContext &&
StudioAPI::scriptContext->PushState() == asSUCCESS) {
AS_CHECK(StudioAPI::scriptContext->Prepare(func));
AS_CHECK(StudioAPI::scriptContext->Execute());
StudioAPI::scriptContext->PopState();
} else {
ImGui::Text("Something failed");
}
ImGui::EndPopup();
}
ImGui::PopStyleVar();
}
} // namespace StudioAPI
} // namespace Deer