Sign in to follow this  
JasonHise

[.net] Dynamic resource compilation

Recommended Posts

[background info] I'm developing a tool for making cell based puzzle games. The idea is that the user can create a project, add sound, music and image resources, and add object scripts to handle how objects interact. An example of the code for a pushable block might look something like this:

OBJECT BLOCK
{
	SPRITE = "block.bmp"
	LAYER  = "OBJECT_LAYER"

	NOTIFY
	{
		MOVE_REFUSED
		{
			PLAY_SOUND "collide.wav"
		}
	}

	PERMISSIONS
	{
		HERO ENTER
		{
			IF MOVE THIS THIS.FACING
			{
				ALLOW
			}
			ELSE
			{
				DENY
			}
		}

		DEFAULT ENTER
		{
			DENY
		}
	}
}

My plan is to do some syntax checking, and then convert this and all of the other objects defined into a C# class which derives from a base class called Game. Then I would use CodeDOM or something like it to compile the C# code into a dll and throw it into a games directory. Another program would allow the user to select any game in that directory and make levels for it. [/background info] The problem I have is that I cannot find any information on compiling resources (the sounds, music, and images in the user's project) into a .NET assembly at runtime. Is this feature available? If so, how is it done? Thanks in advance.

Share this post


Link to post
Share on other sites
Compiling resources into an assembly at runtime is just a specialized case of runtime compilation. You mentioned CodeDOM, so I'm assuming you're already familiar with it. Run the compiler with the "/res:" switch: csc /res:myResourceFile.resources [...] by using the System.CodeDom.Compiler.CompilerOptions class. Here's some quick-n-dirty code that runs by the potential of CompilerParameters:

// ...

// Obtain an ICodeCompiler from a CodeDomProvider class.
ICodeCompiler compiler = provider.CreateCompiler();
CompilerParameters cp = new CompilerParameters();
// Generate a resource library rather than an executable (fails if you don't have an entry point).
cp.GenerateExecutable = false;
// Set the assembly file name to generate.
cp.OutputAssembly = "foobar.dll";
// Generate debug information.
cp.IncludeDebugInformation = true;
// Add an assembly reference.
cp.ReferencedAssemblies.Add("System.dll");
// Save the assembly as a physical file.
cp.GenerateInMemory = false;
// Set the warning level at which the compiler should abort compilation if a warning of this level occurs.
cp.WarningLevel = 4;
// Set whether to treat all warnings as errors.
cp.TreatWarningsAsErrors = false;
// Set compiler argument to optimize output.
cp.CompilerOptions = "/res:myResourceFile.resources /optimize";

[...]

CompilerResults cr = myCompiler.CompileAssemblyFromFile(cp, "mySourceFile.cs");

if (cr.Errors.Count > 0)
{
Console.WriteLine("Errors found!");
foreach (CompilerError ce in cr.Errors)
{
Console.WriteLine("--> {0}", ce.ToString());
}
}



Good luck. Sounds like a fun project!

Share this post


Link to post
Share on other sites
I'm not very familiar with command line compiler flags... would I pass in all the resources I wanted to compile after the res:, separated by commas? Or is the .resources a special type of file that somehow referances all the other resources?

Share this post


Link to post
Share on other sites
Quote:
Original post by 0xCHAOS
I'm not very familiar with command line compiler flags... would I pass in all the resources I wanted to compile after the res:, separated by commas? Or is the .resources a special type of file that somehow referances all the other resources?

You can use any arbitrary file with the /res switch and it'll be embedded in your assembly or output file. I was only using the .resources file as an example. You'll need a separate /res switch for each file you want to embed, e.g. "/res:foo.wav /res:bar.avi /res:quux.doc".

A .resources file is a file containing arbitrary data (bitmap image, sound file, whatever); a .resx file is a .resources file in XML format.

Share this post


Link to post
Share on other sites
When someone else posted something similar, someone said that you should run the code in another app domain (i think) so that a rogue script is inhibited.

Share this post


Link to post
Share on other sites
Quote:
Original post by 0xCHAOS
I'm not very familiar with command line compiler flags... would I pass in all the resources I wanted to compile after the res:, separated by commas? Or is the .resources a special type of file that somehow referances all the other resources?

This just appeared a couple of days ago and may be a great interest to you or anyone working with the command line compiler.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this