Page 1 of 1

CS Plugin System Help

Posted: Tue Jan 13, 2009 3:51 pm
by grimdoomer
Well I'm working on a couple apps that depend on a modified version of shade45 and Anthonys CS plugin system. Now here is my issue. I parse out the tag, then I want to filter the reflexives into a list. But I can't seem to find the right object to get the value with. Here is my code:

Code: Select all

public Chunk Plugin;

private void FilterReflexives()
        {
            FieldInfo[] fields = Plugin.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);
            for (int i = 0; i < fields.Length; i++)
            {
                FieldInfo f = fields[i];
                if (f.FieldType.IsGenericType && (f.FieldType.GetGenericTypeDefinition() == typeof(Reflexive<>)))
                {
                    Reflexives.Add((Reflexive<Chunk>)f.GetValue(Plugin));
                    Reflexives.AddRange(((Reflexive<Chunk>)f.GetValue(Plugin)).FilterReflexives().ToArray());
                }
            }
        }
Here is the exception:
System.InvalidCastException was unhandled
Message="Unable to cast object of type 'HaloObjects.Reflexive`1[HaloObjects.sbsp+Collision_MaterialsBlock]' to type 'HaloObjects.Reflexive`1[HaloObjects.Chunk]'."

Note: I set the fields value with the Plugin object, but it doesn't work when I try to retrive it that way.

Posted: Tue Jan 13, 2009 6:48 pm
by LuxuriousMeat
Does "HaloObjects.sbsp.Collision_MaterialsBlock" inherit from "HaloObjects.Chunk"?

Posted: Wed Jan 14, 2009 3:02 am
by grimdoomer
Yes.

Posted: Wed Jan 14, 2009 3:24 am
by kornman00
Even if the type parameter used in a generic type is a class which inherits from a class you're using in another instance of the same generic type, you can't cast it.

In simpilar terms, you can't do the following:

Code: Select all

List<StreamWriter> writers = ...

List<Stream> streams = writers; // can't. same with explicit conversion or an 'as' operator
With that said, what you're trying to do with that code isn't feasible in its current direction. Which is why they made abstraction

Posted: Wed Jan 14, 2009 11:47 am
by grimdoomer
Ok so if my reflexive look like this:

Reflexive<Collision_MaterialsBlock> Collision_MaterialsBlock
Reflexive<Collision_BspBlock> Collision_BspBlock
Reflexive<LeavesBlock> LeavesBlock

How do I get them like this:

Reflexive<Chunk> Collision_MaterialsBlock
Reflexive<Chunk> Collision_BspBlock
Reflexive<Chunk> LeavesBlock

If I can't cast them to a class they inherit?

Posted: Wed Jan 14, 2009 1:52 pm
by kornman00
The thing is, you're not casting them to a class they inherit from. "Reflexive<Collision_MaterialsBlock>" doesn't inherit from "Reflexive<Chunk>".

You're going to have to create a "Reflexive<Chunk>" then add each element in "Reflexive<Collision_MaterialsBlock>" one by one, or call List<>.ToArray() to add it by range. However this is not performance nor memory (let alone design) efficient. I suggest you actually learn about generic types and also about interfaces before you try to implement what you're trying to do.

Posted: Wed Jan 14, 2009 5:29 pm
by grimdoomer
After looking at some of shde45 and Anthonys code again, I saw they converted it to an IList. After try it myself I got it to work.

I know this isn't efficient as it takes a lot longer then xml. But I like it because it automatically parses the tag.

Posted: Thu Jan 15, 2009 8:57 am
by kornman00
There are more efficient ways to implement what you're doing, while keeping the definition process in actual source code and not XML. I didn't mean to sound as if I was backing the xml avenue of approach. But you got what you wanted, so all is well in the end I guess

Posted: Thu Jan 15, 2009 11:50 am
by grimdoomer
How would you do it?