Thursday, June 25, 2009

My Reflection

The other day I had some trouble with ASP.Net. I was saving a class I'd written into the ViewState (I did this a long time ago, I know now that that might not be the best idea) and it was giving me errors saying that the ViewState was corrupted somwhere around saving it into or loading it from the ViewState.

I had to fix this, but I still needed all the information inside the class. Even though I knew that it was not the right thing to do really and in the end proved to be seriously useless since another measure I took apparently removed the need of saving it in the ViewState altogether.

I did find a solution that worked before the other thing started to take over. I wrote 2 functions, one to save the info in the object into the ViewState and one to load it again.
using System;
using System.Reflection;

namespace My.NameSpace
{
class MyClass
{
private void savetoViewState(MyObj saveobject)
{
Type t = saveobject.GetType();
foreach (PropertyInfo info in t.GetProperties())
{
object value = info.GetValue(saveobject, null);
if (value != null && test.GetType().Namespace == "System")
ViewSate["myobj_" + info.Name] = value;
}
}

private MyObj loadfromViewState()
{
MyObj myObj = new MyObj();
Type t = myObj.GetType();

foreach (PropertyInfo info in t.GetProperties())
{
object obj = ViewState["myobj_" + info.Name];
if (obj != null)
info.SetValue(myObj, obj, null);
}

return myObj;
}
}

class MyObj
{
public string Name
{
get;
set;
}

public int Number
{
get;
set;
}
}
}
In the save function we get the type of the object we're working with, because the type class has some very nice reflection functions, among which are GetProperties(), GetMethods(), GetContructors and many more.
We use the GetProperties method to get all the properties and we loop through them in a foreach loop. Now we can examine each property seperately.

We get the value of the property by calling the PropertyInfo.GetValue() method which requires the object from which to get the property (our argument in this case) and an object array of index values, so that you can, I'm guessing, get a or multiple items in an array. The index must be null of you're getting non-indexed properties.

Then we check if our value is null, because if it is we don't need to save it, and we check to see if the namespace of the property's type is System, which in my case made sure that I was only saving properties that were of type System.String or System.Int32 etc and not Some.NameSpace.In.My.Project.

Finally if our property's value gets through these checks, we save it in the ViewState with a prefix to identify it as part of our object.

In the load function we do something very similar. First we instantiate a new instance of our class and we again get the type of it.
Then we loop through all it's properties, much like we did in the save function.
Now, though, we get a value from the ViewState, which should correspond to what we saved in there before. Now if there is a property that we didn't save then getting it from the ViewState will of course result in null, so we check if the value if null. If it's not then we call the PropertyInfo.SetValue() method which needs the instance of the object it must place the value in, then the value that it must place and again like with GetValue() an object array of indexes.

Once we've looped through all the properties, it should again be filled with all the relevant information and we're good to get to work on it again.

This is my first little bit of Reflection that I've written to date. I know it's not much, but since I didn't know if MyObj was going to stay the way it was and I wanted it to work regardless. I also didn't feel like going ViewState["myobj_name"] = myObj.Name; over and over, since the object I was working with had many more properties than this example.

In the line with if (value != null && test.GetType().Namespace == "System") I had just gotten the value of the property, if it had one at all, and then I'm checking to see if the type of that property's namespace equals "System", this is because in the object I was working with also had a few properties that were connected to lazy-loaded database entities, which in turn also had these, and if I wanted to save these then it would have been a serious disaster (Damn how did I ever think that writing an object like that in the ViewState would just work...).

Anyway, it's fun to see how easy a simple reflection function can be. I'd read about it when I studied for my certificate exams and I saw some of it at the Microsoft Dev Days this year, but it always seemed complicated and strange to me. All the more reason to try it out somewhere.

Friday, June 5, 2009

SVN+SSH username trouble in Netbeans 6.5

Haha, I was having trouble with SVN in Netbeans. It was trying to log in with the wrong user. I could checkout fine by editing the tunnel parameters in the checkout window, but after that if I tried updating it'd use my local username instead of the one I use on the server.

After looking around a bit I found the answer!
In the checkout window, when asked for the url of your svn server, add your username to the url twice. so
svn+ssh://username@username@ip.address.of.server/location/of/svn/repository
should do the trick, apparently Netbeans only removes the first username@ from the url. I tested it and it does seem to work.

Thursday, June 4, 2009

Quick mail post

Linux has an excellent command: mail, now who can guess what it does?

Anyway, I was searching how to send something with this today even though I've looked at this before, it somehow got screwed up.
We only have mail on our server (and sendmail, but that seems way more complicated) and we need to send an attachment and have a sender address.

After looking around for a while I found this:
uuencode $writefile $readfile |\
mail -s "$subject" $recipient -- -r "$sender"

sorry if you don't like the use of variables in explanations, but this seemed easiest.
$writefileis the filename as the person recieving the email will see it (can be same as $readfile)
$readfileis the filename as it is stored on your hard drive
$subjectis of course the subject of the mail you are sending
$recipientis the email address of the person you're sending it to
$senderis the email address that others will see in the From: field in their mail

uuencode should encode the file so that it will show as an attachment instead of just binary giberish or plain text, but for me, in thunderbird, this doesn't work.
the '|' of course means that you're using the left command as input for the right one
and mail is the mail command.

Wednesday, June 3, 2009

No C++ at all today

I've only done a little bit of work on whatever it might be that I am working on today, but I did make some promising progress. I decided I might not be able to use the map and instead might use the vector, the only problem with vector is that it doesn't seem to have a find() function or anything similar.

I will work on it some more tomorrow and try to write some more.

No more C++ today

Alas, I was not able to write what I wanted to today, so I will not be able to post anything explaining what the hell I'm doing.
I will try again tomorrow though, maybe I'll be able to find some more then.

I know there's 2 people per year or something that stumble down here, but in case someone just happens to stumble down here tonight, here's my problem:
I've made a very simple class with only a few properties. I put this class in a set and when I try to do this:
myClass myclass;
mySet.insert(mySet.end(), myclass);

of course in what I'm working on this class is filled with data, but this is just a quick post. I might be missing something, since I'm tired and the NetBeans error messages confuse me.

Anyway, maybe a night of sleep and a day of work will improve my thinking capacity.
I think it might have something to do with comparison, since one of the messages I see when looking at Netbeans' output it seems to say that it doesn't have a > operator for __y > __x.

Hmm, must quit now, more to follow tomorrow.

Tuesday, June 2, 2009

C++: Some more stuff

I thought it might be best to write some extra info on the stuff I wrote yesterday about reading and writing stuff from and to files.

First thing is that I started off with a header (*.h) file. For those who really don't know C++ (pretty much like me then), these files are used to kind of 'define' the corresponding source files.
What we did in there was let whichever other file includes this one know that the source file that should come with this header file contains 1 class with 2 public functions, both returning void.

We then write those functions in the *.cpp file (which we should have named the same as the .h file, except change it's extension from .h to .cpp). In this file we use className::functionName to indicate that this function we're writing belongs the that previously (in the .h file) defined class. The '::' being the scope operator, you can use it to tell what which variable belongs to within your code.

I also seem to have forgotten to post the actual main.cpp file, sorry for this, It was late and I was both rushed and tired, but here it is:
#include "filerw.h"

int main()
{
FileRW filerw;
filerw.read();

return 0;
}
We include our header (.h) file so that the compiler knows where to look for that class we instantiate.

Now this is where it gets kind of weird for me. I'm used to writing in C#, so that first line would create a warning that filerw was never instantiated and at runtime an exception that filerw is null. Here though this seems enough to declare and instantiate. We then call the read() function from the class we wrote and it should work.

Our application will return 0 to let everything involved know that it exited correctly, any other value would mean that our application crashed.

As you can see I don't do anything with the write() function. We could, you could add a line write("anything"); there and it should do what you expect (append "anything" to the end of the file, if the file didn't exists yet, it should now have been created).

So I think this is all I can tell you right now, I'll try to write some more once I've written some more code.

Blue Dragon

A while ago I finished playing through Blue Dragon on the XBOX360. I've told myself that I should write something about each game I finish to improve on my writing skills.

Now Blue Dragon is a fun game that unfortunately suffers from some faults. It has a very typical story, typical main-character and of course the trademark look and feel from Akira Toriyama, creator of Dragonball.
Being from Akira Toriyama it is fun to walk around the world and see all the different species of creatures living together and co-operating with each other.

The battle system is old. It is unfortunately very repetitive and can get on your nerves from time to time. The thing that really bugged me is that none of the characters in the game have any real weapons or armor, so nothing changed on them through the entire game.
Monster fights are fun though, but they are (to me at least) too much of a hassle to get together all the time.
Balance is a little out of whack though, mostly Disc 1 is easy and you don't really have any trouble with anything or anyone, then Disc 2 becomes slightly annoying since there are a lot of fights and they take a few turns, and though the battles have ok animations they take a while to execute and you start falling asleep after a while, this is the point where I left my XBOX on for 2 weeks without playing.

Story is fun, but nothing spectacular. Boy and friends want to save village, they get lost, they get back, they leave for a big 'ol adventure.

I don't really have much else to say. I liked playing it, I loved getting through it (finally) and that's about it, it's not very remarkable in any respect (other then it's made by Akira Toriyama).

Monday, June 1, 2009

C++: Reading from and writing to a file

Me being the idiot that I am, I am not satisfied that I have just recently finally really gotten my random wallpaper script working with Python. Nooo, now I feel like a sell-out since I'd already written it in C++ once and unfortunately lost that somehow.
So now that it works in Python, of course I just had to decide to write it in C++ again too.
I found, though, that I am severely lacking in C++ knowledge. All the tutorials I followed almost a year ago now (I think it was at least 3) have all been next to lost from my mind.

Fortunately I had decided on completing a very simple task for today, since it was already 10pm when I started on this: Read all lines from a file and be able to write a line to a file, the rest will come later.

I started out with creating a header file that looked like this:
#include <string>

class FileRW {
public:
void add(std::string filename);
void read();
};
Declaring a class called FileRW and 2 public functions: add, read

Now for the simplest of implementations of these functions we're going to read a file with read() and add a line with write()

first we have to include
#include <iostream>
#include <fstream>
#include <string>
#include "filerw.h"
That last one is, of course, to include the header file I wrote before, which I called filerw.h

to keep it simple we'll also be
using namespace std;
otherwise we'd be writing std:: everywhere, which is just not so much fun really...

then the functions:
void PaperConfig::read() {
string line; // string where a line will be stored

// Open the file for reading
ifstream myfile("test.txt");
// If the file was opened
if (myfile.is_open()) {
// Until it reaches the end of the file
while (!myfile.eof()) {
// Get the next line
getline(myfile, line);

// If it's not an empty line, print it
if (line != "")
cout << line << endl;
}

// Close the file
myfile.close();
}
// If the file was not opened
else
cout << "Unable to open file";
}
We use ifstream (in file stream?) to open the file for reading.
We use the line variable as a temporary variable to store each line we read in so that we can write it to the console (or do something else with it). We use myfile.is_open() to check if the file could be opened, if not then it'll tell us and we use myfile.eof() to check if we have anything left to work with.
If the currently read line does not equal "" (an empty string).
When we're done we close the file.
void PaperConfig::add(string filename) {
// Open file for writing and set the append flag
ofstream myfile("test.txt", ios::app);

// Write filename to file
myfile << filename << endl;

// Close the file
myfile.close();
}
Here we use the ofstream (out file stream?) to open the file for writing and the ios::app flag to tell the stream to append whatever we write to the end of the file.
Then we write our parameter string to the myfile object like we write a lot of other things to cout and we add an endline character (endl)
Finally we close the file, this way we don't keep things in memory we don't need to.

Now I hope I have explained enough in this post, I don't often write things like this (in case you don't get it this is my version of a tutorial, but even I can't really call it that because it is writting in about 30 minutes) so if you see room for improvement please let me know. I will try to write more things like this in the future and hope to get better at writing, C++ and software development in general.