Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Simple Screen Carrier V1 (ssc.lib v1)

Hi, today i updated my simple screen carrier library. Now it can do many cool things.

Main features of new version:

  1. Pre-event and pos-event user-defined function calls
  2. Global variables overload
  3. Simple Codea-like I/O interface
  4. Pastebin access
  5. Shorter code
  6. All code are comented now

Library description:

This library contains two classes:

Struct_touch class:

First is "struct_touch" that represents information about touch-event in non constant form, also it has some service functions for main class("screen").

Screen class:

Second class is main class of the library. It is named "screen".
It represents part of the main screen as single frame with it's own drawing and touching space(or coordinate system, named it as you wish).
Also it is a container that automatically scrolls draw- and touch-event thru all of it members(object that contains in this container).
As part of main screen it automatically track WIDTH and HEIGHT global values and device orientation and corrects self width, height and position on the screen.
Width, height and position of frame can be in proportion with main screen WIDTH and HEIGHT and it can be precise value in pixels.
If it is proportions SSC("screen" class member) will automatically detect changes in WIDTH and HEIGHT and correct self width, height and position.

Main features explanation:

  1. Pre-event and pos-event user-defined function calls:
    all "screen" class members now have two function type values: self.CallFirst and self.CallLast. self.CallFirst will be called every time before drawing all objects in frame, also it calls every
    time in touch event before objects get struct_touch from frame, it have self(screen) as first
    parameter and original touch as second parameter at call, if this function returns false statment
    then render(or touch event) skips, and self.CallLast starts working.
    self.CallLast will be called every time after drawing all objects in frame, also it calls every
    time in touch event after objects get struct_touch from frame, it have same parameters as self.CallFirst at calls.
  2. Global variables overload:
    all "screen" class members now have table type value: self.UserValues, that stores user-defined values that if it will have same name(or kye) will be changed with global values in draw- and touch-events(before self.CallFirst calls) and will be restored after self.CallLast calls ended. Globals also will be restored.
  3. Simple Codea-like I/O interface:
    i trying to follow Codea-style interface everywhere where i can.
  4. Pastebin access:
    now all library are accessible by this link: SSC.lib V1: http://pastebin.com/KTZg4zqS
  5. Shorter code:
    as it is
  6. All code are comented now:
    i am trying to substantively coment my code everywhere where i can.

Future features and objectives:

  1. Meshing and schrader support
  2. Minimal and Maximal versions for big and small projects
  3. Performance upgrade
  4. Reducing code size

App example

--=====================TOUCHFINDER===================
touchfinder = class()

function touchfinder:init()
    self.pos = nil
    self.state = nil
    self.color = color(128)
end

function touchfinder:draw()
    if self.pos == nil or self.state == nil then
        return
    end
    if self.state == BEGAN then
        fill(255)
    elseif self.state == ENDED then
        fill(0)
    else
        fill(self.color)
    end
    ellipse(self.pos.x, self.pos.y, 100)
end

function touchfinder:touched(touch)
    self.pos = vec2(touch.x, touch.y)
    self.state = touch.state
end
--=====================MAINFUNC===================
function setup()
    spriteMode(CORNER)
    --global value that can be overloaded
    lol = 1
    scr1 = screen(0.5, nil, nil, {lol = 2})
    scr2 = screen(0.5, nil, vec2(0.5, 0), {lol=3})
    scr1.background = color(255,0,0,10)
    scr2.background = color(0,255,0,10)
    tf1 = touchfinder()
    tf2 = touchfinder()
    tf1.color = color(255,255,0)
    tf2.color = color(0,0,255)
    scr1:push(tf1)
    scr2:push(tf2)
    --[[
    --print is very slow function
    --uncomment this section to see globals swaping
    scr1.CallFirst = function() print("First: ", lol) return true end
    scr2.CallFirst = function() print("Second: ", lol) return true end
      ]]
end

function draw()
    --[[
    --uncomment this section to see globals swaping
    print("Global: ", lol)
      ]]
    scr1:draw()
    scr2:draw()
end

function touched(touch)
    scr1:touched(touch)
    scr2:touched(touch)
end

Previous version

Simple Screen Carrier

Curent version

By Pastebin: SSC.lib V1
or by code: in first comment
Thanks for reading your comments and suggestions are welcome

Comments

  • edited September 2015 Posts: 11
    --=====================STRUCT_TOUCH===================
    struct_touch = class()
    --this is primitive struct_ class with some service functions for screen class
    --it is represents standart Codea touch class as variable not a constant(as touch class is)
    function struct_touch:init(touch)
        self.id = touch.id
        self.x = touch.x
        self.y = touch.y
        self.prevX = touch.prevX
        self.prevY = touch.prevY
        self.deltaX = touch.deltaX
        self.deltaY = touch.deltaY
        self.state = touch.state
        self.tapCount = touch.tapCount
    end
    --defines new zero of cordinate axis
    function struct_touch:newzero(position)
        self.x = self.x - position.x
        self.y = self.y - position.y 
    end
    --check inbound conditions for almost every spriteMode
    function struct_touch:inbounds(width, height)
        if spriteMode() == CENTER or spriteMode() == RADIUS then
            return self.x < width/2 and self.y < height/2
        else
            return math.abs(self.x-width/2)<width/2 and math.abs(self.y-height/2)<height/2
        end
    end
    --updating without constructing new object
    function struct_touch:update(touch)
        self.id = touch.id
        self.x = touch.x
        self.y = touch.y
        self.prevX = touch.prevX
        self.prevY = touch.prevY
        self.deltaX = touch.deltaX
        self.deltaY = touch.deltaY
        self.state = touch.state
        self.tapCount = touch.tapCount
    end
    --=====================SCREEN===================
    screen = class()
    --[[
    main class of the screen lib
    represents screen(or its fixed parts) as a frame and auto-detects WIDTH and HEIGHT constants
    changing and saves self width, height and position
    if position or width/height values equals 1 or less then it will be used in proportion
    with main screen values of WIDTH and HEIGHT else it will be used as precise value in pixels
    ]]
    function screen:init(Width, Height, Position, UserValues)
        --default size is float fullscreen
        self.floatsize = vec2(1,1)
        self.size = vec2(WIDTH, HEIGHT)
        self.globalWH = vec2(WIDTH, HEIGHT)
        --value that allows to not check status of all self correcting variables at every draw-event
        self.updater = false
        if Width or Height then
            if Width then
                if Width <= 1 then
                    self.floatsize.x = Width
                    self.size.x = WIDTH * Width
                    self.updater = true
                else
                    self.floatsize.x = nil
                    self.size.x = Width
                end
            end
            if Height then
                if Height <= 1 then
                    self.floatsize.y = Height
                    self.size.y = HEIGHT * Height
                    self.updater = true
                else
                    self.floatsize.y = nil
                    self.size.y = Height
                end
            end
        end
        self.i = image(self.size.x, self.size.y)
        --default position is fixed in (0,0) screen pixel
        self.floatposition = vec2(nil,nil)
        self.pos = vec2(0,0)
        if Position then
            if Position.x <= 1 then
                self.floatposition.x = Position.x
                self.pos.x = self.floatposition.x*WIDTH
                self.updater = true
            else
                self.pos.x = Position.x
            end
            if Position.y <= 1 then
                self.floatposition.y = Position.y
                self.pos.y = self.floatposition.y*HEIGHT
                self.updater = true
            else
                self.pos.y = Position.y
            end
        end
    --array of objects that are visible and toucheble in this frame
        self.objects = {} 
        self.visible = true 
        self.enable = true
    --force to copy last frame every draw call if true
        self.copylastframe = false
        self.background = color(0,255)
    --reserved memory for struct_touch
        self.CurentTouch = struct_touch(CurrentTouch)
    --[[
    this functions calls every time before drawing all objects in frame, also it calls every 
    time in touch event before objects get struct_touch from frame, it have self(screen) as first 
    parameter and original touch as second parameter at call, if this function returns false statment 
    then render(or touch event) skips, and CallLast starts working
    ]]
        self.CallFirst = function() return true end 
    --[[
    this functions calls every time after drawing all objects in frame, also it calls every 
    time in touch event after objects get struct_touch from frame, it have self(screen) as first
     parameter and original touch as second parameter at call
    ]]
        self.CallLast = function() return true end
    --[[
    UserValues is a table of local(for this screen) values defined by user, it MUST be table,
    keys are the same as in user-defined table, global values that have the same key automatically
    swaps in touch and draw events before CallFirst calls and after CallLast calls
    ]]
        self.UserValues = {}
        local varCount = 0
        if type(UserValues) == "table" then
            for k,v in pairs(UserValues) do
                self.UserValues[k] = v
                varCount = varCount + 1
            end
        else
            --for not tables
            self.UserValues = nil
        end
        if varCount == 0 then
            --for zero value tables (aka {})
            self.UserValues = nil
        end
    --buffer for global swaping
        self.buff = nil
    end
    --draw-event handler
    function screen:draw()
        if not self.enable or not self.visible then
            return
        end
        if ((self.globalWH.x ~= WIDTH) or (self.globalWH.y ~= HEIGHT)) and self.updater then
            self:update()
        end
        pushStyle()
        setContext(self.i)
        if not self.copylastframe then
            fill(self.background)
            rect(0,0,self.size.x,self.size.y)
        end
        if self.UserValues then
            for k,v in pairs(self.UserValues) do
                if _G[k] then
                    self.buff = _G[k]
                    _G[k] = v
                    self.UserValues[k] = self.buff
                end
            end
        end
        if self.CallFirst(self) then
            for _,v in pairs(self.objects) do
                v:draw()
            end
        end
        self.CallLast(self)
        if self.UserValues then
            for k,v in pairs(self.UserValues) do
                if _G[k] then
                    self.buff = _G[k]
                    _G[k] = v
                    self.UserValues[k] = self.buff
                end
            end
        end 
        setContext()
        popStyle()
        sprite(self.i, self.pos.x, self.pos.y)
    end
    --touch-event handler
    function screen:touched(touch)
        if not self.enable then
            return
        end
        self.CurentTouch:update(touch)
        self.CurentTouch:newzero(self.pos)
        if not self.CurentTouch:inbounds(self.size.x, self.size.y) then
            return false
        end
        if self.UserValues then
            for k,v in pairs(self.UserValues) do
                if _G[k] then
                    self.buff = _G[k]
                    _G[k] = v
                    self.UserValues[k] = self.buff
                end
            end
        end
        if self.CallFirst(self, touch) then
            for _,v in pairs(self.objects) do
                v:touched(self.CurentTouch)
            end
        end
        self.CallLast(self, touch)
        if self.UserValues then
            for k,v in pairs(self.UserValues) do
                if _G[k] then
                    self.buff = _G[k]
                    _G[k] = v
                    self.UserValues[k] = self.buff
                end
            end
        end 
        return true
    end
    --function that updates width, height and position
    function screen:update()
        self.globalWH.x = WIDTH
        self.globalWH.y = HEIGHT
        if self.floatsize.x then
            self.size.x = WIDTH*self.floatsize.x
        end
        if self.floatsize.y then
            self.size.y = HEIGHT*self.floatsize.y
        end
        self.i = image(self.size.x, self.size.y)
        if self.floatposition.x then
            self.pos.x = self.floatposition.x*WIDTH
        end
        if self.floatposition.y then
            self.pos.y = self.floatposition.y*HEIGHT
        end
    end
    --clears screen settings to default
    function screen:clear()
        self.i = image(self.size.x, self.size.y)
        self.objects = {}
        self.visible = true
        self.enable = true
        self.background = color(0,255)
        self.copylastframe = false
        self.CallFirst = function() return true end
        self.CallLast = function() return true end
    end
    --adds new object to object list
    function screen:push(obj)
        table.insert(self.objects, obj)
    end
    --delete last object (or object on position i) from object list, returns it
    function screen:pop(i)
        return table.remove(self.objects, i)
    end
    
  • IgnatzIgnatz Mod
    Posts: 5,396

    Can you maybe show a little video so we can see what it does?

  • edited September 2015 Posts: 11

    @Ignatz
    Sorry, but i can't, and i have couple of reasons why:
    1. Codea not supported orientation changing while video capturing, every time when i try to capture video and changes orientation of my device video capture stops without saving.
    2. This library is system-style. It helps you to do your projects quickly without meeting troubles with container-class creation while your project in coding phase and orientation changing while your project is running.

    I can provide simple example of usage(as i did), but i better explain here main idea of this lib:
    Usage must be simple:
    1. Create your container("screen" class element)
    2. Push your objects in it
    3. Don't worry, be happy:)

  • IgnatzIgnatz Mod
    Posts: 5,396

    I'm still not sure what it does!

  • @Ignatz
    I want to share this lib with other developers because i use something like container-class, and screen divider(class that captures touch-events in some part of the screen) class for all my big projects. But this lib includes all of it in one class with minimum amount of code and some cool build-in features(as local globals overload and pre-post-event user-defined function calls).
    I am sure that i will use this lib in my future projects.

Sign In or Register to comment.