ENIGMA Development Environment
Website is in read-only mode due to a recent attack.

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.

Messages - Josh @ Dreamland

Announcements / Re: Shortcuts
« on: July 29, 2010, 12:25:19 PM »
This is not why I write intricate news posts.

Announcements / Shortcuts
« on: July 28, 2010, 10:34:26 PM »
Long, long ago, in a land far-- actually, it was in this chair. Or some chair that looked similar. Be it as it may, a while back, I took a shortcut and thought, "If this ever comes back to bite me, it'll be after the rest of the project is stable and I can fix it without fear." Well, that mostly came true. There are no detrimental effects at this time, simply because the amount of skill required for the malefaction to manifest simply isn't being exhibited by ENIGMA users at this time. For those who wish to be weary, this is the issue:

When I designed the C++ parser, I did not implement a proper overloading system. Overloads were, instead of instantiated as children of a main instance as I considered doing, applied to the current copy by way of modifying the bounds for acceptable parameter numbers. For instance,
Code: (C) [Select]
string func(int a) { return "test"; }
double func(int a, int b) { return  "test2"; }

is stored only as a function returning double that takes either 1 or 2 parameters. Had the second function taken three parameters, the choices would be 1, 2, or 3, even though 3 was actually an invalid option. This makes for a blazingly inaccurate syntax check in rare situations (a GML user would never come close to noticing).

It also means a less pleasant inaccuracy on a more important system.
The following expressions were passed to a new type resolution system of mine:

room + room
room + 1
room - 1

The results were, respectively, as follows:
Let's see if I can't waste some space and make a nicer table.

room + room=>variant
room + 1=>variant
room - 1=>double

The more curious of you have a few questions. I'll do my best to answer those here:
room_speed and the like are being left integers. I see no point in wasting memory and speed so users can set some random array element in global scalars.
The type resolution system doesn't distinguish between cast and type at the moment (by choice, so I can debug without thinking of a global by that type. :P)
The type "roomv" is a special type with an overloaded operator= that calls room_goto(). It inherits from variant.
Because "roomv" is a special variant, room + room will return variant. This is correct. Room + anything will, in fact, so you can keep adding things such as strings.
However, room - 1 is double because subtraction only works on such. It wasn't worth it to avoid a warning on re-cast. Maybe I'll change my mind later, but in any case, the resolver was accurate.
Calls to [] on var are indeed variants.

So what's the problem? Look at item three, "*var". The parser can't distinguish between binary and unary *. Even though it knew it wanted the unary version, it couldn't get the accurate type, because I only store the type of the last declared overload, and so the parser was given `double`, the type returned by the multiplication operator.

When I need, I will store all overloads with argument counts and types, but that is a job for after the basics are all working. I want one more thing to work before I proceed, and it is indeed a trick; I would like for templated types to work, and if possible (by which I mean, it shall pass), templated casts. This way, if you have map<int,int> amap, you can say amap[whatever].x and have it behave correctly. That has been important to me since square one.

Another nice thing I can implement with the help of this system is the switch() optimization, as well as something brand new.

It befuddles me that neither C++ nor GML have a foreach construct. ENIGMA will be given one. It will work rather uniquely, since neither language was designed for it. Basically, it will have the following syntaxes:

foreach (array as element)
foreach (element in array)
foreach (element : array) //Java-esque

Trouble is getting it to work around this little issue: "in" and "as" are common variable names. So, I'm going to work around that thanks to how carefree my parser is when it operates.

Code: [Select]
foreach in in as

will work fine.

To ease the sadistic and curious, that will look like this in intermediate parse:

Which makes it very easy to parse out. The first item, in (), is either what I'll be iterating, or the element name. The second, of form "nn;", will determine which; it should be "in" or "as". The third set, denoted easily by regexp /;(^;);/, is the corresponding element of the foreach.

So, how will that work from there? Simple. I determine which is the container to iterate. I then check for the following:
  • Typedef by name "iterator"; iterator container::begin(); iterator container::end(); iterator::operator++() or iterator::operator++(void)
  • container::operator[](int); size_t container::size() or typeof(container::operator[](int))::operator bool()

Depending on which of those I find, the foreach will be replaced with code to iterate each. The real trick is managing to proxy the "as" component in as a method of retrieving the element itself, and not the iterator type. Mind all of you, I'm not afraid to implement a macro if I must. But I imagine I can find a creative way to cram more instructions into the mix using operator, .

Anyway, I'll be busy. Thanks for your patience. I know this is taking a while, but the level of detail Ism and I've put into this goes far beyond the previous releases' quicker development time.


Issues Help Desk / Re: GL Lighting
« on: July 25, 2010, 12:21:59 PM »
As usual.

Issues Help Desk / Re: GL Lighting
« on: July 25, 2010, 12:07:14 AM »
I myself can't stand when you have snippets like this:

Code: (C) [Select]
if (something)

So, of course, I never put one-liners in braces

Code: (C) [Select]
if (something)

Most people don't. And I do my very best to cram things into one line, even if they end up getting pretty ugly themselves...

Code: (C) [Select]
something ? something_unremarkable() : void();
Operator, is nice, too...

Code: (C) [Select]
if (something)
  a++, b++, c++, d=e=f;

And then there's those times I just totally ugly it up because continue and operator, don't agree.

Code: (C) [Select]
if (something)
  { something_tedious(); continue; }

And if I've got two things that really need done, I group them like Ism does.

Code: (C) [Select]
if (something) {

I'm not afraid to put a continue; or the like after thing2(), either.

But when I'm navigating code flow, Ism's method makes my skin crawl, and I hate the rest of your proposals, too. Of course, that's just my opinion. It's one thing to waste space, it's another to cloud structure.

Off-Topic / Re: hi my name is kaylee!!!
« on: July 20, 2010, 06:42:17 PM »
First of all, the filters are infallible. I designed them myself. Our friend kaylee is just genuinely dumb. Picture a lifeless loser of a teenage drama queen who googles what she would look like if she weren't disgusting and posts pictures of herself on random message boards. Now picture a very bored Gary. kaylee is the latter.

Second off, as fate would have it, I'm grounded for an unspecified amount of time for crimes against the empire. I'll be back sometime in the near future. My father absconded with the more important of my outlet strips, so powering my computer will prove... well, unsafe in multiple respects.

This has not deterred planning on paper. Details will follow.

General ENIGMA / Re: APIs & Articles worth keeping in mind
« on: July 17, 2010, 12:05:09 PM »
...That's Luis, not Luda...

General ENIGMA / Re: Pixel-Perfect Collision by default ? Box2D
« on: July 16, 2010, 08:10:07 AM »
I don't believe Luda is going to go through with it, nor post what he's actually finished. I'm going to end up doing them myself.
...Yes, Retro beat me to it by five seconds.

General ENIGMA / Re: Markdown
« on: July 11, 2010, 05:00:32 PM »
You've my support on the idea. It's about time people started merging the two anyway; markdown is a beautiful format.

Issues Help Desk / Re: Stuff referencing each other.
« on: July 10, 2010, 11:33:31 PM »
Returning incomplete types seems sketchy to me. Try returning a pointer, that's guaranteed to never fail, however incomplete. But I'm not sure, since you're not implementing opposite() immediately, why it wouldn't work.

Announcements / Re: Worth Mentioning
« on: July 10, 2010, 06:30:08 PM »
Correct. I intend to eventually deploy tricks like your precompiled headers, and it may require source files for each object in large games, meaning more existing object files to use. But that's later.

Right now, there is one main source file that includes many code-generated headers. Each of these implements a different chunk of user code; one for object events, one for event code, one for scripts, one for globally defined variables, one for room codes, one for room data (In array format; will actually need some rethinking for improved compile speed and possibly loading time)... the list goes on.

When ENIGMA allows for larger games, it may become necessary to compile objects in their own sources, as I mentioned, which will call for precompiled headers as well. We'll see then what's required. When that time comes, the majority of the main source file will be made into a header (precompiled, I hope) and included from each of the object sources. I'll probably always leave room creation code in the same source.

If and when I do separate them, there'll be some organizing and double checking to prevent linker errors. Otherwise, to make it flawless, I'd have to recompile them all anyway, which would be very inefficient. There'd also be the itty bitty problem of having to recompile them all anyway each time you switch games. Fortunately, the main system code never needs recompiled (unless you check out new versions, of course, in which case the makefile will take care of it automatically because it's cool like that).

Announcements / Re: Worth Mentioning
« on: July 10, 2010, 03:29:34 PM »
Luis: Yes, this is a simple particle drawing executable (Compile time increase is immeasurable compiling things like "Click the Clown"). Some object files were already compiled; they always will be. Most of ENIGMA's code is modular and independent of the main source file. More of it has been separated and is yet to be thanks to the new instance system and the tiered local system. This is the compile time users will be seeing. The important thing is that it's faster than GM can export and run its own executables. I intend to keep it that way.

Announcements / Worth Mentioning
« on: July 10, 2010, 08:58:21 AM »
As a by-the-way sort of deal, I've reduced ENIGMA's compile time to roughly two seconds on this old computer. Compile, link, and run took 2.75 seconds. This means I pressed "run," and in 2.75 seconds (minus my reflex time on the stopwatch), the game window was there.

On my laptop, a newish (less than two years) dual core with decent specs by today's standards, the process takes 1.4 seconds. Again not accounting for my reflexes.

So all-in-all, I'm pretty happy about that.

I've gotten a few bug reports via the tracker and have fixed most of them that were for me. More will follow, but I've been busy these last few days; today should be my last busy day. I'll be moving air conditioners around; don't ask. The most immediate thing I'll be working on is my type resolver. The only reason it's not finished is the amount of crap I've had to deal with lately.

So. Enjoy the new compile time. I believe it can later be reduced further; we'll see.

It's also worth mentioning that I could use someones to verify that all the math functions work properly (they are included directly from the C library, mostly; ambiguity is quite possible with var's many legal casts). The bessel_* functions may or may not work; I'll figure that out eventually. Logically, they shouldn't; I renamed the symbols in the header without renaming them in whatever library they are implemented in. But who knows? Also, if someone is feeling really bored, they could make sure that all the operators work on var. They are largely code-generated, so slight error can be catastrophic. For instance, division once returned zero consistently. And freezway found an ambiguity in variant += var. There's a lot of boring testing to do with those.

Announcements / Re: Progress
« on: July 08, 2010, 07:35:19 PM »
Screw you. You can have it when I'm 100% happy with the type resolver. Or I cuss it out and abandon it, then commit this part in disgust.

Announcements / Progress
« on: July 08, 2010, 12:01:23 PM »
I'm so happy with a couple changes I've made and am making.

First off, I'm proud to announce that standard templates are now completely available to ENIGMA users.
Code: (C) [Select]
map a; // is the same as...
map<> a; // is the same as...
map <variant> a; // is the same as...
map <variant,variant> a;

That's right: ENIGMA now correctly defaults all non-defaulted template parameters (as in, template parameters that are not already optional according to the C++ library) to variant. That means that once Ism and I are finished coordinating our new "Definitions" resource (previously "WhiteSpace"... we're still working on a catchy name) you will be able to #include <map>, use it, and use codes like this:

Code: (EDL) [Select]
map a;
a[100] = "one hundred";
a[15625682900000000.0] = "lol, big float";
a[3.141592653589793238] = "pie";
a["pi"] = 3.14;

That's right: with the implementation of var4, comparison operators are correctly implemented for all types and mirrored const. This makes them capable of complete interaction with the standard template library. GM's ds_* functions are officially toilet food in comparison.

Furthermore, map isn't exactly necessary for large numbers. Var4 also implements Lua's algorithm for fast, sparse arrays. This introduces a number of nice properties:

Code: (EDL) [Select]
var a = 0;
for (int i=0; i<100; i++) a[i] = i;
a[1000000000] = "one billion";

How can this be efficient? It's simple. a[0..127] operates in O(1), because that's how much space was allocated for the array. a[128] operates in either O(1) or O(n), depending on how your system resources are doing. a[256..INT_MAX] operates in O(log(N)), as it relies on a map for the lookup. (This will hopefully be replaced with a sparse hash map at some point).

Currently the system is functional, but not finished. Var4's lua_table<> needs to ensure that elements can hop data structure when the array part is resized. Templates need field tested, which will happen after my latest renovation: the dot operator.

Because C++ introduces structures and classes which I do not want to alienate, I have to take special care to ensure that the left-hand side of the dot is not an instance of a structure. This requires a type resolver, which I hope to complete inside 400 lines. We'll see. Basically, it will return the type of the expression that precedes the dot. I intend for the following to happen:

If it's an instance of a class, check for a member by name of the variable to the right hand side of the dot. If the member exists, ignore the dot. Possibly, if the class was actually a pointer, not a direct reference, replace the dot with ->. C++ should have done this from square one; I see no use for pointer.member. If no member was found, or if the type was scalar, replace the dot with an integer-based accessor function and record that the global was indeed accessed that way so optimizations can be done later. Also try to warn if it was a class without a member and without operator int() or some other scalar that can be cast easily. Perhaps it should be up to ENIGMA to find an appropriate cast path, such as int(var()).

Anyway, just something to think about.
Back to work, ciao for now.

Announcements / Re: Bugtracker trial
« on: July 08, 2010, 11:33:45 AM »
General: I believe a2h has or was going to add categories, certainly. Perhaps some will want to have a separate category for suggestions. It'd probably be good if he let the intermediate user (as in, whatever we are to Simple Machines: not the creator, not the end-end-user) change the labels of each severity. That's just if he wants to put it out there for the public, as I know is his intention.

1: Vote for bugs. I assume you mean "This affects me, too!", in which case, yeah. Good idea.
3: There is an Assigned to: field.
6: That's kind of silly; why not just paste any concerned URLs into the body of the bug report?

I like the idea of and have no further comment on suggestions 2, 4, 5, and 7.

But personally, I'm happy with it right now. So he can take his sweet time on that extra glittery stuff. As long as I can mark a bug "solved," which I've not yet been given a chance to test.