Commit 35162722 authored by Yori Fournier's avatar Yori Fournier
Browse files

Merge branch 'updateSyncFig' into 'dev'

updating a synced figure now works

See merge request !47
parents 1255d850 160d326e
Pipeline #434 failed with stage
in 3 minutes and 11 seconds
......@@ -108,7 +108,7 @@ class MplClient2():
"""
pass
def newSyncFigure(self, figname, dataname,*args,**kwargs) :
def newSyncFigure(self, figname, dataname, *args, **kwargs) :
'''
Send a query NEWSYNCFIGURE to the server
wait for the status.
......@@ -120,41 +120,40 @@ class MplClient2():
if not status :
print('something went wrong with the sending of newSincFigure request...')
statusSig = self.waitForSignal()
answer = self.waitForSignal()
# try to create a figure of the same class on the client side
if self.testStatusSig(query,statusSig) :
if isinstance(answer,Answer) :
print('trying to create a figure of the same class on the client side')
fig = figname((MyData(),),*args,**kwargs)
fig = figname( MyData(), *args, **kwargs)
# Link the temporary Sync Figure
fig.syncID = '26042017'
fig.syncID = answer.content
fig.client = self
return fig
return fig
elif isinstance(answer,Status) :
self.testStatusSig(query,answer)
return None
else :
print('an unknown error occured')
return None
def updateSyncFigure(self,syncID,kwargs) :
''' Send a UPDATE_SYNC_FIGURE query to the server.
wait for the status
if status ok then sync.
'''
# create a signal with args
query = Query(Query.UPDATESYNCFIGURE,(syncID,kwargs))
self.send(query)
statusSig = self.waitForSignal()
#~ def updateSyncFigure()
#~ '''
#~ Send a UPDATE_SYNC_FIGURE query to the server.
#~ wait for the status
#~ if status ok then sync.
#~ '''
#~ # create a signal with args
#~ query = Query(Query.UPDATE_SYNC_FIGURE)
#~ sendSignal(query)
#~ statusSig = waitForSignal()
#~
#~ if statusSig.value :
#~ # update Figure with args
#~ if updated
#~ # create a signal of type status (True)
#~ status = Status(True)
#~ else:
#~ # create a signal of type status (False)
#~ status = Status(False)
#~ sendSignal(status)
#~ else:
#~ # do not update the figure.
#~ print statusSig.error
#~
if statusSig.value :
return True
else:
return False
def deleteSyncFigure(self,syncID):
'''
Send a DELETESYNCFIGURE query to the server.
......
import SocketServer
import pickle
import threading
from . import Signal,Status,Query,Answer
......@@ -68,11 +69,9 @@ class MplHandler(SocketServer.StreamRequestHandler):
datas = [G_RAWDATA[name] for name in datanames]
# Generate an FigID
FigID = '26042017'
try:
G_FIGURES[FigID] = FigClass(datas, **kwargs)
# create the figure:
fig = FigClass(datas, **kwargs)
if (DEBUG):
print(INFO+"SERVER: I created the requested Figure")
except Exception as e:
......@@ -82,13 +81,14 @@ class MplHandler(SocketServer.StreamRequestHandler):
print(SPCE+"SERVER: Exception details where:",e.message, e.args )
return Status(False, "I could not create the requested Figure. I tried: "+str(FigClass.__name__)+'('+str(datas)+', '+str(kwargs)+')'+" Exception details where:"+str(e.message)+str(e.args))
if FigID in G_FIGURES :
return Status(True,"SERVER: I created the requested Figure with following instructions"+str(FigClass.__name__)+str(datas)+'('+str(args)+', '+str(kwargs)+')')
def treatUpdateSyncFigure(self,content) :
pass
# add the figure to the global index
G_FIGURES[fig.getFigID()] = fig
if fig.getFigID() in G_FIGURES :
return Answer(fig.getFigID())
def treatSyncFigFormatRawData(self,figID):
def getFigByID(self,figID) :
""" Identify the figure by ID and return it. On error it will return a Status Signal"""
# Identify the figure
fig = G_FIGURES.get(figID,None)
......@@ -99,6 +99,33 @@ class MplHandler(SocketServer.StreamRequestHandler):
elif isinstance(fig,MyFig) :
if DEBUG :
print('Figure ',figID,' found in database')
return fig
def treatUpdateSyncFigure(self,content) :
""" If client request an update of the keywords of a figure. This function forwards the request to the corresponding figure"""
figID,kwargs = content
fig = self.getFigByID(figID)
# if an error occured forward the signal
if isinstance(fig,Signal) :
return fig
status = fig.update(**kwargs)
if status :
return Status(True,'Kewords of figure ID: '+figID+' successfully updated')
else :
return Status(False,'Kewords of figure ID: '+figID+' could not be updated')
def treatSyncFigFormatRawData(self,figID):
# Identify the figure
fig = self.getFigByID(figID)
# if an error occured forward the signal
if isinstance(fig,Signal) :
return fig
# Format the rawdata
try:
......@@ -238,8 +265,18 @@ class MplServer2(SocketServer.TCPServer):
self.defineKnownFunctions(knownFunctions)
self.defineKnownFigures(knownFigures)
SocketServer.TCPServer.__init__(self, (ip, port), handler)
self.running = False
self.initialized = True
def run(self, as_daemon=True):
self.server_thread = threading.Thread(target=self.serve_forever)
self.server_thread.daemon = as_daemon
self.server_thread.start()
self.running = True
def stop(self): # not yet working
print('STOPING...')
# self.server_thread.stop()
self.running = False
......@@ -83,6 +83,7 @@ class MyFig_client(Figure):
# (private variable can not be updated)
FIGSIZE = D_FIGSIZE
# CONSTRUCTOR --------------------------------------------------------
# CONSTRUCTOR --------------------------------------------------------
def __init__(self, rawdata, *args, **kwargs):
......@@ -109,7 +110,7 @@ class MyFig_client(Figure):
# initialise
self._initialize(*args, **kwargs)
def deSyncFig(self):
if self.client is not None :
if self.client.deleteSyncFigure(self.syncID) :
......@@ -130,49 +131,66 @@ class MyFig_client(Figure):
self.declareAliases()
# update the attributes and keywords
self.update(**kwargs)
# UPDATE ----------------------------------------------------------
def update(self, **kwargs):
self._update(**kwargs)
def _update(self, **kwargs):
# check attributes in keywords
for keyword in kwargs.keys():
# if it is an attribute
if keyword in self._attributesToUpdateKeys:
# update value
setattr(self, keyword, kwargs[keyword])
# For each axes update the keywords
for ax in self.get_axes():
forax = {}
for keyword in kwargs.keys():
# ignore figure attributes
if keyword in self._attributesToUpdateKeys :
pass
# Check if a key of kwargs has an alias for this axes
elif keyword in self.aliases.keys():
alax, alkey = self.aliases[keyword]
# If an alias is found then update axkwargs
if ax == alax:
forax.update(**{alkey: kwargs[keyword]})
# use keyword as it is for the axes
else :
forax.update(**{keyword : kwargs[keyword]})
# Then eventually all collected Keywords are updated in one go
if (forax) :
if self.debug:
print (DBUG+' fig.update ', ax, 'keywords: ', forax)
ax.update(**forax)
return(True)
return(True)
# UPDATE ----------------------------------------------------------
def update(self, **kwargs):
# send the keywords to the server
if self.client is not None :
status = self.client.updateSyncFigure(self.syncID,kwargs)
# if the server reported no errors apply the keywords on client side also:
if status :
self._update(**kwargs)
else :
print('The server reported of an error in setting the keywords')
return(False)
else :
print(WARN+'The figure is not yet connected to a client')
self._update(**kwargs)
return(False)
# DECLARE ALIASES -------------------------------------------------
def declareAliases(self):
......
......@@ -81,6 +81,8 @@ class MyFig_server(object):
# Set the size of the Figure in inch
# (private variable can not be updated)
FIGSIZE = D_FIGSIZE
G_FIGNUM = 0 # This is to become global counter for myFig Instances to prevent ID collision
# CONSTRUCTOR --------------------------------------------------------
def __init__(self, rawdata, *args, **kwargs):
......@@ -89,7 +91,7 @@ class MyFig_server(object):
self._attributesToUpdateKeys = ['fignum', 'reformat', 'debug', 'formatted', 'aliases']
# initialise the attribute default values and remove them from kwargs
self.fignum = kwargs.pop('fignum', -1) # need to be hard coded for interactive mode
self.fignum = kwargs.pop('fignum', MyFig_server.G_FIGNUM) # need to be hard coded for interactive mode
self.reformat = kwargs.pop('reformat', D_REFORMAT)
self.debug = kwargs.pop('debug', D_DEBUG)
self.formatted = kwargs.pop('formatted', D_FORMATTED)
......@@ -102,6 +104,9 @@ class MyFig_server(object):
self._initialize(*args, **kwargs)
self.set_rawdata(rawdata)
# count the global counter up by one
MyFig_server.G_FIGNUM += 1
# INITIALIZE -------------------------------------------------------
def _initialize(self, *args, **kwargs):
......@@ -160,6 +165,10 @@ class MyFig_server(object):
return(True)
# GET FIG ID AS STRING --------------------------------------------
def getFigID(self) :
return str(self.fignum)
# DECLARE ALIASES -------------------------------------------------
def declareAliases(self):
pass
......
......@@ -11,22 +11,35 @@ SERVER_FIGURES = {'FigTest': FigTests}
import serverside.myplotlib as mpl_server
import clientside.myplotlib as mpl_client
server = mpl_server.MplServer2(port=50803, knownFunctions=SERVER_IOFUNCTIONS, knownFigures=SERVER_FIGURES)
server = mpl_server.MplServer2(port=12345, knownFunctions=SERVER_IOFUNCTIONS, knownFigures=SERVER_FIGURES)
client = mpl_client.MplClient2()
# Start a thread with the server -- that thread will then start one
# more thread for each request
server_thread = threading.Thread(target=server.serve_forever)
# server_thread = threading.Thread(target=server.serve_forever)
# Exit the server thread when the main thread terminates
server_thread.daemon = True
server_thread.start()
print "Server loop running in thread:", server_thread.name
# server_thread.daemon = True
# server_thread.start()
server.run()
print "Server loop running in thread:", server.server_thread.name
client.connect(('', 50803))
client.connect(('localhost', 12345))
client.readData('readStupidData', 'data1')
fig = client.newSyncFigure(FigTestc, ('data1',))
win=mpl_client.MyWin(fig)
fig1 = client.newSyncFigure(FigTestc, ('data1',))
win=mpl_client.MyWin(fig1)
sleep(2)
fig.deSyncFig()
# update test
fig1.update(xRange=[-2, 2],yRange=[-2, 2])
win.refresh()
sleep(2)
# multiple figures
fig2 = client.newSyncFigure(FigTestc, ('data1',), xRange=[-1.5, 1.5], yRange=[-1.5, 1.5])
win=mpl_client.MyWin(fig2)
fig1.deSyncFig()
fig2.deSyncFig()
sleep(2)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment