Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - monkey0506

#481
Engine Development / Re: Choosing a way to go
Mon 28/07/2014 23:54:57
While I'm all in favor of starting to port the codebase to C++11 (it's been the official standard for three years now), I don't think that shared_ptr<string> really serves the same purpose as a reference-counted string. One of the benefits of a proper ref-counted string is that it also provides string pooling. For this we'd need a wrapper class to provide COW behavior if the shared_ptr is not unique. Also, while we're at it, we might consider using std::u32string instead. We could convert quite easily to/from UTF-8 as needed, but bear in mind that std::string doesn't guarantee its operations to operate on characters but just bytes (UTF-8 characters can consume up to 4 bytes), so UTF-8 strings could easily become corrupted. Using u32string would provide this guarantee for UTF-32 characters, and help prevent corruption.
#482
Quote from: Calin Leafshade on Mon 21/07/2014 07:37:56
The point is that they don't know at runtime.

Oh...duh. (roll)

So since the compiled program basically just deals with chunks of raw memory, and the members are then offsets from a parent address, essentially we need an additional step to say, "Before you free up this memory, derefence this offset and free up its memory too," right?
#483
I'm still a little bit confused. It seems that in order for structs to even work, they would have to know the relevant types and offsets of the members, but you're saying that's not the case? >:(
#484
I have a question regarding the issue of pointer members of managed structs. CW has said that this can't (simply) be made to work. I'm trying to understand why. The engine already has reference counting and garbage collection for the built-in managed types, including DynamicSprites and dynamic arrays. These pointers can be included as members of user structs, which only exist as one instance, but are still cleaned up by the garbage collector. There are no known issues with pointer members of user structs. So where is the discrepancy when it comes to managed (dynamically allocated) user structs? Shouldn't the reference counts for pointer members still be updated, and the relevant objects freed if their reference counts reach zero? :-\
#485
^ I basically... Yeah, what Gurok said. ;)
#486
If AGScript is replaced by a Java-based language, I will stop contributing to AGS development.
#487
This may be a good time to port the compiler fully over to managed code (C#). I've actually started exploring that already, but I need to understand the compiler better to make a useful conversion. I've been going through and heavily commentating the script in a separate local branch. If anyone would find it useful I could share, once I'm finished documenting.
#488
I basically agree with Calin on this. Object "pointers" in AGS would be more aptly named references. This applies to their usage for built-in and user types alike.

C# delegates are more similar to a reference to a function than a C-style function pointer. This is why I suggested that style mechanic, because it most similarly matches the "pointer" system already in-place, and maintains a high-level approach to a lower-level problem.
#489
Not yet Rick, but the engine already has the capability, we just have to come up with a way of adding the mechanic. I definitely think we should push for C#-style delegates, but that is a pretty major change, that should probably be saved for a future version. 8-)
#490
Quote from: Gurok on Tue 08/07/2014 14:28:15Yes. That's exactly what I meant. Sorry, it was confusing even as I was typing it out.

It's a rather specific and convoluted thing to try explaining in regular speech. Thanks for the clarification.

Also looking forward to constructors, thanks for your hard work. Delving into the compiler last night I realize it's pretty complex.
#491
If the consensus is to push back the autoptr declarations then I won't keep pressing it for now, but I think the compiler will need a way to see the instances as not being pointers.

Gurok, do you mean you can now have nested user pointers within a user type with access modifiers within the same script in which the first struct is defined? I'll test this afternoon. Probably do some more extensive testing on my changes as well.
#492
Created an unrelated pull request, to allow dynamic arrays within structs:

Code: ags
struct MyStruct
{
  int Array[];
};

function game_start()
{
  MyStruct ms;
  ms.Array = new int[5];
  ms.Array[3] = 42;
}


Will definitely require further testing, but preliminary testing (including saving and loading tests) show that this should be working.
#493
I did, of course, intend to add an option to retain legacy pointer syntax, which would be on by default for any old projects being imported and off by default for new projects. It wasn't some careless or thoughtless hacking either, but a step toward implementing a meaningful class keyword, as per my prior suggestion. I don't think that optionally removing the pseudo-pointer syntax (while preserving full compatibility for its use) constitutes such a drastic change that we should be forced to put it off. :-\

Quote from: Crimson Wizard on Tue 08/07/2014 00:25:04
Quote from: monkey_05_06 on Mon 07/07/2014 23:09:22
Sticking the keyword in front of the struct definitions was the easy bit, but now I have to figure out how to differentiate between the autoptrs and the actual instances that are being imported (like cEgo, which is a Character instance, not a Character*). I presume at this point I need to be looking in the engine code. Any pointers appreciated. (roll)

I think its in "AGS.Editor.Tasks.AppendCharactersToHeader()".

I wasn't referring so much to where the instances are included in the header, but the fact that they are importing the actual instances rather than importing pointers. If the types are made to be autoptr, then the imports are seen as pointers, not the actual instances.
#494
I'm looking into making the built-in instantiable types into autoptr types as a step toward deprecating the pseudo-pointer syntax. Sticking the keyword in front of the struct definitions was the easy bit, but now I have to figure out how to differentiate between the autoptrs and the actual instances that are being imported (like cEgo, which is a Character instance, not a Character*). I presume at this point I need to be looking in the engine code. Any pointers appreciated. (roll) Once I get it figured out I can submit a pull request for it.
#495
Discovered another issue, though this might be one that we can reasonably write off. If a user struct only has imports, and does not actually define any members, then you cannot create a new instance of it ("requested user object of size 0"):

Code: ags
autoptr managed struct MyStruct
{
  readonly import attribute int MyProperty;
};

function game_start()
{
  MyStruct i = new MyStruct; // crashes
}


If there is a reasonable use case for instanciating a user struct like this (can't really think of one off the top of my head, the imports could all just be static) then it could be rectified by simply adding an unused char to the struct definition:

Code: ags
autoptr managed struct MyStruct
{
  protected char __unused; // $AUTOCOMPLETEIGNORE$
  readonly import attribute int MyProperty;
}
#496
Eastwing, no worries. We definitely appreciate people trying to help, but if a more experienced member suggests that there is a better way of doing it, then you might just want to step aside. In time you'll pick these things up and be able to give stronger advice yourself. ;)
#497
This may be a bit belligerent, and definitely adding to the confusion, but dynamic arrays are passed by reference, so you could use multiple arrays and pass them variably into the function...

But seriously, what CW said is the most friendly approach ATM. Future versions of AGS will support more flexibility with user types, but it's still going to be quite similar in practice.
#498
You could do it all in one shot with:

Code: ags
String Prepend(this String*, String newbit)
{
  if (String.IsNullOrEmpty(newbit)) return this;
  return String.Format("%s%s", newbit, this);
}


Usage:

Code: ags
String text = "World!";
text = text.Prepend("Hello ");
Display(text); // shows "Hello World!"
#499
Another minor issue with managed user objects: If you try to create a struct B which has a protected or writeprotected member (field) of type struct A in the same script where struct A has been defined, then the compiler throws a syntax error that struct A is not a type.

Code: ags
// Script.ash
autoptr managed struct A
{
};

autoptr managed struct B
{
  A a1; // works fine
  protected A a2; // throws compile error
  writeprotected A a3; // throws compile error
};


This can currently be dealt with by simply moving the second struct definition to another script:

Code: ags
// ScriptA.ash
autoptr managed struct A
{
};

// ScriptB.ash
autoptr managed struct B
{
  protected A a; // works fine
};


Also, while I have your attention, might I ask how difficult it would be to allow dynamic arrays as struct members? We can already have pointer members to built-in and user defined types, so simply storing the pointer to the array seems as though it wouldn't be terribly difficult to manage...?
#500
I agree that the headers can cause more confusion than they might be worth. I've seen numerous beginners putting actual definitions in the header files, not understanding the import/export keywords. I find them perfectly easy to work with, and as CW said, comparable to C++'s extern, but if we can lower the learning curve for newbies then I'm all for it. Calin's suggestion for a global keyword seems reasonable to me, and it pretty clearly explains what it does.

I also understand we shouldn't add new keywords without consideration first, but I support this, and the two-pass compiler suggestion.
SMF spam blocked by CleanTalk