Re: [Vala] Immutable ref-counted objects?



Jim Peters wrote:
Java has partial support for immutable GC'd objects by marking all
public variables in the class as 'final'.  So long as all the
referenced objects are also immutable objects, then everything works
out.  The objects can be freely passed around without fear that some
caller will modify something and break some other distant code's
assumptions.

- [Compact] [Immutable]: copied, not ref-counted

Using [Compact] [Immutable] would be ideal, since for immutable data I
don't need GObject features.  A couple of attempts to get ref-counting
to work both involved 'cheating', and the compiler still didn't stop
me modifying the values I wanted to keep immutable.  So I guess this
kind of thing isn't supported for now.

For reference my attempts are attached below.  

For now I'm using properties like this, which seem less expensive than
'private set', and do work as intended:

  private int _x;
  public int x { get { return _x; } }

Jim

------------------------------------------------------------------------

[Compact]
[Immutable]
[CCode (ref_function = "uazu_test_incref", unref_function = "uazu_test_decref")]
public class Uazu.Test {
   public int refcnt;

//   public unowned Uazu.Test incref () { refcnt++; return this; }
//   public void decref () { if (--refcnt == 0) delete (void*)this; }
   public unowned Uazu.Test incref () { *((int*)(&refcnt)) = refcnt+1; return this; }
   public void decref () { int tmp = refcnt - 1; *((int*)(&refcnt)) = tmp; if (tmp == 0) delete (void*)this; }
   
   public int x;
   public int y;

   public Test(int x, int y) {
      this.x = x;
      this.y = y;
   }
}

public int main() {
   Uazu.Test t1 =  new Uazu.Test(12, 13);
   t1.x = 20;   // Want compiler to give error here
   
   stdout.printf("Test: %d, %d\n", t1.x, t1.y);
   return 0;
}
      
oselotl.jim> valac test1.vala
/w2/v/cwrk/vala/test1.vala.c: In function '_vala_main':
/w2/v/cwrk/vala/test1.vala.c:72: warning: assignment discards qualifiers from pointer target type
oselotl.jim> ./test1
Test: 20, 13

------------------------------------------------------------------------

public struct Uazu.RefCounter {
   public int refcnt;

   public unowned Uazu.RefCounter* incref () { refcnt++; return &this; }
   public void decref () { if (--refcnt == 0) delete (void*) (&this); }
}

[Compact]
[Immutable]
[CCode (ref_function = "uazu_ref_counter_incref", unref_function = "uazu_ref_counter_decref")]
public class Uazu.Test {
   public Uazu.RefCounter refcnt;
   
   public int x;
   public int y;

   public Test(int x, int y) {
      this.x = x;
      this.y = y;
   }
}

public int main() {
   Uazu.Test t1 =  new Uazu.Test(12, 13);
   t1.x = 20;   // Want compiler to give error here
   
   stdout.printf("Test: %d, %d\n", t1.x, t1.y);
   return 0;
}
      
oselotl.jim> valac test2.vala
/w2/v/cwrk/vala/test2.vala.c: In function '_vala_main':
/w2/v/cwrk/vala/test2.vala.c:103: warning: assignment discards qualifiers from pointer target type
/w2/v/cwrk/vala/test2.vala.c:108: warning: passing argument 1 of 'uazu_ref_counter_decref' from incompatible 
pointer type
/w2/v/cwrk/vala/test2.vala.c:48: note: expected 'struct UazuRefCounter *' but argument is of type 'struct 
UazuTest *'
oselotl.jim> ./test2
Test: 20, 13

------------------------------------------------------------------------   

-- 
 Jim Peters                  (_)/=\~/_(_)                 jim uazu net
                          (_)  /=\  ~/_  (_)
 UazĂș                  (_)    /=\    ~/_    (_)                http://
 in Peru            (_) ____ /=\ ____ ~/_ ____ (_)            uazu.net



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]