greenhouse
a creative coding toolkit for spatial interfaces

Proteins

Plasma provides Greenhouse’s framework for inter-object, inter-process, and inter-machine messaging.

It’s important to note that Greenhouse applications are single-threaded. Metabolizing (processing) of messages is done on the main run loop. Any slow computations in your message-handling code will slow down the application’s frame rate.

  • ProteinWithDescrip ()
  • AppendDescrip ()
  • AppendIngest ()
  • Deposit ()
  • ParticipateInPool ()
  • Metabolize ()
  • ListenForDescrip ()
  • HasDescrip ()
  • HasIngest ()
  • Ingest ()
  • ImageDataFromIngest ()
  • SaveProtein ()
  • LoadProtein ()

Example

//create several imageholders, load an image into it, and
//update from a deposited protein via a pointer harden

#include "Greenhouse.h"

class UpdatableImgHolder  :  public Image // subclassing from Thing
{ public:

  Image *uih;

  UpdatableImgHolder (const Str &s)  :  Image (s)
    { SetCornerRadius (0);
      SetScale (.25);

      ParticipateInPool ("tex_updater");
    }

  void Metabolize (const Protein &p)
    { if (HasDescrip (p, "switch_image"))
        { if (HasIngest (p, "new_tex"))
            { ImageData *i = ImageDataFromIngest (p, "new_tex");
              SetImage (i);
            }
          if (HasIngest (p, "tex_description"))
            { Str s = Ingest <Str> (p, "tex_description");
              INFORM ("the new image for " + Name () + " is " + s);
            }
        }
    }

  void PointerWithinKid (PointingEvent *e, Node *kid)
    { if (IsHardened (e))
        PointingInsideHarden (e);
      else
        PointingSoften (e);
    }

  void PointingInsideHarden (PointingEvent *e)
    { if (IsHeedless ())
        Heed (e);
    }

  void PointingMove (PointingEvent *e)
    { if (IsHeeding (e))  //  drag the object
        IncTranslation (IntersectionDiff (e, Loc ()));
    }

  void PointingSoften (PointingEvent *e)
    { if (IsHeeding (e))
        StopHeeding ();
    }
};

class ProteinDepositor  :  public Thing
{ public:

  int current_int_for_tex;

  ProteinDepositor ()  :  Thing ()
    { current_int_for_tex = int (Random (1, 7)); }

  Protein CreateProtein ()
    { Protein temp_p = ProteinWithDescrip ("switch_image"); //TODO
      if (current_int_for_tex % 2 == 1)
        AppendDescrip (temp_p, "main_box");

      INFORM (ToStr (current_int_for_tex));
      Str filename = "box_0" + ToStr (current_int_for_tex) + ".png";
      ImageData *replacement_imgdata = Image::FetchImageData ("images/" + filename);
      AppendIngest (temp_p, "new_tex", replacement_imgdata);
      AppendIngest (temp_p, "tex_description", filename);

      return temp_p;
    }

  void PointingHarden (PointingEvent *e)
    { current_int_for_tex = int (Random (1, 7));

      Protein p = CreateProtein ();
      Deposit (p, "tex_updater");
    }

  void Blurt (BlurtEvent *e)
    { if (Utters (e, "s"))
      { Protein p = CreateProtein ();

        SaveProtein (p, "current_tex.protein");
        Protein p2 = LoadProtein ("current_tex.protein");
        if (HasDescrip (p2, "switch_image"))
          INFORM ("successful save and load of current_tex.protein");
      }
    }
};

void Setup ()
{ new ProteinDepositor ();

  UpdatableImgHolder *uih01 = new UpdatableImgHolder ("images/box_02.png");
  uih01 -> SlapOnFeld ();
  uih01 -> ListenForDescrip ("main_box");

  UpdatableImgHolder *uih02 = new UpdatableImgHolder ("images/box_03.png");
  uih02 -> SlapOnFeld ();
  uih02 -> IncTranslation (Feld () -> Over () * 50);

  UpdatableImgHolder *uih03 = new UpdatableImgHolder ("images/box_01.png");
  uih03 -> SlapOnFeld ();
  uih03 -> IncTranslation (Feld () -> Over () * -50);
}