Showing posts with label programming. Show all posts
Showing posts with label programming. Show all posts

Thursday, September 22, 2005

UsUnit

There you've got it. The second more mature release of the UnrealScript Unit Testing Framework. A few minor changes to the real framework. More important is a working WebAdmin module.

So far UsUnit contains some graceful code, some somehwta hacky code and some scary code. For the webadmin module I tried to create a better PlayInfo to HTML converter that the one that was already present. Actualy, the existing one couldn't be use in arbitrary places. My converter current supports just check and text types, but also arrays. My initial idea was to auto detect arrays, but because of a bug in PlayInfo's validation code for TEXT render types this can't be used. Instead you will have to use a CUSTOM render type which will figure out of it was suppost to be rendered by the TEXT type. For the TEXT type I also made a special case of numeric values. If the extra data contains range information it will be used to show a specialised text filed with a plus and min button and it will respond to certain key events (up, down, home, end, pgup and pgdown) to modify the value.

An other tricky issue I had to solve was to add some logic to cope with possible invalid test classes. The test class configuration uses strings. It might happen that a single entry isn't a valid name for a class. But during configuration I don't want to remove those entries, or change them at all. Therefor I added a displacement array that keeps track of the array index differences between the two arrays.

More information about UsUnit.

Saturday, September 17, 2005

UnrealWiki Developer Journal 17-09-2005

It has been a while since my last dev journal entry (again). First a little update about my last entry. I'm no longer actively working on a VisualStudio AddIn. The features I wanted to add required me to write a VisualStudio Package instead of just an AddIn. Writing a package isn't as simple as writing an AddIn. I hit an issue while implementing the basic framework that I haven't been able to resolve (devstudio gives me an error when I want to load a few things here and there). So that project has been put on ice.

As for other projects, a while ago I continued some development of LibHTTP and got a bit annoyed on my testing class. So I decided to make a testing framework based on unit testing. That's how UsUnit came to life. Because I wanted to include the source file and line where a check failed I had to write an UnrealScript PreProcessor, and I also wanted a few other features that a precompile could accomplish. And that's why I created UCPP. Well, UCPP had some releases, and it quite mature and finished right now. So I've gone back to working on UsUnit some more. I've already made one release so far. But this was mostly to put out the first binary package for people to play with. You could consider it a beta release for now. I want to complete just a few more things for the next release, it can be summed up into: finish the webadmin module.

Also, today barnEbiss contacted me if I was interested in helping him with a weapon mod. His idea is quite interesting. He wants to create a weapon that allows you to create a line of gasoline and set that one fire (the fire ofcourse will hurt people). It's quite an interesting weapon to create, with some interesting implementation issues to solve. So I will also be working on that project.

Well I guess that's all I have to say about that for now.

Wednesday, June 15, 2005

UsUnit + UCPP

Well I laid my plans for a VS.Net Package aside for a while, kept getting annoying errors outside my source code. I'm been working on a UnrealScript Unit Testing Framework, somewhat similar to DUnit and JUnit. It's called UsUnit. It's almost done, but UnrealScript doesn't allow me to do certain cool things (like point out what check() failed). For this I started to create a PreProcessor for UnrealScript: UCPP

UCPP stands for UnrealScript (Class|Code) PreProcessor, the extention for UnrealScript classes is .uc so therefor UCPP, I'm not sure what the 'c' stands for. So far I've implemented quite some useful features:

  • #define NAME VALUE
  • #if EXPR (#else) #endif
  • UpperCase words in the code are replaced with thier definition according to a previous #define statement
The expression in the #if is quite extensive, simple boolean evaluations and some basic math functions.

But my current problem is with defining function macros:

#define DUMMY(a,b) DoSomething(a, b)

DUMMY("bla", 12345) -> DoSomething("bla", 12345);
I'm having problems to create a nice way to implement this feature. I don't want the definition list to be depended on a parser, but how do I process the definition to replace the arguments. a should be replace, but aa or "a" shouldn't be replaced. A simple replace text routine won't work. I could write an event
OnParseArguments(args: array of string; func: string; var OffsetList: TListOfSomeSort)
args
the argument names as specified in the name; this is simple to parse
func
the function part of the definition
OffsetList
Will contain the positions of the of the argument names in the function string; length isn't required since it's known.
The user will then have to assign a function to this event that will do the real parsing. However, this doesn't solve the magic entities in the macro definition (e.g. # and ##).But I guess that can be hacked in to the offset list in someway. Or I can add self and give direct access to the object that is actually being parsed.
The function definition only needs to be parsed the first time it's used. I can throw an exception when a definition can not be parsed because the event is not assigned.

Saturday, April 23, 2005

VisualStudio.Net Add-in written in Delphi, part 2

Ok, adding a new tool window wasn't hard at all, actually it's quite simple.

Just create an ActiveX form, get it's GUID from the type library window View -> Type Library and call the following functions:
myToolWindow = DTE(Application).Windows.CreateToolWindow(AddInInstance, 'your_library.activex_form', 'Some Title', '{THE GUID}', dummyIDsipatch);
The form is just like any other form in Delphi, you might want to set the form's AxBorderStyle to efbNone.

One ting, when creating an activex form Delphi automatically changes the target extention to ocx, I didn't like that and changed it back to the normal dll. Also, don't forget to register the "ActiveX Server" when you added a new COM object, otherwise the GUID won't be registered in the registry.

Friday, April 22, 2005

VisualStudio.Net Add-in written in Delphi

I'm planning to create a spin-off of UnCodeX (again), this is going to be an add-in for VisualStudio.Net. Right now Epic has a simple tool that gives a class and package tree, but compared to UnCodeX is kinda inferior. Since I have a lot of base code it would be easy to create an add-in right?

Well not completely, first the add-in creation is done via an wizard in VisualStudio, well great, but how would I do the same in Delphi?. The add-ins are all COM based, so I will have to import a type-library somewhere. The VS.Net wizard does all the base work, so I have a few pointers, like what interfaces I should implement. But I have no idea what type-libraries to import. After a long search and some pointers here and there I've found out how to create a Add-in for VS.Net in Delphi.

  1. Before you do anything you will first have to import and install the type libraries (to make things easier in the next few steps).
    1. Import and install the type library: Microsoft Add-Iin Desginer, the actual file is called: MSADDNDR.DLL.
    2. Import and install the type library: Microsoft Development Environment 7.0, the actual file is called: dte.olb.
    Make sure you installed them in a package.
  2. Now create a new ActiveX library; nothing major here, you just need it.
  3. Now in your library create a new ActiveX Automation Object.
    1. Enter any name you like; different from your library name.
  4. You will now see the Type Library tool, select your library in the tree and open the Uses tab.
    1. Right-click the list and "show all type libraries"
    2. Now select the same type libraries you previously installed.
  5. Now select the Automation Object you created (it's the one not prefixed with an I)
    1. Select the Implements tab
    2. Right click and add _IDTExtensibility2
    3. Right click and add AddIn
    4. If either one of these are not available you messed up in the previous steps.
  6. Close the type library tool window.
  7. Save the new unit (Save all files i the project)
  8. Now add the following to the interface uses list: , EnvDTE_TLB, AddInDesignerObjects_TLB
  9. If everything is ok you should be able to compile the library.
  10. After the compile is done you should register the library via the menu Run -> Register ActiveX Server
  11. Now you will have to add an entry to the registry so the add-in will show up in the Add-in manager. Add a new key to HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\7.1\Addins\. The key name should be: <library name without extention>.<automation object name>
  12. The add-in should now be visible in the add-in manager

If you want to change the descript and version information in a later stage just open the .tlb file in Delphi. This will pop-up the type library tool.

These are just the basics for a add-in, how the rest works is still a mystery, but I hope to solve it soon and report it here. Next thing might be how to add your own tool window, I assume this can done via an ActiveForm. The tool windows are refered to via the GUID in VisualStudio.NET, so it would be some more ActiveX\COM stuff.

Wednesday, April 13, 2005

Delphi 6 + build configuration

Delphi 6 misses (at least) one important feature: being able to create\manage build configurations. For my UnCodeX project I want two build configurations: debug (or development) and release. For the simple reason that the debug builds will include debugger information so I can use some tools to find memory leaks and what not. The release builds ofcourse should not contain the debug info and should be optimized. But Delphi 6 was no way to manage the project options\settings. You can have various "desktop" configurations, really don't see the use of that, but not build configurations. So far I've only found one IDE expert that helps me a little bit: GExperts. However, the way I have to use this isn't great at all, the overview of te configuration is completely lost and it doesn't store the alternate configurations on the project. This way I can't include it with the CVS and use the alternate configurations on other machines. This sucks a lot.

I don't know if newer Delphi releases do support management of alternate build cofigurations, I don't have the money to upgrade to a newer Delphi release anyway. Delphi 6 still works well enough for me, except for a couple of annoyances.

If anyone knows of an IDE expert, or maybe an other method, that makes this easier please let me know. Important to note that this tool has to be free (as in beer), or at least with a small price tag, because I don't want to limit people in being able to work on my open source uncodex project.

Thursday, April 07, 2005

Open Source, it's nice.

I'm not going to stay Open Source is the way to go, or that everybody must switch to open source (altough it would be very nice).

I'm working on a fully Open Source programms (UnCodeX), and while working on it I sometimes use other open source tools (FreePascal compiler) and components (RemObjects' PascalScript). Both the examples are open source (and free software, in a way).
PascalScript didn't compile for FreePascal out of the box, but because the source was available I could apply the changes required to make it compile. I mailed my changes to the developers and they applied them to their SubVersion repository. Now everybody can enjoy PascalScript in FreePascal.
As for FreePascal, the ini file classes provided by Borland in Delphi 6 didn't meet up to some of my requirements, and because of the private vs protected shit I could override some functions. FreePascal provided similar classes, and because the license of FreePascal is compatible with the license of UnCodeX (both are LGPL) I could use the FreePascal implementation and make my adjustments. While I was making some adjustments I discovered a few bugs in their implementation (the Delphi memory leak detection script by Vincent Mahon helped me to find one of them). I reported the bugs I found, and the fixes for it, and they have been applied to the standard distribution of FreePascal.

So, for at least two projects I found some issues, was able to fix them and contributed the fixes back to the creators. They helped me, I helped them in return. Sure, there are a lot of people that don't help out. But why shouldn't you? What would be the reason not to help others out that helped you at the first place. Please that report bugs are great, people that report bugs with correct patches are just awesome. And you can't create patches when you don't have source access.

Tuesday, December 21, 2004

Private vs Protected

Pretty much every object oriented programming language let's you set the visibility of object members. Usually it defaults to public. That means everybody can access that member. Ofcourse often you don't want to other objects to access certain parts of your object. This is where private or protected come in to play.

Limiting members access

An object should only expose members that really need to be accessed from the outside. All other members should be "hidden". It's not just a security issue but also creates nicer foot prints to work with the code. For example IDEs only have to list the public accessable functions in their "code insight" (or whatever you want to call it) listing. The public members are the members to work with, it also makes it easier for you to find what entry points you need to use on an object (in case it's not your code).

Private

The actual outcome of this depends on the language. But usually it comes down that only the objects within the same scope can access this member, subclasses do no have access to this member. What the scope is depends on the language used, often the scope is just the object itself. In ObjectPascal however the scope is the unit file (the source code).

One of the basics of OOP is that you can extend an object and add additional functionality. And usually you can only add additional functionlity outside of the "scope" because you can either not touch the original source or you simply shouldn't.
Using private to protect members of an object will prevent an subclass to work with these members. This is often needed.

Protected

Protected is similar to private except that subclasses can always access these members no matter if they are in the same scope.

Making members protected opens a security issue for those members. Since a subclass has access to these members it's possible to work around security measures.

How to choose

I'm sure somebody already though about that, however I am not aware of a document that introduces a formal method for member accessability. If such document would exist it would be very technical for most programmers to understand, or at least it would way to time consuming. That doesn't mean it's not wise to read it and use it's methods.

Here's a simple classification scheme I think should work well enough for most people.

  1. Is the member valuable to access from other classes? (1)
    Yes -> go to 2; No -> go to 3.
  2. Is it a variable?
    Yes -> go to 2.1; No (it's a function) -> public
    1. Should this variable be read-only? (2)
      Yes -> create a public accessor function and go to 3; No -> public
  3. Does the member contain\give access to security sensitive information? (3)
    Yes -> go to 3.1; No -> protected
    1. Is it a variable?
      Yes -> go to 3.1.1; No -> go to 3.2
      1. Should a subclass be able to write this member?
        Yes -> go to 3.3; No -> go to 3.1.2
        1. Should a subclass be able to read this member?
          Yes -> private and create a protected accessor method; No -> private
      2. Does this member give readonly access?
        Yes -> go to 3.2.1; No -> go to 3.3
        1. May a subclass read this data? (4)
          Yes -> protected; No -> private
      3. Does the new value need to be validated? (5)
        Yes -> private and create a protected method that will validate and set the private method; No -> protected
Only in a few cases the member will become and isolated private member (e.g. unable to read\write to the member).

1.
This is quite a difficult question, is the member for internal use only? When is something for internal use only? Things like buffers and pointers are usually for internal use only. Maybe somebody else can shed some light on this question.
2.
Very often you want to be able to give other classes access to certain variables, like the current position of a parser, but you don't want them to be able to modify the value. For this you should create an accessor function getMyVariable() that will simply return the current value of the variable.
3.
When is something security sensitive? Things like keys and passwords and sensitive. But it's not limited to authentication related information, sometimes things like an URI could be sensitive. Things that might need to be validated before they are used are security sensitive. For example in games you might want to give a user the freedom so configure some client side things. However, these things could be abused for cheating. So the settings need to be validated before they are set.
4.
In only a very few cases you want to prevent a subclass from reading certain variables. It's pretty much only the case for keys and passwords. Even though a subclass might have set the value via an other method it still doesn't mean it should be able to read a password.
5.
In some cases you want to give a subclass the right to set a new value, but you also want to validate the new value to meet certain security measures. For this you need to make sure the subclass has to use your method to set the new value and not be able to override it with it's own faulty method. Most languages provide the means to do this (UnrealScript allows you to mark a function as final, thus preventing it to be overwritten by a subclass). There is a trick to do this. Simply make the member private so it can't be accessed from the subclass and create protected accessor methods (get and set). In your set method you will validate the new value and pass it to the protected member. This way subclasses will have to use the parent set method in order to write the new value.
 //pseudo code

 var private string SensitiveInfo;

 protected function bool SetSensitiveInfo(string newValue)
 {
  if (newValue doesn't meet constraints) return false;
  SensitiveInfo = newValue;
  return true;
 }

 protected function string GetSensitiveInfo()
 {
  return SensitiveInfo;
 }