Josh Posted November 21, 2016 Share Posted November 21, 2016 I'm tentatively thinking about including an extendable class like this: #pragma once #include "../Leadwerks.h" namespace Leadwerks { class Actor : public Object { public: Entity* entity; Actor(); virtual ~Actor(); virtual void Collision(Entity* entity, const Vec3& position, const Vec3& normal, float speed); virtual void UpdateWorld() virtual void UpdatePhysics() virtual void UpdateMatrix() virtual void Draw() virtual void DrawEach(Camera* camera) } } You would declare your own class derived from the Leadwerks actor class, and set an entity's actor to your object. The engine would then call your object's methods at various points in the program. (The default functions declared above would just be empty functions that don't do anything.) #pragma once #include "../MyGame.h" namespace MyGame { class MyActor : public Actor { public: virtual void UpdatePhysics() } } The hooks system will not be removed, but the recommended way of interfacing with entities in C++ would be through this method. Thoughts? 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted November 21, 2016 Author Share Posted November 21, 2016 A clever way of disabling calls to methods the user does not declare in their derived class would be to store a Boolean member for whether each function should be used. For example, useCollisionMethod. useCollisionMethod = true; The default function could then deactivate this function the first time it is run: void CollisionHook(Entity* entity, const Vec3& position, const Vec3& normal, float speed) { useCollisionMethod = false; } Next time a collision occurs, the engine will see that the useCollisionMethod member is false, and skip the function call. Your function would override the one above, ensuring that it continues to be called. So you wouldn't actually need to know about this at all, but I thought it was cool. Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
aiaf Posted November 21, 2016 Share Posted November 21, 2016 This looks good to me. Quote I made this with Leadwerks/UAK: Structura | Stacky Desktop Edition Website: Binary Station Link to comment Share on other sites More sharing options...
Josh Posted November 23, 2016 Author Share Posted November 23, 2016 This is available in the beta branch now. UpdatePhysics, UpdateWorld, and PostRender functions will not work right now. The other functions will work. This is experimental. Please let me know if you use it and tell me how it works for you. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
reepblue Posted November 23, 2016 Share Posted November 23, 2016 I wrote something like this for Crawler's Den. I'm waiting for C++ actor support with the editor. Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Josh Posted December 13, 2016 Author Share Posted December 13, 2016 This example will work with the 4.2 beta and demonstrates the use of the base actor class to create a derived class and add your own behavior, without using callbacks. actor.zip 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
reepblue Posted December 13, 2016 Share Posted December 13, 2016 Are all the functions working now? What's your plan for integrating actors with the editor? Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Josh Posted December 13, 2016 Author Share Posted December 13, 2016 This works right now, but is not official and may change. The UpdateWorld, PostRender, and UpdatePhysics functions will not get called at this time. My plan is to let people play with this some more and then listen to what they need in the editor, as they use this. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
reepblue Posted December 13, 2016 Share Posted December 13, 2016 Alright, sounds understandable. It's not too hard to do a hook to get those functions working again. Thanks for answering, just wanted to know if there was any improvement since the 22nd. Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
reepblue Posted December 18, 2016 Share Posted December 18, 2016 I just put it together; can't say I tested it, but this chunk of code is how my Puppeteer class worked. This class derives from the actor class so that the update and post render functions update. BaseActor.h // Temp Actor class until the offical one gets improved. #if !defined(BASEACTOR_H) #define BASEACTOR_H #pragma once #include "Leadwerks.h" namespace Leadwerks { class BaseActor : public Actor { BaseActor(); virtual ~BaseActor(); virtual void Attach(); virtual void Detach(); // Hooks that are not working with actors in 4.2 virtual void UpdateWorld() {}; virtual void UpdatePhysics() {}; virtual void PostRender(Leadwerks::Context* context) {}; protected: static void PostRenderHook(Entity* entity); static void UpdatePhysicsHook(Entity* entity); static void UpdateWorldHook(Entity* entity); }; } #endif BaseActor.cpp // Temp Actor class until the offical one gets improved. #include "BaseActor.h" namespace Leadwerks { BaseActor::BaseActor() : Actor() {}; BaseActor::~BaseActor(){}; void BaseActor::Attach() { Actor::Attach(); entity->AddHook(Entity::PostRenderHook, (void*)PostRenderHook); entity->AddHook(Entity::UpdatePhysicsHook, (void*)UpdatePhysicsHook); entity->AddHook(Entity::UpdateWorldHook, (void*)UpdateWorldHook); } void BaseActor::Detach() { entity->RemoveHook(Entity::PostRenderHook, (void*)PostRenderHook); entity->RemoveHook(Entity::UpdatePhysicsHook, (void*)UpdatePhysicsHook); entity->RemoveHook(Entity::UpdateWorldHook, (void*)UpdateWorldHook); Actor::Detach(); } void BaseActor::PostRenderHook(Entity* entity) { BaseActor* script = (BaseActor*)entity->GetUserData(); Leadwerks::Context* context = Leadwerks::Context::GetCurrent(); if (script != nullptr) { script->PostRender(context); } } void BaseActor::UpdatePhysicsHook(Entity* entity) { BaseActor* script = (BaseActor*)entity->GetUserData(); if (script != nullptr) { script->UpdatePhysics(); } } void BaseActor::UpdateWorldHook(Entity* entity) { BaseActor* script = (BaseActor*)entity->GetUserData(); if (script != nullptr) { script->UpdateWorld(); } } } You may need to static cast your Actors based off this when you go to attach the actor to the entity with Entity->SetActor(). 1 Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
reepblue Posted December 18, 2016 Share Posted December 18, 2016 Seem to be getting crashes when I clear the world. I thought it was because the hooks were not being detached before the actor was, but I disabled my additional hooks and I'm getting the same crash. Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Josh Posted December 18, 2016 Author Share Posted December 18, 2016 Try removing these calls: Actor::Attach(); Actor::Detach(); Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
reepblue Posted December 19, 2016 Share Posted December 19, 2016 Still no dice. I got my custom Actor Class to work tho. There seems to be an issue with Detach. When CUSTOM_ACTOR is defined, everything works like expected. (Fully custom class based on hooks) vs the class derived from the stock Actor Class. Header: // Temp Actor class until the offical one gets improved. #if !defined(BASEACTOR_H) #define BASEACTOR_H #pragma once #include "Leadwerks.h" #define CUSTOM_ACTOR namespace Leadwerks { #ifdef CUSTOM_ACTOR class BaseActor : public Object { public: Entity* entity; BaseActor() {}; virtual ~BaseActor(); virtual void Attach(); void RemoveHooks(); virtual void Detach(); void Shutdown() { Detach(); }; virtual void Collision(Entity* pEntity, float* position, float* normal, float speed) {}; virtual void UpdateWorld() {}; virtual void UpdatePhysics() {}; virtual void UpdateMatrix() {}; virtual void PostRender(Context* context) {}; virtual void Draw() {}; virtual void DrawEach(Camera* camera) {}; protected: static void CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed); static void DrawHook(Entity* entity); static void DrawEachHook(Entity* entity); static void PostRenderHook(Entity* entity); static void UpdateMatrixHook(Entity* entity); static void UpdatePhysicsHook(Entity* entity); static void UpdateWorldHook(Entity* entity); }; inline void AttachEntityToActor(Entity* entity, BaseActor* actor) { actor->entity = entity; actor->Attach(); } inline void DetachEntityFromActor(Entity* entity) { if (entity->GetUserData() != NULL) { BaseActor* actor = (BaseActor*)entity->GetUserData(); actor->RemoveHooks(); delete actor; } } bool DetachAllActors(); #else class BaseActor : public Actor { public: BaseActor(); virtual ~BaseActor(); virtual void Attach(); virtual void Detach(); void AddHooks(); void RemoveHooks(); // Hooks that are not working with actors in 4.2 virtual void UpdateWorld() {}; virtual void UpdatePhysics() {}; virtual void PostRender(Leadwerks::Context* context) {}; protected: static void PostRenderHook(Entity* entity); static void UpdatePhysicsHook(Entity* entity); static void UpdateWorldHook(Entity* entity); }; #endif } #endif CPP: // Temp Actor class until the offical one gets improved. #include "BaseActor.h" std::vector<Leadwerks::BaseActor*> vActors; namespace Leadwerks { #ifdef CUSTOM_ACTOR bool DetachAllActors() { if (vActors.size() <= 0) return false; // Come back to this later... for (auto actor : vActors) { actor->Shutdown(); } vActors.clear(); return true; } void BaseActor::Attach() { if (entity == nullptr) { return; } entity->SetUserData((void*)this); entity->AddHook(Entity::CollisionHook, (void*)CollisionHook); entity->AddHook(Entity::DrawHook, (void*)DrawHook); entity->AddHook(Entity::DrawEachHook, (void*)DrawEachHook); entity->AddHook(Entity::PostRenderHook, (void*)PostRenderHook); entity->AddHook(Entity::UpdateMatrixHook, (void*)UpdateMatrixHook); entity->AddHook(Entity::UpdatePhysicsHook, (void*)UpdatePhysicsHook); entity->AddHook(Entity::UpdateWorldHook, (void*)UpdateWorldHook); vActors.push_back((BaseActor*)this); } void BaseActor::RemoveHooks() { if (entity == nullptr) { return; } entity->RemoveHook(Entity::CollisionHook, (void*)CollisionHook); entity->RemoveHook(Entity::DrawHook, (void*)DrawHook); entity->RemoveHook(Entity::DrawEachHook, (void*)DrawEachHook); entity->RemoveHook(Entity::PostRenderHook, (void*)PostRenderHook); entity->RemoveHook(Entity::UpdateMatrixHook, (void*)UpdateMatrixHook); entity->RemoveHook(Entity::UpdatePhysicsHook, (void*)UpdatePhysicsHook); entity->RemoveHook(Entity::UpdateWorldHook, (void*)UpdateWorldHook); entity->SetUserData(NULL); } BaseActor::~BaseActor() { //RemoveHooks(); } void BaseActor::Detach() { System::Print("Puppeteer: Detach() was called."); RemoveHooks(); delete this; } void BaseActor::CollisionHook(Entity* entity0, Entity* entity1, float* position, float* normal, float speed) { BaseActor* actor = (BaseActor*)entity0->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { actor->Collision(entity1, position, normal, speed); } } void BaseActor::DrawHook(Entity* entity) { BaseActor* actor = (BaseActor*)entity->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { //actor->Draw(WORLD->); } } void BaseActor::DrawEachHook(Entity* entity) { BaseActor* actor = (BaseActor*)entity->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { //actor->DrawEach(); } } void BaseActor::PostRenderHook(Entity* entity) { BaseActor* actor = (BaseActor*)entity->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { actor->PostRender(Leadwerks::Context::GetCurrent()); } } void BaseActor::UpdateMatrixHook(Entity* entity) { BaseActor* actor = (BaseActor*)entity->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { actor->UpdateMatrix(); } } void BaseActor::UpdatePhysicsHook(Entity* entity) { BaseActor* actor = (BaseActor*)entity->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { actor->UpdatePhysics(); } } void BaseActor::UpdateWorldHook(Entity* entity) { BaseActor* actor = (BaseActor*)entity->GetUserData(); if (actor->entity == nullptr) { return; } if (actor != NULL) { actor->UpdateWorld(); } } #else BaseActor::BaseActor() : Actor() {}; BaseActor::~BaseActor() {}; void BaseActor::Attach() { AddHooks(); } void BaseActor::Detach() { RemoveHooks(); } void BaseActor::AddHooks() { entity->AddHook(Entity::PostRenderHook, (void*)PostRenderHook); entity->AddHook(Entity::UpdatePhysicsHook, (void*)UpdatePhysicsHook); entity->AddHook(Entity::UpdateWorldHook, (void*)UpdateWorldHook); } void BaseActor::RemoveHooks() { entity->RemoveHook(Entity::PostRenderHook, (void*)PostRenderHook); entity->RemoveHook(Entity::UpdatePhysicsHook, (void*)UpdatePhysicsHook); entity->RemoveHook(Entity::UpdateWorldHook, (void*)UpdateWorldHook); } void BaseActor::PostRenderHook(Entity* entity) { BaseActor* script = (BaseActor*)entity->GetUserData(); Leadwerks::Context* context = Leadwerks::Context::GetCurrent(); if (script != nullptr) { script->PostRender(context); } } void BaseActor::UpdatePhysicsHook(Entity* entity) { BaseActor* script = (BaseActor*)entity->GetActor(); if (script != nullptr) { script->UpdatePhysics(); } } void BaseActor::UpdateWorldHook(Entity* entity) { BaseActor* script = (BaseActor*)entity->GetActor(); if (script != nullptr) { script->UpdateWorld(); } } #endif } Only gotcha with mine is that I need to call this command before clearing/releasing the world. Leadwerks::DetachAllActors(); Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Josh Posted January 13, 2017 Author Share Posted January 13, 2017 A new function is being added to this class: virtual void EndAnimation(const int sequence) This will be called when a one-shot PlayAnimation call reaches the end of the sequence. Support for UpdateWorld, UpdatePhysics, and PostRender calls is being added as well. 1 Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
Josh Posted January 28, 2017 Author Share Posted January 28, 2017 This should be fully functional now. Is anyone using this? Quote My job is to make tools you love, with the features you want, and performance you can't live without. Link to comment Share on other sites More sharing options...
reepblue Posted March 7, 2017 Share Posted March 7, 2017 This should be fully functional now. Is anyone using this? Splendid. Came back here for my Base Actor Class for a C++ player. I'll let you know how it works out! Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
reepblue Posted March 10, 2017 Share Posted March 10, 2017 Assigning an actor to an entity during or after level load causes crashing. CPP: #pragma once #include "ActorFactory.h" /* #include #include #include */ #include "../../Game/SimpleActor.h" namespace Leadwerks { void ActorFactory::AssignEntityToActor(Entity* entity, string actorname) { if (actorname == "actor_test") { SimpleActor* a = new SimpleActor; if (entity != NULL) { entity->SetActor(a); } } } /* Actor* TestCreate(vector parameters) { Actor* b = new Actor; return b; } */ } Header: #pragma once #include "Leadwerks.h" namespace Leadwerks { class Actor; class Entity; class ActorFactory : public Object//lua { public: //static void AssignNameToActor(string pName, Actor* actorclass); static void AssignEntityToActor(Entity* entity, string actorname);//lua private: ActorFactory() {}; ~ActorFactory() {}; }; } What I was trying to do was a system in which I'd register all my actors to a map, but this simple function is causing issues... Quote Cyclone - Ultra Game System - Component Preprocessor - Tex2TGA - Darkness Awaits Template (Leadwerks) If you like my work, consider supporting me on Patreon! Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.