Laden...
Avatar #avatar-2376.jpg
Benutzerbeschreibung
Mag unkonventionelle Lösungen, am liebsten wenn sie garnicht gehen dürften.

Forenbeiträge von Floste Ingesamt 1.130 Beiträge

15.03.2010 - 21:18 Uhr

meine letzte info dazu war:

  • man kann assemblies nich entladen
  • man kann nur neue kontexte öffnen

Du meinst sicher appdomains und die kann man als ganzes entladen.

  • aber zwischen denen kann man wiederum nur per serialisierung daten übertragen
  • also keine referenzen

MarshalByRefObject und unmanaged zeiger gehen (keine gchandles, soweit ich weiß)

= sehr langsam

kommt drauf an was und wie man macht, es ist wenn mans richtig macht sogar halbwegs bequem.

bzw:

  • c# läuft im prinzip als "managed code".. wie in einer sandbox Sandbox heißt für mich, dass man nix kaputt machen kann so richtig. Das ist aber nicht der Fall, man kann standardmäßig mit pointern und pinvoke arbeiten, esseiedenn man setzt entsprechende restriktionen, dann ist es eine echte sandbox.
  • du hast keinen speicherzugriff auf externe komponenten

Wenn man keine restriktionen setzt, kann man pointer nehmen.

  • du kannst in diese sandbox ne dll reinladen
  • aber die bekommt man dann nich mehr raus

die sandbox kann man in verschidene domains unterteilen und diese einzeln entladen. Jede domain hat ihre eigenen Sicherheitsbestimmungen.

15.03.2010 - 18:58 Uhr

*Grr* das gibts doch garned! Ich kann einfach nix finden, dass ich daran auszusetzen hätte!

Spaß beiseite: MarsStein, du bist dran!

Ich hab MarsSteins code mal durch nen Compiler geschickt, das Resultat ist im Anhang.

15.03.2010 - 13:06 Uhr

Wie es zu den 2 Worten kam: Ich hatte grade den link rausgesucht und hatte ihn grade eingefügt, als es an der tür klingelte. Da die "mühe" nicht umsonst sein sollte, hab ich einfach schnell auf abschicken gedrückt und bin weggegangen, denn für jemanden, der sich mit p-invoke auskennt, ist das absolut ausreichend. Es war also keineswegs böse gemeint und hatte nix mit dir zutun.
Da sich aber sehr viele und vorallem leute, die solche Fragen stellen nicht besonders gut mit p-invoke und winapi auskennen hat es natürlich nicht gereicht.

Ich habe jetzt keine Ahnung, wieviel du davon schon kennst, also fange ich mal von vorn an: Manche Probleme, so wie deins, lassen sich mit dem Framework nicht oder nicht optimal lösen. Man kann aber Funktionen, die nicht direkt im Framework vorhanden sind, sondern zur Nativen Api gehören aufrufen, indem man die Methodensignatur mit dem Dllimport- Attribut in eine eigene Klasse schreibt.
Schon fertige Signaturen gibt es auf pinvoke.net (ich hab mal die Signatur von EnumWindows verlinkt)
Die Beschreibungen der Funktionen stehen auf msdn.

Für dein Problem brauchst du außerdem noch die Funktion GetWindowText.
Wenn du beide Beschreibungen und Signaturen und den Beispeilcode auf Pinvoke.net gelesen hast, bist du hoffentlich einen Schritt weter.

Irgendwie hab ich auf mycsharp so auf anhieb keinen artikel zu pinvoke gefunden.

10.03.2010 - 14:18 Uhr

Ich wusste garned, dass es hier noch andere asimov-fans gibt. 👍

08.03.2010 - 11:20 Uhr

einzelne User nur über Ihren Socket angesprochen werden.

Die einzige Alternative ist multicast, wobei du dann auf tcp verzichten musst und nicht ins Internet kommst => Scheiße!

warum legst du nicht einfach ne liste von clients an und machst


lock (connectedClients) foreach(Client c in connectedClients)
{
    c.Sende("irgendwas");
}

Ich sehe dein Problem nicht.

07.03.2010 - 20:16 Uhr

Ab windows vista gibt es eine traffic filtering api

07.03.2010 - 20:11 Uhr

Vorher wollte ich aber erstmal nach Alternativmöglichkeiten fragen.

Einzige Alternative: fertiges Protokoll nehmen.
Man kann .net remoting über tcp laufen lassen, das bringt sein eigenes Protokoll mit und man muss sich um sogut wie nix mehr kümmern, es is aber nicht unbedingt immer das schnellste (nicht für livestreaming oder actionspiele).

Absolute beginner's introduction to remoting

04.03.2010 - 18:51 Uhr

Theoretisch:ja, wegen konsequenter Programmierung
Praktisch: nein, denn sie verwenden vom garbage collector gemanagte Arrays,

01.03.2010 - 22:49 Uhr

du suchst "DesignerSerializationVisibility"-Attribut

28.02.2010 - 20:33 Uhr

... oder ein onload-Script generieren, das die Toggle-Funktion (für die gewünschten Elemente) aufruft - damit auch die Bildchen richtig gesetzt und die Höhen zwischengespeicher werden.

Besser nicht, dann kann man beim anfänglichen Zuklappen der Elemente zuschauen, während css sofort greift

Dies würde jedoch ein generiertes Script vorraussetzen. Wenn es diese Möglichkeit gibt, lassen sich dann tatsächlich einzelne oder alle Blöcke problemlos ein- und ausblenden.
(Meine Lösung geht bisher lediglich von einem statischen Script aus, mit generierten Teilen im HTML-Teil)

wieso sollte das nicht reichen?

Emittiert man einfach 2 verschidene css-klassen mit javascript:"eingeklappt" und "ausgeklappt" und weist im htmlteil den trs diese jeweils zu.
Wenn javascript aus ist, sind die klassen nicht definiert und alles ist siochtbar.
man kann natürlich alternativ auch ein script ins html generieren, mit schon beschriebenen Nachteil.

28.02.2010 - 16:07 Uhr

Also wenns so problemlos möglich ist wie Floste sagt, würde ich auch standardmäßig eingeklappt bevorzugen. Wenn man explizit zuklappen muss hat man doch kaum was von dem Feature.

Ich bin da für eine Benutzereinstellung, aber das ist herbivore wohl zu viel Arbeit, oder?

Ich würds sogar noch mehr bevorzugen wenn standardmäßig nen paar Zeilen gezeigt werden als Vorschau und man den Rest bei Bedarf aufklappen kann 😃 So könnt man beurteilen ob man den Quelltext weiter anschaun möchte und spart trotzdem Platz bei langen Quelltexten. Aber da weiß ich nicht ob sich sowas leicht umsetzen lässt. JavaScript ist net so mein Ding 😉

Zeilen abschneiden und wieder ransetzen ist schon etwas kompliziereter, aber noch möglich, allernings flackert es dann zwangsweise beim Laden.

Ich bin eher für eine zusätzliche Höhenbegrenzung mit scrollbalken, die ein 8und ausschaltbar ist. Das ist aber auchnicht trivial und wenn man kein php zur Hilfe nimmt, flackert es ebenfalls beim laden. (Auf dem Wege, wi ich jetzt denke, ich lasse mich gerne eines besseren belehren)

28.02.2010 - 14:55 Uhr

Dann aber bitte mit anständiger Implementierung und nicht wie ein Großteil der Klapptexte, die JavaScript voraussetzen, damit man die ausklappen kann. Das schließt sich durchaus NICHT aus!
Man kann mit javascript eine cssregel zum header hinzufügen, die die boxen einklappt.
Wenn javascript deaktiviert ist, wird diese Regel nicht erstellt und die Boxen sind auf.

Soweit ist das auch schon in meinen beiden Vorschlägen enthalten, die ich herbivore Gesendet habe.

Man kann es auch problemlos (was das Clientscrip angeht problemlos, wie es mit der Serverseite aussieht weiß ich nicht) ergänzen, dass nur ausgewählte Boxen betroffen sind.

27.02.2010 - 16:27 Uhr

Was man noch wissen sollte: nur die Winkeländerung angeben und bei matrizen kommt es darauf an, in welcher Reihenfolge sie multipliziert werden. Ansonsten musst du halt die matrix deines Meshes speichern:

Matrix meshMatrix=Matrix.Identity;//außerhalb der methoden
void RotiereX(float winkelÄnderung)
{
    meshMatrix=Matrix.RotationX(winkelÄnderung)*meshMatrix;
}
//Das gleiche für x,y,z....

void Zeichnen()
{
    device.WorldMatrix=meshMatrix;
    //zeichencode
}

Das ist schon alles. (esseiedenn du interessierst dich dafür, was hinter den Kunissen passiert.)

27.02.2010 - 11:15 Uhr

Speicher keine Winkel, sondern ne Matrix:
Matrix meshMatrix;

rotieren geht dann so:
neueMatrix=Matrix.RotationIrgendwas(winkel)*alteMatrix;

25.02.2010 - 22:55 Uhr

Dieses Verhalten interpretiere ich so, dass eben nicht die komplette Liste an eine andere Stelle im Speicher geschoben wird, sondern der neu angeforderte Speicherbereich an den bereits reservierten angehängt wird.

*hehem*
Vielleicht solltest du deine Behauptungen einmal selbst Reflektieren

25.02.2010 - 20:13 Uhr

Speicher mehr gibt, der groß genug ist, um die neue Liste aufzunehmen.

selbst dann ned immer
http://www.eggheadcafe.com/software/aspnet/30953784/why-virtualalloc-succeeds.aspx

25.02.2010 - 19:39 Uhr

haste ma den scancode eingetragen? irgendwie gibts sowas wie mapvirtualkey (oder ähnlich, auf mycsharp gibts was) und außerdem uipi und uac beachten

22.02.2010 - 19:26 Uhr

Ich kann dir auchned weiterhelfen. Ich stell aber einfach mal den source hier rein, dann kann jeder selber debuggen (ok, einiges ist etwas unschön vom programmierstil, aber passt schon) Konkret kannste mal die exe aus bin\dump starten und gucken, ob mitschnitte im ordner der exe erscheinen.

Aber wo ich bei der Fehlersuiche war bin ich über die Ursache davon gestolpert, dass bei manchen hier keine Netzwerkkarten erscheinen und hab ihn behoben. (uac lässt grüssen)

20.02.2010 - 23:32 Uhr

Directinput wird von vielen spielen verwendet und umgeht direkt die windowsnachrichten. das lässt sich wiederum umgehen

20.02.2010 - 15:17 Uhr

Ich hab keine lust auf dauernd neuinstallation, und noch bringt mir c# 4.0 nix, weil auf vielen rechnern noch nichtmal das servicepack 1 für framework 3.5 drauf is und ich msis für kleinere sachen doof find. Außderdem sieht die gui von den buttons doch ziemlich gleich aus. Gibt es neue funktionen, die wirklich nützlich sind (außer framefork 4.0)? Ich warte ich erstmal ein paar monate und gucks mir dann vielleicht an. 👅

15.02.2010 - 20:50 Uhr

Man kann sicher ein control erstellen in wpf und auf diesem dann slimdx einsetzen (nicht getestet).
Was sicherlich auch geht, ist dass man auf einem control wpf hostet und dieses auf oder neben der slimdx-fläche platziert.

Performanchetechnisch ist beides eher ungünstig und lässt keine transparenz zwischen den lagen zu.

Eine weitere möglichkeit (ich hqab sie nur so hlab verstanden) wird dort beschrieben. Wenns mit xna geht, gehts mit slimdx sicher auch: http://www.xnamag.de/article.php?aid=15

15.02.2010 - 14:44 Uhr

ich gebe immer zusätzlich noch doublebuffered=true an.
Ansonsten poste mal ne zusammenfdassung deines codes und guck dir mal folgenden code an: Programmier-Spiel

14.02.2010 - 13:20 Uhr

Google ist ned schlau, aber die programmierer wollten es schlau machen. deshalb probiert google jetzt bei webforms zufällige eingaben aus, und guckt was rauskommt, das ist die eine Seite, was google indiziert.
Die andere ist, dass dein Browser einen Referer sendet und manche (meistens unseriöse räusper) Seiten aus diesem den Suchbegriff nehmen und dann danach suchen. das ist dann natürlich nicht der Begriff, den google ursprünglich probiert hat, und deshalb kommt auch etwas anderes raus, als google indiziert hat. Als ergebnis kommt noch unseriöses und Werbung und davon leben die seiten.

12.02.2010 - 18:33 Uhr

meistens PictureBoxen verwendet.

Ganz schlecht, wenn man paint abboniert und picturebox ist sowieso mehr oder weniger überflüssig, seit es background-image gibt.

12.02.2010 - 17:12 Uhr

DoubleBuffered muss vor dem aufruf von OnPaint gesetzt sein, sonst hat es keinerlei effekt:

public MeinControl()
{
    InitializeComponents();
    SetStyle(OptimizedDoubleBuffer|alpaintingInWmPaint,true);
    DoubleBuffered = true;
}

Double buffering hat immer nur für das control, dem das paint-ereignis gehört effekt.
Wenn du also doubleBuffering für dein usercontrol anstellst, ist es für dein PANEL immernoch aus! Das ist auchd er Grund, warum es nicht geht.

Mach das Panel weg (Controls nicht als Zeichebereiche Missbrauchen!) und zeichne direkt auf dein usercontrol mit


protected override void OnPaint(object sender, PaintEventArgs e)
{
e.Graphics.TranslateTransform(x,y);//wo dein panel war
//zeichnen
}
09.02.2010 - 16:03 Uhr

Binary-Writer/-Reader 2.0 dem musst du ein memory stream übergeben und hinterher steam.ToArray() aufrufen

08.02.2010 - 17:30 Uhr

Da es programmier-SPIEL heißt, dachte ich, es kann auch mal ein spiel rauskommen.

Das wird, wenn es auch keine besonders anspruchsvolle Aufgabe ist, doch eine recht Lange.
Spielidee: Man schießt aus der Mitte mit Geschossen herumfligende Brocken ab, damit diese einem nicht zu nahe kommen.

Um die Sache einfach zu halten ist alles rechteckig:
-Das Spielfeld ist 500x500 Pixel groß
-Genau in der Mitte ist ein zu verteidigendes Quadrat, das 20x20 Pixel groß ist
-Aus der Mitte herkommend kann man zum Mauszeiger hin 10x10 große Quadrate (am besten rot) schießen, die sich mit 200px/sekunde Fortbewegen
-Von oben herab regnet es Rechtecke, die 10 bis 50px Seitenlänge haben , sich mit 50 bis 100px/Sekunde nach unten bewegen und mit -50 bis +50px/Sekunde seitwärts bewegen. Sie behalten genau wie die Geschosse ihre Richtung und Größe bei. Die Blöcke sollen sich von Geschossen und dem Hintergrund abheben. Alle Werte sollen innherhalb der Vorgaben möglichst zufällig sein.
-Wenn ein Geschoss einen Block trifft, verschwinden Beide, es wird aber ein neuer Block erzeugt, sodass die Blockanzahl konstant ist.
-Wenn ein Block das Spielfeld verlässt, wird er zerstört und ein neuer erzeugt.
-Wenn ein Geschoss das Spielfeld verlässt wird es ersatzlos zerstört.
-Alle 5 Sekunden kommt ein Block hinzu, am Anfang gibt es genau 5 Stück.
-Wenn ein Block die mitte erreicht hat man verloren und die zeit wird angezeigt.
-Man kan alle 250ms schießen.
-Blöcke haben mit anderen blöcken keine kollision, selbiges gild für geschosse. (ok, eine Variante mit Blockkollision wäre auch mal lustig.)

-Für Grafik sollte Gdi reichen (bitte flackerfrei), anderes ist erlaubt

-Markus111 ist, weil er die Lösung kennt ausgeschlossen.
-Alle, die sich das Programm von markus111 geholt haben sind ebenfalls ausgeschlossen.

Damit es nich so lange dauert, ist heir ein Stub, man muss ihn aber nicht unbedingt benutzen und kann ihn abwandeln.
Tipp1: eine for-Schleife rückwärts ist hilfreich!
Tipp2: rectangle.IntersectsWith testet Kollision!

public class Asteriods : Form
    {
        public Asteriods()
        {
            this.Size = new Size(500, 500);
            this.FormBorderStyle = FormBorderStyle.FixedDialog;
            SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint,true);
            DoubleBuffered = true;
            sw = new Stopwatch();
            sw.Start();
            //TODO:Ergänzen
        }

        Stopwatch sw;
        float nowMilliseconds=0;
        float lastShot = 0;
        Random rnd = new Random();
        List<Particle> asteroids=new List<Particle>();
        List<Particle> missils=new List<Particle>();
        RectangleF center;

        protected override void OnPaint(PaintEventArgs e)
        {
            float timeOffset = sw.ElapsedMilliseconds - nowMilliseconds;
            UpdateParticles(missils, timeOffset);//bewegen und aussortieren, was aus dem Rahmen fällt
            UpdateParticles(asteroids, timeOffset);
            //TODO:Ergänzen

            using (SolidBrush sb = new SolidBrush(Color.Green))
                e.Graphics.FillRectangle(sb,center);
            foreach (Particle p in asteroids.Concat(missils))
            {
                using (SolidBrush sb = new SolidBrush(p.c))
                    e.Graphics.FillRectangle(sb, p.rect);
            }
            nowMilliseconds += timeOffset;
            Invalidate();
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            //TODO:Ergänzen
        }

        class Particle
        {
            public RectangleF rect;
            public float speedx;
            public float speedy;
            public Color c;
        }
    }

ps: inklusive gegebenen Code und using-krimskrams hab ich 122 Zeilen gebraucht
wenn man tipp1 beachtet gibts in meinen Augen auch keinerlei "fallen" mehr.

07.02.2010 - 22:17 Uhr

Funkt bei mir:

public static void Main()
        {
            int[] zahlen = new int[6]
            {
                0,//0
                0,//1
                4,//Uboot(2)
                3,//Kreutzer(3)
                2,//Zerstörer(4)
                1,//Schlachtschiff(5)
            };

            int[,] feldx = new int[10, 10];
            int[,] feldy = new int[10, 10];
            for(int x=0;x<10;x++)
                for (int y = 0; y < 10; y++)
                {
                    feldx[x, y] = 10 - x;
                    feldy[x, y] = 10 - y;
                }
            Random rnd = new Random();
            for (int i = zahlen.Length - 1; i >= 0; i--)
            {
                for (int i2 = zahlen[i] - 1; i2 >= 0; i2--)
                {
                    int xcount = feldx.Cast<int>().Count((f) => f >= i);
                    int ycount = feldy.Cast<int>().Count((f) => f >= i);
                    int c = rnd.Next(xcount + ycount);
                    if (c < xcount)
                    {
                        for(int x=0;x<10;x++)
                            for (int y = 0; y < 10; y++)
                            {
                                if (feldx[x, y]>=i)
                                {
                                    if (c > 0)
                                    {
                                        c--;
                                    }
                                    else
                                    {
                                        for (int ilen = 0; ilen < i; ilen++)
                                        {
                                            Set(x,y,feldx,feldy);
                                            x++;
                                        }
                                        goto breakout;
                                    }
                                }
                            }
                    breakout:{}
                    }
                    else
                    {
                        c -= xcount;
                        for (int x = 0; x < 10; x++)
                            for (int y = 0; y < 10; y++)
                            {
                                if (feldy[x, y] >= i)
                                {
                                    if (c > 0)
                                    {
                                        c--;
                                    }
                                    else
                                    {
                                        for (int ilen = 0; ilen < i; ilen++)
                                        {
                                            Set(x, y, feldx, feldy);
                                            y++;
                                        }
                                        goto breakout;
                                    }
                                }
                            }
                    breakout: { }
                    }
                }
            }

            for (int y = 0; y < 10; y++)
            {
                for (int x = 0; x < 10; x++)
                {
                    if (feldx[x, y] == -1 && feldy[x, y] == -1)
                        Console.Write("X");
                    else
                        Console.Write(".");
                }
                Console.WriteLine();
            }
            Console.ReadLine();
        }

        private static void Set(int x, int y, int[,] feldx, int[,] feldy)
        {
            Setx(x, y, feldx);
            Setx(x, y + 1, feldx);
            Setx(x, y - 1, feldx);

            Sety(x, y, feldy);
            Sety(x + 1, y, feldy);
            Sety(x - 1, y, feldy);
        }

        private static void Setx(int x, int y, int[,] feldx)
        {
            if (y < 0 || y >= 10) return;
            if (x < 9)
            {
                feldx[x + 1, y] = 0;
            }
            int dist = -1;
            for (int x2 = x; x2 >= 0; x2--)
            {
                if (feldx[x2, y] < dist) break;
                feldx[x2, y] = dist;
                dist++;
            }
        }

        private static void Sety(int x, int y, int[,] feldy)
        {
            if (x < 0 || x >= 10) return;
            if (y < 9)
            {
                feldy[x, y+1] = 0;
            }
            int dist = -1;
            for (int y2 = y; y2 >= 0; y2--)
            {
                if (feldy[x, y2] < dist) break;
                feldy[x, y2] = dist;
                dist++;
            }
        }
07.02.2010 - 18:45 Uhr

Tabellenstruktur der Blöcke im Zusammengang mit JavaScript auf dem Firefox. Kurz gesagt veränderte sich die Größe der Tabellenzelle mit dem eigentlichen Inhalt beim jedem Einklapp-Ausklapp-Zyklus.

gehts genauer? Für mich hört sich das gut an, weil man so nicht ewig über leeren platz scrollen muss.
Hast du das display oder visibility-attribut genommen?
Hast du es auf tr oder td angewendet?

Das einzige problem ist doch, dass die größe beim code-tag durch einen Container begrenzt wird, der den Header umschließt. Das einfachste wäre, diesen in den "body" zu verschieben.

BTW: wer jetzt schon dieses feature will, kann greasemonkey (firefox addon um mit javascript seiten zu verändern) nutzen. Dateindung vom Anhang ist eigendlich ".js"

05.02.2010 - 15:57 Uhr

Titel darf man mit ziemlicher sicherheit eigentlich nicht verwenden, wenn es eingetragene Marken sind. Alle Patente(!=Marke) laufen nach 20 Jahren ab und Patente aus Software, und Algorithmen sind in der EU verboten, ob Spielregeln undter Algorithmen fallen frage ich mich allerdings auch. Ist nur die Frage, ob die Verleger sich die mühe machen, gegen einen rechtlich vorzugehen, weil man ein nicht kommerzielles "fan"-remake macht.

Btw ich habe Monopoly nachprogrammiert und es hat sich noch keiner beschwert.

29.01.2010 - 22:31 Uhr

Mir wurde eben gesagt, dass das mit Reflection funktioniert, aber ich hab keine Ahnung wie man das macht.

Man kann das zwar mit Reflection machen, es ist, wenn du nicht grade mehr als 50 Eigenschaften hat, eher die umständliche Variante, die meistens auchnoch langsamer ist (Insbesondere die Methoden "setValue","GetValue" oder "Invoke" lassen sich oft wegoptimieren) und man macht sich unter Umständen Fehler ohne es zu merken rein.

Wenn es recht wenige Eigenschaften sind würde ich da wie folgt rangehen:

Dictionary<string,Action<Control,string>> setter=new Dictionary...;

setter["Text"]=(c,wert)=>{c.Text=wert;};
setter["ForeColor"]=(c,wert)=>{c.ForeColor=ParseColor(wert);};
.
.
.

Bei vielen Eigenschaften würde ich versuchen jeweils einen Delegaten auf den Setter der Eigenschaft zu holen.

27.01.2010 - 18:56 Uhr

Ich würde wenn möglich eher soetwas verwenden:

public static class ObjectRegister
{
    static minId=1;
    static Dictionary<int,WeakReference> dict=new Dictionary...;
    internal static int _register(IdObject obj)
    {
        int id=minId++;
        lock(dict)dict[id]=new Weakreference(obj);
        return id;
    }

    internal static _unregister(IdObject obj)
    {
        dict.Remove(obj.Id);
    }

    public object getById(int id)
    {
        WeakReference w;
        if(dict.TryGetValue(id,out w))return w.object;//oder ähnlich
    }
}

//alle Klassen hiervon ableiten:
public abstract class IdObject
{
    public IdObject()
    {
        id=ObjectRegister._register(this);
        isOriginal=true;
    }
    
    int id;
    public int Id
    {
        get {return id;}
    }

    [NonSerialized()]
    bool isOriginal;
    public bool IsOriginal
    {
        get{return isOriginal;}
    }
    
    ~IdObject()
    {
        if(isOriginal)
        {
            ObjectRegister._unregister(this);
        }
    }
}
26.01.2010 - 21:20 Uhr

Beschreibung:

Normalerweise kann man keine zeiger auf Variablen generischer Typen erstellen. Der folgende Code macht aber genau das. Man muss aber aufpassen, dass man nur mit Zeigern weiterarbeitet, während das Objekt als ref-Parameter an eine belibige Methode übergeben wurde, denn das entspricht von den Opcodes exakt einem fixed-statement oder das Objekt direkt auf dem Stack liegt.

Man kann mit der Methode gut strukturen in bytearrays kopieren (und umgekehrt). Das geht sogar 4x soschnell wie mit den marschal-methoden.

using System;
using System.Reflection;
using System.Reflection.Emit;

using BF = System.Reflection.BindingFlags;
using System.Runtime.InteropServices;

namespace Krimskrams
{
    public static class UnsafeHelper
    {
        /// <see cref="UnsafeHelper<T>.GetPtr"/>
        public static unsafe void* GetPtr<T>(ref T arg) where T : struct
        {
            return UnsafeHelper<T>.GetPtr(ref arg);
        }

        
        public static unsafe void MoveMemory<T1, T2>(ref T1 dest, ref T2 src, int size)
            where T1 : struct
            where T2 : struct
        {
            MoveMemory(UnsafeHelper<T1>.GetPtr(ref dest), UnsafeHelper<T2>.GetPtr(ref src), size);
        }

        public static unsafe void MoveMemory<T>(ref T dest, void* src, int size) where T : struct
        {
            MoveMemory(UnsafeHelper<T>.GetPtr(ref dest), src, size);
        }

        public static unsafe void MoveMemory<T>(int numDestObjs,ref T dest, void* src) where T : struct
        {
            MoveMemory(UnsafeHelper<T>.GetPtr(ref dest), src, numDestObjs * UnsafeHelper<T>.Size);
        }

        public static unsafe void MoveMemory<T>(void* dest, ref T src, int size) where T : struct
        {
            MoveMemory(dest, UnsafeHelper<T>.GetPtr(ref src), size);
        }

        public static unsafe void MoveMemory<T>(void* dest,int numSrcObjs, ref T src) where T : struct
        {
            MoveMemory(dest, UnsafeHelper<T>.GetPtr(ref src), numSrcObjs * UnsafeHelper<T>.Size);
        }
            
        [DllImport("Kernel32.dll", EntryPoint="RtlMoveMemory", SetLastError=false)]
        public static unsafe extern void MoveMemory(void* dest, void* src, int size);

        /// <remarks>Schneller bei mehrmaligem Aufruf! Anders als bei Marshal.SizeOf wird char mit 2 bytes übersetzt!</remarks>
        /// <see cref="UnsafeHelper<T>.Size"/>
        public static int SizeOf<T>()
        {
            return UnsafeHelper<T>.Size;
        }

        /// <remarks>Langsamer bei mehrmaligem Aufruf. Anders als bei Marshal.SizeOf wird char mit 2 bytes übersetzt!</remarks>
        public static int SizeOf(Type type)
        {
            object[] attrs=type.GetCustomAttributes(typeof(StructLayoutAttribute), false);
            if (attrs.Length > 0)
            {
                StructLayoutAttribute attr = (StructLayoutAttribute)attrs[0];
                if (attr.Size > 0) return attr.Size;
            }

            if (type.IsPrimitive)
            {
                if (type == typeof(IntPtr))
                    return IntPtr.Size;

                if (type == typeof(double) ||
                    type == typeof(long) ||
                    type == typeof(ulong))
                    return 8;

                if (type == typeof(float) ||
                    type == typeof(int) ||
                    type == typeof(uint))
                    return 4;

                if (type == typeof(char) ||
                    type == typeof(short) ||
                    type == typeof(ushort))
                    return 2;

                if (type == typeof(bool) ||
                    type == typeof(sbyte) ||
                    type == typeof(byte))
                    return 1;
            }
            else if (type.IsPointer)
            {
                return IntPtr.Size;
            }
            else if (type.IsValueType)
            {
                int sum = 0;
                foreach (FieldInfo info in type.GetFields(BF.Instance | BF.Public | BF.NonPublic))
                {
                    sum += SizeOf(info.FieldType);
                }
                return sum;
            }
            throw new NotSupportedException(type.FullName);
        }
    }

    public static class UnsafeHelper<T>
    {
        public unsafe delegate void* getPtrFunc(ref T value);
        public unsafe readonly static getPtrFunc GetPtr = BuildFunction();
        public static readonly int Size = UnsafeHelper.SizeOf(typeof(T));
        private static DynamicMethod method;

        private unsafe static getPtrFunc BuildFunction()
        {
            method = new DynamicMethod("getPtr<" + typeof(T).FullName.Replace(".", "<>") + ">",
                typeof(void*), new Type[1] { typeof(T).MakeByRefType() }, typeof(UnsafeHelper).Module);

            ILGenerator generator = method.GetILGenerator();
            generator.Emit(OpCodes.Ldarg_0);
            generator.Emit(OpCodes.Conv_U);
            generator.Emit(OpCodes.Ret);
            return (getPtrFunc)method.CreateDelegate(typeof(getPtrFunc));
        }
    }
}

Schlagwörter: pointer generic generics

[EDIT] Unsinnige Methode entfernt
[EDIT2]
Überarbeitet:
Man kann jetzt ganze Arrays umkopieren. (einfach MoveMemory(anzahlArrayElemente,ref meinArray[0],meinZeiger); )

  1. @Peter: Ich habe versucht einen bequemen und sehr schnellen "binarywriter" für nicht verwalteten speicher zu schreiben. (für Grafikdaten)
25.01.2010 - 19:33 Uhr

Mich würde der Quellcode sehr interessieren, da ich selbst grad an eine Möglichkeit arbeite andere Rechner fern zu steuern.

Den Originalcode rücke ich nicht raus. (Das steht auch nicht zur Debatte!)
Du kannst wenn du magst einen blick in den Reflector werfen und dir sogar den quellcode in Dateien Packen lassen (gibt addins dafür).

Sendest nur nur nötige Teile des Bilschirminhaltes zur Aktualisierung?

Ich komprimiere mit jpack. ich habe zuerst versucht nur die nötigen ausschnitte zu senden. Ich war aber so blöd und hab 8x8-Blöcke genommen, ich glaube aber es könnte mit 16x16 gehen, da ich damals die farbunterabtastung nicht bedacht habe.
Jedenfalls sende ich jetzt ein quadrat, dass alle sichtbar veränderten pixel einschließt, was nicht unbedingt optimal ist, aber es geht halbwegs.

Wenn du den Netzwerkteil untersuchst: tu dir den gefallen und nimm meine Netzwerkbibliothek , die ist eine überarbeitete Version des Netzwerkteils der Fernsteuerung und man handelt sich nicht soviele Probleme ein. In meinem Monopoly habe ich die auch verwendet. Ansonsten könnte noch Binary-Writer/-Reader 2.0 interressant sein.

Sendinput geht sein UAC nurnoch bedingt, jenachdem wieviele Rechte der Client hat.

25.01.2010 - 12:51 Uhr

Kostenlose toplevel-domains gibts soweit ich weis nur mit eingeblendeter Werbung. Kostenlose Subdomains wirst du schon eher finden.

Ich bin mit meiner privaten homepage bei coolnic.de,
kostet 0,70€ je monat,
bietet 50mb mit statistik, php und mysql und phpmyadmin

24.01.2010 - 15:45 Uhr

ich würde jedem user eine queue geben, in der diezeitstempel der letzten nachrichten des benutzers gespeichert sind.. wenn der user eine nachricht senden will, werden zuerst alle elemente aus der queue genommen, die älter als 15 sekunden sind und wenn hinterher mehr als 5 elemente drin sind, darf der benutzer die nachricht nicht senden. wenn der benutzer die nachricht doch senden durfte, wird die zeit in die queue gepackt.

22.01.2010 - 23:01 Uhr

Floodfill mit echter rekursion ist sowieso echt...bescheuert.
-> Stack<Point>

20.01.2010 - 22:37 Uhr

Geht das nicht etwas einfacher?


int mul(int a,int b)
{
    if(a==0)return 0;
    return (((a&1)==0)?0:b)+mul(a>>1,b<<1);
}

20.01.2010 - 19:24 Uhr

Nächster Bugfix (aktuelle version): wenn man das spiel verlässt, können die anderen weiterspielen.

20.01.2010 - 12:43 Uhr

Ganz schön schwer, wenn man sich selbst was ausdenkt.
Ich hab einfach mal brute force try und error gemacht, braucht ewig für n≥5, aber die in dem bild da sind eh nur n=3:

public static void Main()
        {
            while (true)
            {
                int xpos, ypos, n;
                do { Console.Write("X="); }
                while (!int.TryParse(Console.ReadLine(), out xpos));
                do Console.Write("Y=");
                while (!int.TryParse(Console.ReadLine(), out ypos));
                do Console.Write("N=");
                while (!int.TryParse(Console.ReadLine(), out n));
                int num = 1 << (byte)n;
                int[,] feld = new int[num, num];
                feld[xpos, ypos] = -1;
                if (!BruteForce(feld, num, 1))
                {
                    Console.WriteLine("Nicht gelöst");
                }
                else
                {
                    for (int y = 0; y < num; y++)
                    {
                        for (int x = 0; x < num; x++)
                        {
                            Console.Write(feld[x, y].ToString().PadRight(3));
                        }
                        Console.WriteLine();
                        Console.WriteLine();
                    }
                }
            }
        }


        private static bool BruteForce(int[,] feld, int num, int tiefe)
        {
            for (int y = 0; y < num; y++)
                for (int x = 0; x < num; x++)
                    if (feld[x, y] == 0)
                    {
                        Point[] points = new Point[3];
                        for (int square = 0; square < 4; square++)
                        {
                            int sx = (square & 1) + x - 1;
                            int sy = ((square & 2) >> 1) + y - 1;
                            for (int ep = 0; ep < 4; ep++)
                            {
                                int i = 0;
                                for (int p = 0; p < 4; p++)
                                {
                                    if (p != ep)
                                        points[i++] = new Point(
                                            (p & 1) + sx,
                                            ((p & 2) >> 1) + sy);
                                    else if (((p & 1) + sx == x) && (((p & 2) >> 1) + sy) == y) goto bad_ep;
                                }
                                if (TrominoTesten(feld, num, tiefe, points)) return true;
                            bad_ep: { }
                            }
                        }
                        return false;
                    }
            return true;
        }

        private static bool TrominoTesten(int[,] feld, int num, int tiefe, IEnumerable<Point> points)
        {
            foreach (Point p in points)
            {
                if (p.X < 0 || p.X >= num) return false;
                if (p.Y < 0 || p.Y >= num) return false;
                if (feld[p.X, p.Y] != 0) return false;
            }
            foreach (Point p in points)
                feld[p.X, p.Y] = tiefe;
            if (BruteForce(feld, num, tiefe+1)) return true;
            foreach (Point p in points)
                    feld[p.X, p.Y] = 0;
            return false;
        }
19.01.2010 - 19:18 Uhr

Auf codeproject hat mal jemand die textbox neu erfunden (auso neu geschrieben) und die kann transparenz.

17.01.2010 - 21:51 Uhr

einen nicht-statischen wrapper für die statische property erstellen?

17.01.2010 - 21:42 Uhr

Wenn ich schon exakt genau weis, was das programm macht und welche knöpfe man braucht, dann klicke ich mir meistens erstmal ein gui zusammen (grober entwurf), aber ohne Funktion (ok ob das sinnvoll ist, sei mal dahingestellt) Mir hilft es aber manchmal zu sehen, was ich alles noch alles vergessen hab, wenn ich schon einen guientwurf habe.

sobald dann ein teil der logik fertig ist, verbinde ich den mit der gui und bessere diese nach bzw erstelle sie erst. Gui kann man natürlich erst ausprogrammieren, wenn die öffentlichen member der objekte, auf den der teil der gui zugreift jeweils definiert sind.

Bei professionellen Projekten werden erste die schnitstellen und klassen geplant und danach kann man direkt loslegen, egal wo, mir ist das zu aufwändig, weil ich eh immer die hälfte vergesse, deshalb mach ich erst die logik.

Man sollte sich eigentlich beim Entwurf aber nicht zusehr von der gui leiten lassen und sich nicht dazu verleiten lassen, guielemente in datenobjekten zu speichern.

Ich bin aber nur hobbyist und hab eher nur kleinere sachen gemacht (bis jetzt).

16.01.2010 - 19:37 Uhr

Netzwerkteil ist hinzugefügt, aber nur kurz getestet.
[EDIT]-Ein Fehler, der auf umlauten+ascii-codierung beruhte beseitigt,

  • Einen Fehler entdeckt, der manchmal auftritt, wenn das Spiel soweiso endet, habe den Grund nochnicht gefunden.
10.01.2010 - 15:46 Uhr

Ich war sehr übereifrig bei nem schulprojekt und habe viel weiter gemacht, als eigentlich nötig (gesamte gui). ich finde das Ergebnis kann sich halbwegs sehen lassen.

Ich habe allerdings weder bots noch netzwerkteil integriert. (Habe es aber so Designt, dass beides ohne große Änderungen ergänzt werden kann, ich habe allerdings nicht wirklich Lust dazu)

wer mal nen Rechtsklick macht und die Maus bewegt, wird wahrscheinlich eine überraschung erleben 😉 (ist aber wirklich nur gdi+ und etwas mathe).

07.01.2010 - 23:31 Uhr

Meinst du mit dem VSync nicht diese Eigenschaft, dass gewartet wird, bis das gesammt Bild gerendert ist und es dann erst auf den Bildschirm kopiert wird?

Wird auch ohne vsync gemacht, also nein

Das würde doch nichts an der Wartezeit ändern...oder meinst du das garnicht?

vsync heißt, dass gewartet wird, bis der bildschirm ein komplett neues bild bekommt und nicht in der mitte des Bildes plötzlich das Bild getauscht wird. Es wird also auf die Bildschirmframerate gewartet.

http://forums.techpowerup.com/showthread.php?t=68589 (ich hoffe, du kannst englisch)