local component=require("component") local unicode=require("unicode") local colorutils=require("colorutils") local buffer={VERSION="1.0"} local bufferMeta={} local debugPrint=function() end --copy these to file local, they're called a lot in performance-intensive loops local convColor_hto8=colorutils.convColor_hto8 local convColor_8toh=colorutils.convColor_8toh local function encodeColor(fg,bg) return convColor_hto8(bg)*256+convColor_hto8(fg) end local function decodeColor(c) return convColor_8toh(math.floor(c/256)),convColor_8toh(c%256) end function bufferMeta.getBackground(buffer) return convColor_8toh(buffer.colorBackground) end function bufferMeta.setBackground(buffer,color) local p=buffer.colorBackground buffer.colorBackground=color buffer.color=encodeColor(buffer.colorForeground,color) return p end function bufferMeta.getForeground(buffer) return buffer.colorForeground end function bufferMeta.setForeground(buffer,color) local p=buffer.colorForeground buffer.colorForeground=color buffer.color=encodeColor(color,buffer.colorBackground) return p end function bufferMeta.copy(buffer,x,y,w,h,dx,dy) buffer.flush() return buffer.parent.copy(x,y,w,h,dx,dy) end function bufferMeta.fill(buffer,x,y,w,h,char) buffer.flush() buffer.parent.setForeground(buffer.colorForeground) buffer.parent.setBackground(buffer.colorBackground) return buffer.parent.fill(x,y,w,h,char) end function bufferMeta.get(buffer,x,y) buffer.flush() return buffer.parent.get(x,y) end function bufferMeta.set(buffer,x,y,str) local spans=buffer.spans local spanI=1 local color=buffer.color local e=x+unicode.len(str)-1 while spans[spanI] and (spans[spanI].y span.e then span.e=e end else --can't, gonna have to make a new span --but first, split this guy as needed debugPrint("can't merge. Splitting") local a,b=unicode.sub(span.str,1,math.max(0,x-span.x)),unicode.sub(span.str,e-span.x+2) if unicode.len(a)>0 then span.str=a span.e=span.x+unicode.len(a) --span is a new span span={str=true,e=true,x=true,y=y,color=span.color} --insert after this span spanI=spanI+1 table.insert(spans,spanI,span) end if unicode.len(b)>0 then span.str=b span.x=e+1 span.e=span.x+unicode.len(b) --and another new span span={str=true,e=true,x=true,y=y,color=color} --insert /before/ this one table.insert(spans,spanI,span) end --now make whatever span we're left with me. span.color=color span.x, span.e = x, e span.str=str span.y=y end else --starts after me. just insert. local span={x=x,e=e,y=y,color=color,str=str} table.insert(spans,spanI,span) end --ok. We are span. We are at spanI. We've inserted ourselves. Now just check if we've obliterated anyone. --while the next span starts before I end... spanI=spanI+1 while spans[spanI] and spans[spanI].y==y and spans[spanI].x<=e do local span=spans[spanI] if span.e>e then --it goes past me, we just circumcise it span.str=unicode.sub(span.str,e-span.x+2) span.x=e+1 break--and there can't be more end --doesn't end after us, means we obliterated it table.remove(spans,spanI) --spanI will now point to the next, if any end end --[[this..won't work. Was forgetting I have a table per row, this would count rows. if #spans>=buffer.autoFlushCount then buffer.flush() end --]] end function bufferMeta.flush(buffer) debugPrint("flush?") if #buffer.spans==0 then return end --sort by colors. bg is added as high value, so this will group all with common bg together, --and all with common fg together within same bg. table.sort(buffer.spans, function(spanA,spanB) if spanA.color==spanB.color then if spanA.y==spanB.y then return spanA.x