-
Posts
7,936 -
Joined
-
Last visited
Content Type
Blogs
Forums
Store
Gallery
Videos
Downloads
Everything posted by Rick
-
A short video showing and explaining how I did things.
-
"This of course may not fit with the programming model you're trying to create, in which case probably the best way to ensure someone can't break your program by trying to do things on deleted objects is to perform additional checks internally (inside your bound methods, etc.) to make sure your shared pointer is still holding a valid pointer." This is what I was saying before about doing the if statement in all commands on the LE side so things don't crash. Probably a good idea anyway to avoid crashing. However, it sounds like that other guy had a fix in mind but had to go to class. Hope he provides it as it sounds like a bug he's been aware of. Why would it affect the entire script? That instance of the entire script should be dead at the point of deletion anyway right? I mean internally you're creating an entity object and a script object separately right? Then assigning the script object to a member of the entity? Or is the script object stored inside the entity and then yes deleting the entity should cause the script to be deleted in the destructor of the entity I would think?
-
1.000000, 2.000000, 3.000000 69.000000, 2.000000, 3.000000 69.000000, 2.000000, 3.000000 If I use System:Print().
-
What's the negative aspect of the first part of what you said? I would think because the C++ side is deleting things the Lua side isn't going to know about it so the lua variable won't be nil, which is why I was thinking the Exist() function is needed because it would do the if(shared_ptr) check in C++ which should correctly show it's no longer valid.
-
What do you mean by saying lua holds onto the invalid pointer? Do you mean that the lua variable doesn’t turn nil after Delete is called? I wouldn’t think it would given that lua variable is a shared pointer right? However if there was an Exists(obj) function that checked the lua shared ptr was valid and returns true or false then if we know a lua variable might be shared in our code like in the tower defense situation where 2 towers point to same obj then we use that Exists() to see if it’s actually valid on the c++ side
-
Correct, but when crossing language domains (C++/LUA) we can't set it to equal nullptr in lua directly like we can in C++. That's the entire point of my post. There is now a way to do that with the Delete() example I showed. That was why I showed it. Lua now has a way to be equal to C++ in the removal of the object vs hiding or even calling garbage collecting manually, both which are pretty hacky for when you want an object gone given you don't do that from C++ to remove the object.
-
But the above is saying if I asked you if you know German you're saying no I don't. The if statement check. Even though you really do, that check says you don't. However, as in our example with the Test class, the language is actually gone (and error happens when we try to access it's function because the memory doesn't seem to be there anymore). So why is the if check acting as it doesn't exist anymore which in the case of the Test() class shared_ptr it doesn't, but in this string case it does. You should always use the if check before trying to access a shared_ptr right? That's the benefit, that you can tell if it's valid or not anymore where straight pointers you can't.
-
You may want to check that with any of the stuff you're currently doing as well. The following won't print because ptr doesn't pass the if check and count is 0 after the reset(). Perhaps some difference between objects and the string class? I mean you've seen it work with objects which you're creating in the engine, but this is a different usage with whatever string is doing behind the scenes. Or perhaps make_shared()? shared_ptr<std::string> ptr = make_shared <std::string>("Hello."); auto a = ptr; long count = ptr.use_count(); ptr.reset(); count = ptr.use_count(); if(ptr) cout << *(a.get());
-
From my testing reset() actually removes all references. void Delete(shared_ptr<Test>& obj) { long count = obj.use_count(); // will show 2 obj.reset(); count = obj.use_count(); // will show 0 } int main(){ shared_ptr<Test> sptr(new Test("Test")); shared_ptr<Test> ptr = sptr; Delete(sptr); //sptr = nullptr; sptr.get()->Print(); int input; cin >> input; return 0; } Note the key is passing the shared_ptr by reference to the Delete() function. So you'd probably need 2 functions. The lua one we call that gets the shared pointer object we passed in and then another that takes the object by reference. This would be the case IF we can't pass by reference from lua. Not sure if that works with the bindings or not. If it does then great, only need the 1 delete.
-
I think this is how you'd do it. #include <memory> #include <string> #include <iostream> using namespace std; class Test{ private: string name; public: Test(string _name){ name = _name; } void Print(){ cout << name; } }; void Delete(shared_ptr<Test>& obj) { obj.reset(); } int main(){ shared_ptr<Test> sptr(new Test("Test")); Delete(sptr); //sptr = nullptr; sptr.get()->Print(); int input; cin >> input; return 0; } You can do an if(sptr) before trying to anything with it and that still works to make sure it's valid. If you do that on the C++ side for every command then in lua it'll never fail if we have multiple variables pointing to the one we deleted. The calls simply won't do anything, but at least they won't fail. You could make another function we can check perhaps like Exists(obj) that does the if statement on the shared_ptr and if not return false else return true? Just thinking high level on that one in case we want to know on the lua side if something was deleted.
-
And a weak pointer fails to exist when the last variable that points to it sets it to nullptr?
-
I would assume you can make a global function that does the exact same thing as setting to nullptr. Delete(box); This way both lua and C++ can do the same thing. It's literally exactly the same thing just a more consistent interface between the 2 languages.
-
I get that's the case, but I'm trying to help find a consistent interface for this between the 2 languages because I think that's a better design and has value. You could make a global DeleteEntity(e) function perhaps that does that for both C++ objects and Lua objects so people just have to know 1 thing between the 2 languages and documentation can be shared to explain it between the 2 languages.
-
The lua object is just a reference to C++ object right? Couldn't the C++ Delete() function delete itself? It's been awhile since I've used C++ but you could do: class Entity{ void Delete(Entity* e){ e = nullptr; } } // whatever the smartpointer syntax is Entity* e = new Entity(); e->Delete(e); per https://stackoverflow.com/questions/1208961/can-an-object-instance-null-out-the-this-pointer-to-itself-safely That way we have a standard interface of deleting objects between C++ and Lua.
-
Hiding and then setting to nil isn’t ideal from a usability standpoint. How about creating a base class method called Delete() which does this stuff for us in c++ as a more intuitive manner.
-
Keep the types. It's more functional even if it looks uglier.
-
Thanks for the idea on this. I used this and it really works out great! I now have random dungeon rooms that match doorways correctly working which is just fun to regenerate new dungeons Now I'm moving onto room prop population. The plan is that each room itself is a 2D array that's used for both AI pathfinding and prop placement. Since I can have 15 different rooms with exits ({ "n", "s", "e", "w", "nw", "ns", "ne", "sw", "se", "ew", "nsw", "nse", "swe", "nwe", "nsew" }) the plan is to have multiple room configurations per room exit type (can keep building on those over time). Since each room will be a 2D array I'll have each prop have an ID and just put the ID in the 2D array. So I'll have preconfigured prop placement rooms per room exit type to pick from after it's determined which room to make. When the props are 1 tile in size this is easy. I have to figure out a way to do this with things that are greater than 1 tile and rotation of said object. I suppose I'll have to include rotation with the ID for the props.
-
If you've ever used .NET then you've heard of linq. I found a sweet lua linq library. This allows you to query tables in a clean and powerful way. It's pretty slick. https://github.com/xanathar/lualinq Just download it all and look in the Release folder and unzip the lualinq.zip in there and it's just the lualinq.lua file that you need. Looks like in there is another querying framework called GrimQ. Something Legend of Grimrock used I guess. Pretty neat!
-
1) I make some csg where one of the csg is the parent and others are the child and give them dummy scripts. 2) If you hide the parent csg at this point the children get hidden. All great right! 3) Now make this a prefab. Delete this from the scene. 4) Bring the prefab in and now changing the hidden flag (or in code too) of the parent does NOT show/hide the children
-
Hmm it plays for me. I'll have to dig into some youtube menus where I can't find anything. OK, it was private. Changed to public. Try now please.
-
Really? So you can't see them? Josk can you see them?
-
I added a script to the workshop which you can get from the LE editor Workshop->Browse Workshop. I also did 3 video tutorials on usage from beginner to more advanced coroutine usage within the states. Don't ask me why the 2nd video link didn't show up in this post. No clue. http://steamcommunity.com/sharedfiles/filedetails/?id=1338038813 https://www.youtube.com/watch?v=AXiJ0DhDV7w
-
Yep that’s the one I have used before. Works great and easy to implement!
-
Honestly, I've had bad luck with LE's navigation. Just always ends up being a decent amount of little issues to it when it comes to the AI moving along it. My plan is to just use A* with something like this since each room will be a square like shown. I'll grid out each room and have them move that way. I'll place props on the grid as well so it's nice and easy. I'm not allowing monsters to move from room to room, but when you are in a room I might sometimes block the doors until you kill the monsters so you are stuck in there and can't just go out to the next room to rest/heal. This example was 2 rooms in the map itself. The 2nd room wasn't generated on the fly but that would be the plan eventually. Room generation is interesting. First everything would be on 1 level. I don't have plans to move up or down. Each room has at least 1 exit/entrance but can have more. My idea was to have a room model for all variations of exits. North.mdl, NorthSouth.mdl, NorthSouthWest.mdl, NorthSouthEastWest.mdl, etc. On map load the entire dungeon is generated. Start with the first room and pick a random exit room model, and build out from there. The themes would just be the material used on the rooms. Since each room is gridded for navigation I can also put the props on the grid as well. If each prop/enemy has an ID each room just becomes a 2D array of numbers. So these configurations can be built out in an editor but ultimately as just 2D arrays stored to file and picked from on load of the dungeon and creation of a room. This way I can have a bunch of predefined configurations to pick from so they look good. I could even make sure each level gets a certain configuration for each room if I wanted. Lots to think about.
-
Plugins in Leadwerks Game Engine 5
Rick commented on Josh's blog entry in Ultra Software Company Blog
Classes are fine in any language, it's really just deep hierarchies you want to avoid. The age old composition vs inheritance. Composition can still be done with the idea of classes which basically every programmer knows and is comfortable using in 2018.